私の以前の質問のフォローアップとして、クライアントサーバーモックアップシミュレーションを実装したいと思います。このシミュレーションでは、クライアントがサーバー上のメソッドの呼び出しを含む一連のアクションを開始し、サーバー上のメソッドを呼び出すことができます(スタックが爆発する可能性があるという問題は無視しましょう)。
具体的には、実装を定義から分割したいので、Serverクラスにはserver.hとserver.cppを、Clientクラスにはclient.hとclient.cppを用意します。サーバーはクライアントへの参照を保持し、そこからメソッドを呼び出すため、を行う必要があり#include "client.h"
ます。また、クライアントはサーバーへの参照を保持し、そこからメソッドを呼び出す必要があります#include "server.h"
。この時点で、server.hとclient.hの両方でヘッダーガードを使用しても、それはまだ混乱しているので(ええ、それは予想されます)、client.hのServerクラスとserverのClientクラスを前方宣言することにしました。 .h。残念ながら、これでは問題を解決するのに十分ではありません。2つのクラスからメソッドも呼び出しているため、クライアントにserver.hを含めることで、コンパイルして実行することができました(私が知る限り)。 server.cppの.cppとclient.h。
上記の「ハック」は合理的に聞こえますか?予期しない結果を予期する必要がありますか?プロキシクラスを実装せずにこれを行う「よりスマートな」方法はありますか?
実装がどのように見えるかの基本的なサンプルを次に示します。
ファイルclient.h:
#ifndef CLIENT_H
#define CLIENT_H
#include <iostream>
#include <memory>
class Server;
class Client
{
private:
std::shared_ptr<const Server> server;
public:
Client () {}
void setServer (const std::shared_ptr<const Server> &server);
void doStuff () const;
void doOtherStuff () const;
};
#endif
ファイルclient.cpp:
#include "client.h"
#include "server.h"
void Client::setServer (const std::shared_ptr<const Server> &server)
{
this->server = server;
}
void Client::doStuff () const
{
this->server->doStuff();
}
void Client::doOtherStuff () const
{
std::cout << "All done!" << std::endl;
}
ファイルserver.h:
#ifndef SERVER_H
#define SERVER_H
#include <iostream>
#include <memory>
class Client;
class Server
{
private:
std::weak_ptr<const Client> client;
public:
Server () {}
void setClient (const std::weak_ptr<const Client> &client);
void doStuff () const;
};
#endif
ファイルsever.cpp:
#include "server.h"
#include "client.h"
void Server::setClient (const std::weak_ptr<const Client> &client)
{
this->client = client;
}
void Server::doStuff () const
{
this->client.lock()->doOtherStuff();
}
ファイルmain.cpp:
#include <iostream>
#include <memory>
#include "client.h"
#include "server.h"
int main ()
{
std::shared_ptr<Client> client(new Client);
std::shared_ptr<Server> server(new Server);
client->setServer(server);
server->setClient(client);
client->doStuff();
return 0;
}