私は 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) 私の悪い英語について申し訳ありません:)