std :: map和id' s继续递增

时间:2018-04-22 03:23:48

标签: c++

我正在处理客户端和服务器项目。

所有会话的std :: map看起来有点像这样:

std::map<int, SOCKET> Sessions;
int g_TotalClientCount;
void Server::HandleNewClientConnection(SOCKET clientSocket){
    Sessions.insert(pair<int, SOCKET>(g_TotalClientCount, clientSocket));
    g_TotalClientCount++;
}
/*Something similar on disconnect*/
void Server::KickClient(int clientId){
    SendPacket(...)
    Sessions.erase(clientId);
}

让我们说随着时间的推移,g_TotalClientCount变得非常高并最终超过MAX_INT(最终导致错误/崩溃)。

是否有正确的方法可以在地图中删除和插入项目,还可以将g_TotalClientCount保持为实际连接的用户数而不是连接的用户数? 使用

g_TotalClientCount--;

最终会造成重复。

g_TotalClientCount仅用于HandleNewClientConnection部分。

我知道我可能永远不会有这个问题,但我想知道这样做的正确方法。

1 个答案:

答案 0 :(得分:0)

更适合您的问题的是std::set(对数复杂度)或更好,std::unordered_set(恒定时间复杂度)。您可以使用iterator方法返回的insert作为clientId

C ++ 98:

#include <set>

std::set<SOCKET> Sessions;

std::set<SOCKET>::iterator Server::HandleNewClientConnection(SOCKET clientSocket) {
    std::pair<std::unordered_set<SOCKET>::iterator, bool> inserted =
        Sessions.insert(clientSocket);
    if (!inserted.second) {
        // handle the insertion error
    }
    return inserted.first;
}

void Server::KickClient(std::set<SOCKET>::iterator clientId){
    SendPacket(...)
    Sessions.erase(clientId);
}

C ++ 11 +:

#include <unordered_set>

std::unordered_set<SOCKET> Sessions;

auto Server::HandleNewClientConnection(SOCKET clientSocket) {
    auto inserted = Sessions.insert(clientSocket);
    if (!inserted.second) {
        // handle the insertion error
    }
    return inserted.first;
}

void Server::KickClient(std::unordered_set<SOCKET>::iterator clientId){
    SendPacket(...)
    Sessions.erase(clientId);
}

C ++ 17:

#include <unordered_set>

std::unordered_set<SOCKET> Sessions;

auto Server::HandleNewClientConnection(SOCKET clientSocket) {
    auto [iterator, success] = Sessions.insert(clientSocket);
    if (!success) {
        // handle the insertion error
    }
    return iterator;
}

void Server::KickClient(std::unordered_set<SOCKET>::iterator clientId){
    SendPacket(...)
    Sessions.erase(clientId);
}