c++ - 两个类之间的循环引用

标签 c++ pointers client-server pass-by-reference circular-reference

我知道这一定是一个 n00b 问题,但我必须实现一个模型客户端-服务器顺序交互应用程序,并且由于客户端-服务器调用的次数不同,我不能只在外部函数中迭代步骤,总是获取来自客户端的数据,然后将其转发到服务器,反之亦然,所以我需要让我的 ServerClient 类相互了解,以便它们可以调用他们之间的公共(public)方法。一种方法是将两者都设计为单例,但我希望以一种更简单的方式来实现,更准确地说是使用循环引用:客户端存储对服务器的引用,服务器存储对客户端的引用。我知道这可能不是一个好方法,它可能会导致调用堆栈爆炸 when it becomes too deep , 所以欢迎对我的设计进行任何改进。

为了实现所描述的实现,我认为我可以使用 std::shared_ptr,因为如果我也想使用 std::unique_ptr 将无法工作当我调用两个 setter 时,防止来自 main 的两个变量被破坏(对吗?)。所以,这就是我所拥有的(简化代码):

#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;
}

不幸的是,我的代码似乎试图多次调用客户端和服务器(隐式)析构函数,或一些类似的讨厌的事情,我确信这是由于我对 std::shared_ptr 应该可以工作。请指教。

最佳答案

您在堆栈上分配您的 Server 和 Client 实例,它们将在 main() 退出时被删除。您不希望 std::shared_ptr 也删除它们。因此,有两种解决方案:

  1. 在客户端和服务器中使用非托管指针,并在外部管理它们的生命周期。

  2. 在任何地方都使用托管指针,包括 main()。请注意,shared_ptr 表示所有权。在当前的设计中,服务器拥有客户端,但客户端也拥有服务器。这是一个循环引用:默认情况下,它们永远不会被释放,除非您在仍然可以的时候重置其中一个指针。

    例如,您可以决定客户端让服务器保持事件状态,因此如果没有其他 shared_ptr 指向它,最后消失的客户端将关闭服务器。服务器将有一个到客户端的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;
}

关于c++ - 两个类之间的循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11127089/

相关文章:

c - 矩阵幂和指针

java - 无法使用JAVA连接到另一台电脑(另一个IP)

c++ - 未初始化的类字段和 STL 容器

C++ 做什么 >> 做什么

Javascript:如何销毁一组变量指向的值?

c - 为什么必须在以下代码中将结果变量声明为指针?

带 SSL 的 Tomcat,网站部分的客户端/服务器身份验证

c# - C# 中的 select() 函数

c++ - 无限循环

c++ - 是否可以从 cin 输入 "prepare"?