作爲an older question of mine的後續,我希望實現客戶端 - 服務器模型仿真,其中客戶端啓動一系列涉及調用服務器上方法的操作,其中轉,可以調用客戶端上的方法(讓我們忽略堆棧可能炸燬的問題)。處理通知包括循環引用
更具體地說,因爲我想從定義中分離出實現,所以我將爲Server類使用server.h和server.cpp,爲Client類使用client.h和client.cpp。由於服務器持有對客戶端的引用並從中調用方法,因此它需要#include "client.h"
。此外,客戶端持有對服務器的引用並從中調用方法,它需要#include "server.h"
。在這一點上,即使我在server.h和client.h中都使用了標頭守護程序,它仍然會出現錯誤(是的,這是預期的),所以我決定在client.h中轉發聲明Server類,並在服務器中聲明Client類。H。不幸的是,這還不足以解決問題,因爲我也在調用這兩個類的方法,所以我設法通過在客戶端中包含server.h來編譯& run(正確地說,據我所知)。 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;
}
對我來說很正常,不會稱之爲破解。 – Kimi
這通常是如何完成的。 –