我一直在研究用 C++ 编写的服务器,并使用 SFML 网络连接套接字和所有内容。但是,我遇到了一些死胡同。SFML 套接字是不可复制的,因此不能存储到大多数(我所知道的所有)stl 容器中。
所以,我很快就想到了使用指针,然后突然想到我应该使用 RAII,但我讨厌智能指针,需要存储更多信息,而不仅仅是指向 Socket 类的指针。
我写了一个客户端类,它包装了套接字并在调用客户端类的析构函数时将其删除,这很好而且花花公子..直到我记得 stl 容器将复制我的类,删除指针然后我会留下一个悬空的指针。
那么,无论如何我可以绕过不可复制的东西吗?我需要将指针存储在类中,并且我需要类来销毁分配的内存。
我想我可以使用复制构造函数将复制的类的指针设置为空,但我找不到这样做的方法。
以供参考:
Client.cpp
Client::Client()
{
};
Client::Client(sf::TcpSocket* in_Connection)
{
m_Connection = in_Connection;
m_IPAddress = m_Connection->getRemoteAddress().toString();
m_AccountName = "NOACCOUNT";
m_CharacterName = "NOCHARACTER";
};
Client::~Client()
{
m_Connection->disconnect();
delete m_Connection;
};
//getters
sf::TcpSocket* Client::getConnection()
{
return m_Connection;
};
std::string Client::getIPAddress()
{
return m_IPAddress;
};
std::string Client::getAccountName()
{
return m_AccountName;
};
std::string Client::getCharacterName()
{
return m_CharacterName;
};
//setters -- Account Name and Character Name are the only two that can be changed during a connection.
void Client::setAccountName(std::string in_AccountName)
{
m_AccountName = in_AccountName;
};
void Client::setCharacterName(std::string in_CharacterName)
{
m_CharacterName = in_CharacterName;
};
//Copy Constructor <--This defintely won't work and I know that, haha.
Client::Client(const Client& that)
{
m_Connection = new sf::TcpSocket();
*m_Connection = *that.m_Connection; // Cannot copy non-copyable
m_IPAddress = that.m_IPAddress;
m_CharacterName = that.m_CharacterName;
m_AccountName = that.m_AccountName;
};
Server Accept Function
void Server::AcceptConnections()
{
sf::TcpSocket* Socket = new sf::TcpSocket();
if( m_Listener.accept(*Socket) == sf::Socket::Done)
{
if(Socket != NULL )
{
std::string IPAddress = Socket->getRemoteAddress().toString();
if( m_Connections.find( IPAddress ) == m_Connections.end() )
{
std::cout << IPAddress;
std::cout << " Has Connected.";
std::endl( std::cout );
m_Connections.insert( std::make_pair(IPAddress, Client(Socket) ) );
}
}
}
};