5

これは未熟な質問であることは承知していますが、モックアップのクライアント サーバー シーケンシャル インタラクション アプリケーションを実装する必要があります。クライアントとそれをサーバーに転送し、その逆も同様であるため、クラスとクラスが相互に認識できるようにしてServerClientクラス間でパブリックメソッドを呼び出すことができるようにする必要があります。1 つのアプローチは、両方をシングルトンとして設計することですが、より単純な方法で、より正確には循環参照を使用することを望んでいました。クライアントはサーバーへの参照を格納し、サーバーはクライアントへの参照を格納します。これは良いアプローチではない可能性があることを認識しており、コールスタックが深くなりすぎると爆発する可能性があります、そのため、私のデザインの改善は大歓迎です。

説明されている実装を実現するために、2 つのセッターを呼び出したときに main の 2 つの変数が破壊されるのを防ぎたい場合にも機能しないstd::shared_ptrため、を使用できると思いました (右?)。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;
}

残念ながら、私のコードはクライアントとサーバーの (暗黙の) デストラクタを複数回呼び出すか、または同様の厄介なことを試みているようですstd::shared_ptr。お知らせ下さい。

4

2 に答える 2

7

サーバーとクライアントのインスタンスをスタックに割り当てます。これらはmain()終了時に削除されます。std::shared_ptrそれらも削除したくありません。したがって、2 つの解決策があります。

  1. クライアントとサーバー内でアンマネージ ポインターを使用し、それらの有効期間を外部で管理します。

  2. を含むあらゆる場所でマネージ ポインターを使用しますmain()shared_ptr所有権を意味することに注意してください。現在の設計では、サーバーがクライアントを所有していますが、クライアントもサーバーを所有しています。これは循環参照です。デフォルトでは、これらのポインターのいずれかをリセットできるうちにリセットしない限り、解放されることはありません。

    例として、クライアントがサーバーを存続させるように決定することができます。したがって、他の shared_ptrs がそれを指していない場合、最後に消失したクライアントがサーバーをダウンさせます。サーバーはweak_ptrクライアントに対して a を持ちますが、クライアントはshared_ptrサーバーに対して a を持ちます。

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;
}
于 2012-06-20T20:00:03.260 に答える
0

変数には自動有効期間があり、スコープ外になると破棄されます。

したがって、ライフタイムを管理するスマートポインターのいずれかを使用すると、2回目にdeleteが呼び出されるため、間違っています。

于 2012-06-20T19:53:30.840 に答える