В ответ на мой старый вопрос я хочу реализовать клиент- имитация макета сервера, где клиент инициирует последовательность действий, включающую вызов методов на сервере, который, в свою очередь, может вызывать методы на клиенте (давайте проигнорируем проблему, что стек может взорваться).
В частности, поскольку я хочу отделить реализацию от определения, у меня будут server.h и server.cpp для класса Server и client.h и client.cpp для класса Client. Поскольку Сервер хранит ссылку на Клиент и вызывает у него методы, ему необходимо #include "client.h"
. Кроме того, Клиент хранит ссылку на Сервер и вызывает у него методы, ему нужно #include "server.h"
. На данный момент, даже если я использую защиту заголовков как в server.h, так и в client.h, это все равно мешает (да, это ожидаемо), поэтому я решил предварительно объявить класс Server в client.h и класс Client в server. .час. К сожалению, этого недостаточно для решения проблемы, потому что я также вызываю методы из двух классов, поэтому мне удалось скомпилировать и запустить его (насколько я могу судить, правильно), включив server.h в клиенте .cpp и client.h в server.cpp.
Вышеприведенный «хак» звучит разумно? Стоит ли ожидать каких-то непредвиденных последствий? Есть ли какой-нибудь «умный» способ сделать это без необходимости реализации прокси-класса?
Вот рудиментарный пример того, как будет выглядеть реализация:
файл клиент.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
файл север.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;
}