作为我的一个较老问题的后续,我希望实现一个客户端-服务器模型模拟,其中客户端启动一系列操作,这些操作涉及调用服务器上的方法,而服务器又可以调用客户端上的方法(让我们忽略堆栈可能会爆炸的问题)。
更具体地说,由于我想将实现从定义中分离出来,我将为 Server 类提供 server.h 和 server.cpp,为 Client 类提供 client.h 和 client.cpp。由于 Server 持有对 Client 的引用并从中调用方法,因此它需要#include "client.h"
. 此外,Client 持有对 Server 的引用并从中调用方法,它需要#include "server.h"
. 此时,即使我在 server.h 和 client.h 中都使用了标头保护,它仍然会搞砸(是的,这是意料之中的)所以我决定在 client.h 中转发声明 Server 类,在 server 中声明 Client 类。H。不幸的是,这还不足以解决问题,因为我也在调用这两个类的方法,所以我设法通过在客户端中包含 server.h 来使其编译和运行(据我所知是正确的) server.cpp 中的 .cpp 和 client.h。
上面的“hack”听起来合理吗?我应该期待一些无法预料的后果吗?是否有任何“更智能”的方法可以做到这一点而无需实现代理类?
这是实现的基本示例:
文件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
文件 server.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;
}