gpt4 book ai didi

c++ - 对象管理器的最佳实践

转载 作者:行者123 更新时间:2023-11-30 02:12:11 24 4
gpt4 key购买 nike

我对 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)抱歉我的英语不好:)

最佳答案

一些评论:

  • 使用 std::vector 来保存您的客户端对象,而不是某种自行开发的结构。它会让你的生活更轻松
  • 我认为如果 get() 返回一个引用很好,前提是用户确实知道如果他们坚持太久该引用可能会失效
  • 如果该元素不存在,我会在 get() 中抛出异常;这就是异常的用途,它将允许您在适当的级别处理缺失的元素

至于 (2),您可以处理适当的信号并调用 dispose()。我认为您可能确实想在退出之前关闭套接字。

关于c++ - 对象管理器的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2337650/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com