1

次のような「is-a」関係を作成している人を見てきました。

class TCPClient : public Socket
{
public:
    TCPClient(const std::string& host, unsigned short port);
};

ここで、Socket クラスは Connect()、Close()、Bind() などの Winsock 関数を実装します。

:

しかし、ソケットプログラミングの初心者である私にとって、これは自然なことではありません。

上記の階層は、次の「has-a」の対応よりも論理的に意味がありますか?

class TCPClient
{
public:
    TCPClient(const std::string& host, unsigned short port);
    ....
private:
    Socket m_socket;
};
4

4 に答える 4

4

TCPClientはソケットを使用するか、ソケットを持っていますが、それ自体はソケットではありません。通常、ソケットが期待される場所でTCPClientを置き換えることができるとは期待していません。そのため、公的継承は意味がありません。

この場合、プライベート継承を使用できますが、(少なくとも一般的なケースでは)おそらくあまり意味がありません。プライベート継承は、主に、基本クラスが子クラスでオーバーライドする予定の仮想関数を少なくとも1つ提供する場合に意味があります。仮想関数があり、それをオーバーライドする必要がある場合は、継承を使用する以外に実際の選択肢はありません。ただし、Socketクラスに仮想関数があるとは思いません。通常、ここでは適用されません。

これは基本的に2番目の解決策につながります。TCPClientには、継承を使用するのではなく、Socketのインスタンスを含める必要があります。

ただし、ここで示したSocketクラスは、実際のソケットの概念とアドレスの概念を混同しているように見えることを付け加えておきます。私の最初のソケットクラス(数年前)はそのように機能しましたが、それ以来、それは実際には理想的な設計ではないと結論付けました。アドレスの概念をソケット自体から分離しておくことは価値があると私は確信しました。私の場合は少し複雑ではありませんが、私が思いついたのは、BoostASIOが派生したプロトタイプである可能性がほとんどあるように見えるのは興味深いことです。少し小さくてシンプルですが、基本的な考え方の多くは、とにかく一般的にかなり似ています。

それが私の次の推奨事項につながります。BoostASIOを見てください。それ以外のことをするかなり具体的な理由がないので、それは私がほとんどの新しいコードでアドバイスする(そして一般的に使用する)ものです。(私が上で言ったように)私は何年にもわたっていくつかのソケットクラスを書いてきましたが、私はかなり長い間(何か?)新しいコードでそれらのどれも使用していません-それらは実際にはASIOに対して2つの可能な利点しかありません。最初のものは私だけに当てはまります。ASIOが存在する前にそれらを作成して使用したので、私はすでにそれらとそれらがどのように機能するかを理解しています。2番目は似ているかもしれません:少なくとも私には、それらは少し小さくて単純に見えます(しかし、繰り返しますが、それは私が最初にそれらを使用したという理由だけかもしれません)。それでも、(たとえば)他の人がすでに理解しているものを使用することの利点は、それらを非常に簡単に打ち負かします。

于 2012-07-01T15:45:54.253 に答える
2

を使用しhas-aます。TCPClient は、人が電話を使用するようにソケットを使用します。電話から人を導き出しますか?

于 2012-07-01T15:25:00.850 に答える
0

私はそう言うでしょう。ソケットは抽象化されたファイル記述子 (UNIX) またはハンドル (Windows) であり、関連付けられたリソースを持ち、オペレーティング システムによって管理されます。OSI モデルを考えると、ソケットはプレゼンテーション層 (2 つのノード間の通信チャネルを提示または記述する) にうまく適合しますが、ソケットを使用するプログラムはアプリケーション層に位置します。

これを考慮して、論理接続を提示および処理し、ソケットに関連付けられたリソースを何らかの方法で管理するために、ある種の高度なソケット (類推: C ポインターとスマート ポインター) を実装しない限り、ソケットから継承しないことをお勧めします。ビジネスまたはデータ処理ロジックを実装することを目的とするアプリケーションの場合XYZClient、これら 2 つの概念を混ぜ合わせて 2 番目のアプローチ (has-a) を使用することはありません。

インフラストラクチャ/リソース固有のロジックとビジネス/アプリケーション固有のロジックを分割します。

于 2012-07-01T15:08:38.603 に答える
0
class TCPClient : public Socket
{
public:
    TCPClient(const std::string& host, unsigned short port);
};

ネットワーク ソケットは TCP/IP だけでなく、ネットワーク ソケットを使用する他のプロトコルを実装するために "Socket" クラスを再利用する場合は、上記の設計が適しています。例えば:

class UDPClient : public Socket
{
};
于 2012-07-01T14:35:08.523 に答える