2

パブリッククラスメンバーの違いは何ですか

class data
{
public:

    std::list<data> list_of_data;
};

そして、プライベートメンバーを参照として返すメソッドは?

class data
{
public:

   std::list<data>& get_data()
   { return list_of_data; }

private:

    std::list<data> list_of_data;
};

どちらの方がよいですか?

4

5 に答える 5

3

その質問はその形ではあまり意味がありません。list_of_data2 番目のケースでが実際に のメンバーであるという事実を公にブロードキャストした場合data(プライベートであっても)、実際には違いはありません。

しかし、それは私たちがプライベートメンバーを持っている理由ではありません。典型的な C++ 設計では、2 番目のバリアントでは、外部コードは のプライベート メンバーに関する知識を使用できませんdata。外部コードが知っているのは publicget_data()メンバーだけです。それが実際のデータのどこにget_data()行くのか - 部外者は知りませんし、気にしません。

この場合、違いは非常に顕著になります。

  • list_of_data最初のケースでは、 class のメンバーとして物理的に存在するという事実を公開していますdata。たとえば、 の寿命が対応するインスタンスlist_of_dataの寿命と同じであることをすぐに意味します。また、インスタンスごとにメンバーが異なるdataことも意味します。datalist_of_data

  • 2 番目のケースでは、そのようなものを公開していません。std::list<data>外部コードは、実際のオブジェクトがどこにあるか、およびその有効期間を知りません。外部コードは、 の異なるインスタンスがメンバーdataから異なる参照を返すかどうかを知りません。get_data()これらの質問に対する答えを得るために、外部のユーザーは、コードを読んで結論を急ぐのではなく、意図したコードの設計に注意を払わなければなりません。そして、それは良いことです。

これが、データ メンバーを公開する代わりにアクセサー関数 (参照を返すものであっても) をよく使用する理由です。

于 2012-07-04T17:30:44.673 に答える
2

2 番目のアプローチは、ほとんどの場合、より望ましい方法です。非常に便利なだけの、少し余分な抽象化を追加します。

たとえば、2 番目の方法では、メンバー変数をクラス内の他のコンポジットに移動しても、インターフェイスを維持できます。それを PIMPL に移動して、含める要件を削除することもできます<list>。または、関数を仮想にして、メンバーを別の場所に移動することもできます。基本的に、クラスを使用するすべてのコードの変更に対する耐性が高まります。これは常に良いことです。

最も基本的な形式では、関数は通常インライン化されており、実行時に抽象化が自由になります。

現在、実際に無料ではない唯一の側面はプログラマーの時間です。関数の作成を省略した方が費用対効果が高いと思われる場合は、そうしてください。tuple<>しかし、おそらく、またはのような「ダム」集計タイプのいずれかを使用する必要がありますpair<>

于 2012-07-04T17:29:59.347 に答える
0

いくつかの記事を参照してください。

gotw #70 - カプセル化公開、保護、非公開のデータ メンバーに関する質問を扱います。

gotw #76: アクセス権の使用と乱用

いくつかの gow 記事 (上記のものを含む) を含むHerb Sutter のExceptional C++ スタイルを読んだ後、私は間違いなくあなたの 2 番目の例: プライベート メンバー、パブリック アクセス メソッドに投票します。

于 2012-07-04T18:09:56.580 に答える
0

構造体でない場合 (つまり、ロジックのないデータのみ)、メンバーは非公開にする必要があります。説明については、たとえば Herb Sutter を読んでください。

于 2012-07-04T17:10:22.717 に答える
0

どちらのアプローチも、オブジェクトを変更したり、新しいオブジェクトに置き換えたりできるため、カプセル化としては不適切です。代わりにget、オブジェクトを値またはconst参照で返すメソッドを使用します。

const MyClass &getObj() { .... }

返されたオブジェクトを変更できないようにします。

編集 返されたオブジェクトを変更したい場合は、参照によって返してください。これは、私の考えでは、少なくとも よりも優れていpublic fieldます。

于 2012-07-04T17:11:41.667 に答える