我对 c++ 编程有点陌生,我正在为多人游戏编写对象管理器,但我对如何管理客户端对象有些疑问。客户端对象由连接的客户端参数(如 IP、连接时间、接收数据等)组成。
为了避免内存碎片,我打算分配一个允许最大客户端数量的对象池。为此,我正在编写这样的客户端对象管理器:
ClientManager.h
#include "Client.h"
class ClientManager {
public:
static void init(int max); //initialize pool (allocate memory)
static void dispose(); //dispose pool (deallocate memory)
static bool add(int socketFd); //add connected client by its socket file descriptor
static bool remove(int socketFd); //remove connected client by its socket fd
static Client& get(int socketFd); //get the client object by its socket fd
private:
Client* clientList; //array of allocated clients objects
int maxClient; //max number of connected clients allowed
请注意,此类将仅以静态方式调用,因此没有构造函数/析构函数。此类必须是静态的,因为必须可以在不同类型的对象之间读取/修改客户端数据。
实现将类似于:
ClientManager.cpp
void ClientManager::init(int max) {
maxClient = max;
clientList = new Client[maxClient];
}
void ClientManager::dispose() {
maxClient = 0;
delete [] clientList;
clientList = NULL;
}
bool ClientManager::add(int socketFd) {
//search pool for non-initialized object
//if(there is a non-initializes object) { initialize it with socketFd and return true}
//else return false;
}
bool ClientManager::remove(int socketFd) {
//search pool for socketFd
//if(socketFd found) { clear object (make it non-initialized) and return true}
//else return false
}
Client& ClientManager::get(int socketFd) {
//search for object position
if(pos) return clientList[pos];
else ???????
}
现在,如何管理 get 函数中的对象返回?参考是最好的选择吗?我不想返回一个指针,但如果这是我最后的选择,我可以接受它。我想我可以确保我只在池中获得注册(初始化)对象,如果是这样,是否需要在 get 函数中进行检查?我不想要断言,因为我希望代码健壮并且在运行时不会停止(我是 C++ 新手,所以如果我说错了,请纠正我)。
在主程序中,我在想这样的事情:
Daemon.cpp
#include "ClientManager.h"
int main(...) {
ClientManager::init(100);
while(1) {
//do server stuff
//get onConnect event (new client is connecting)
//get onDisconnect event (connected client has gone offline)
//get onDataReceived event (connected client has sent data)
}
}
void onConnect(int socketFd) {
ClientManager::add(socketFd);
}
void onDisconnect(int socketFd) {
ClientManager::remove(socketFd);
}
void onDataReceived(int socketFd) {
do_something(ClientManager::get(socketFd).data);
}
我做对了吗?谢谢
注意:
1)这段代码是我的想法,我在这里输入了它,所以我可能忘记了一些东西。
2)程序只有被杀死才会终止(我使用的是linux),因此在主程序中不会显式调用ClientManager的dispose方法(因为它是一个静态类)。再次,如果我说错了,请告诉我!
3) 对不起我的英语不好:)