1. ホーム
  2. c++

[解決済み] メンバーデータにはポインタとリファレンスのどちらを使うべきですか?

2022-05-06 19:20:30

質問

これは、質問を説明するための簡略化された例です。

class A {};

class B
{
    B(A& a) : a(a) {}
    A& a;
};

class C
{
    C() : b(a) {} 
    A a;
    B b; 
};

このコードをlintにかけたところ、参照メンバについて警告が出ました。 lint#1725 . しかし、デフォルトのコピーと代入は、ポインターについても同様で、ほとんど利点がありません。

裸のポインターは、そのポインターを削除する責任が誰にあるのかが不明確になるので、私は常に、できる限り参照を使用するようにしています。 私はオブジェクトを値で埋め込むことを好みますが、ポインタが必要な場合は、ポインタを所有するクラスのメンバーデータでauto_ptrを使用し、オブジェクトを参照として渡しています。

一般的に、メンバーデータでポインターを使用するのは、ポインターがNULLになる可能性がある場合や、変更される可能性がある場合に限られますね。 データ・メンバに参照ではなくポインタを使用する他の理由はありますか?

参照は一度初期化されると変更できないはずなので、参照を含むオブジェクトは割り当て可能であってはならないというのは本当でしょうか?

どのように解決するのですか?

参照メンバは、クラスの実装ができることを制限し(あなたが言うように、代入演算子の実装を阻止することを含む)、クラスが提供できることに何のメリットももたらさないので、避けてください。

問題例です。

  • を使用すると、各コンストラクタの初期化リストで参照を初期化することを余儀なくされます。この初期化を別の関数 ( C++0xまでは、とにかく を編集してください。 C++は現在 委譲コンストラクタ )
  • 参照はリバウンドしたり、NULLにすることはできません。これは利点でもありますが、もしコードを変更して再バインドを可能にしたり、メンバーをNULLにしたりする必要がある場合は、そのメンバーのすべての使用方法を変更する必要があります。
  • ポインタ・メンバとは異なり、リファレンスはスマート・ポインタやイテレータに簡単に置き換えることができないので、リファクタリングで必要になるかもしれません。
  • 参照が使用されるときはいつでも、値型( . 演算子など)、しかしポインタのようにふるまう(ぶら下がることができる) - だから例えば Googleスタイルガイド を推奨しています。