我知道这必须是一个n00b问题,但是我必须实现一个模型客户端 - 服务器顺序交互应用程序,并且因为客户端 - 服务器调用的数量不同,我不能只迭代外部函数中的步骤,总是提取来自客户端的数据然后将其转发到服务器,反之亦然,因此我需要让Server
和Client
类相互了解,以便他们可以在自己之间调用公共方法。一种方法是将两者都设计为单身,但我希望以更简单的方式进行,更准确地说使用循环引用:客户端存储对服务器的引用,服务器存储对客户端的引用。我知道这可能不是一个好方法,它可能会导致调用堆栈爆炸when it becomes too deep,因此欢迎对我的设计进行任何改进。
为了实现所描述的实现,我认为我可以使用std::shared_ptr
,因为如果我还想阻止main中的两个变量在我调用时被破坏,那么std::unique_ptr
将不起作用两个二传手(对吗?)。所以,这就是我所拥有的(简化代码):
#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;
}
不幸的是,我的代码似乎试图多次调用Client和Server(隐式)析构函数,或者一些类似的讨厌的东西,我确信这是由于我对std::shared_ptr
的概念的理解不足造成的。应该工作。请指教。
答案 0 :(得分:7)
您在堆栈上分配服务器和客户端实例,并在main()
退出时删除它们。您也不希望std::shared_ptr
删除它们。因此,有两种解决方案:
在客户端和服务器中使用非托管指针,并在外部管理其生命周期。
在任何地方使用托管指针,包括main()
。请注意shared_ptr
意味着所有权。在当前设计中,服务器拥有客户端,但客户端拥有服务器。这是一个循环引用:默认情况下,它们永远不会被释放,除非你仍然可以重置其中一个指针。
作为示例,您可以确定客户端使服务器保持活动状态,因此如果没有其他shared_ptrs指向它,则最后消失的客户端将关闭服务器。服务器对客户端有weak_ptr
,但客户端对服务器有shared_ptr
。
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;
}
答案 1 :(得分:0)
您的变量具有自动生命周期,并且当它们超出范围时将被销毁。
因此,使用任何生命周期管理智能指针都是错误的,因为它会再次调用delete。