Loops between two classes

I know this should be a question n00b, but I have to implement an application for sequential interaction with the mockup client server, and since the number of client-server calls is changing, I can’t just repeat the steps in the external function, always getting the data from the client, and then forward it to the server and vice versa, so I need my Server and Client classes to know about each other so that they can call their public methods among themselves. One approach would be to develop as singleton, but I was hoping to do it in a simpler way, more precisely using a circular link: the client stores a link to the server, and the server stores a link to the client. I know this may not be a very good approach, and this can cause the call stack to explode when it gets too deep , so any improvements in my design are welcome.

To achieve the described implementation, I thought that I could use std::shared_ptr because std::unique_ptr will not work if I also want the two variables from main not to be knocked down when I call two setters (right? ) So this is what I have (simplified code):

 #include <iostream> #include <memory> class Server; class Client { public: void SetServer (const Server &server); private: std::shared_ptr<const Server> server; }; void Client::SetServer (const Server &server) { this->server = std::shared_ptr<const Server>(&server); } class Server { public: void SetClient (const Client &client); private: std::shared_ptr<const Client> client; }; void Server::SetClient (const Client &client) { this->client = std::shared_ptr<const Client>(&client); } int main () { Server server; Client client; server.SetClient(client); client.SetServer(server); //Here I ask the client to start interacting with the server. //The process will terminate once the client //exhausts all the data it needs to send to the server for processing return 0; } 

Unfortunately, my code seems to be trying to repeatedly call client and server destructors (implicit), or some similar unpleasant things, and I'm sure this is due to my poor understanding of how std::shared_ptr Work. Please inform.

+4
source share
2 answers

You allocate your server and client instances on the stack, and they will be deleted when main() exits. You do not want std::shared_ptr delete them. So there are two solutions:

  • Use unmanaged pointers inside the client and server and manage their lives from the outside.

  • Use managed pointers everywhere, including main() . Note that shared_ptr implies ownership. In the current project, the Server belongs to the client, but the Client also owns the server. This is a circular link: by default, they will never be freed unless you reset one of these pointers while you can still.

    As an example, you can decide that the clients support the server, so the last disappearing client will reset the server if there are no other shared_ptrs on it. The server will have weak_ptr for the client (s), but clients will have shared_ptr on the server.

 class Client; class Server; class Client { public: void SetServer (const std::shared_ptr<const Server> &server); private: std::shared_ptr<const Server> server; }; void Client::SetServer (const std::shared_ptr<const Server> &server) { this->server = server; } class Server { public: void SetClient (const std::weak_ptr<const Client> &client); private: std::weak_ptr<const Client> client; }; void Server::SetClient (const std::weak_ptr<const Client> &client) { this->client = client; } int main() { std::shared_ptr<Server> server(new Server); std::shared_ptr<Client> client(new Client); server.SetClient(client); client.SetServer(server); // do stuff return 0; } 
+6
source

Your variables have an automatic lifetime and will be destroyed when they go out of scope.

Therefore, the use of any of the smart pointers that control the life cycle is incorrect, because it will cause deletion a second time.

0
source

All Articles