データ メンバーとしてポインターと参照のどちらを優先すべきでしょうか? 質問する

データ メンバーとしてポインターと参照のどちらを優先すべきでしょうか? 質問する

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

class A {};

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

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

は、Bの一部を更新する役割を担っていますC。 コードを lint で実行したところ、参照メンバーに関するエラーが発生していました。リント#1725これはデフォルトのコピーと割り当てに注意することについて説明していますが、これは妥当なことですが、デフォルトのコピーと割り当てはポインターでも問題があるため、あまり利点はありません。

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

通常、ポインターが null になるか変更される可能性がある場合にのみ、ポインターをデータ メンバーとして使用します。データ メンバーの参照よりもポインターを優先する理由は他に何かありますか?

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

ベストアンサー1

私の経験則:

  • オブジェクトの寿命を他のオブジェクトの寿命に依存させたい場合には参照メンバーを使用します。: これは、割り当てがなく、コンストラクターを介して参照の初期化を取得する義務があるため、別のクラスの有効なインスタンスがなければオブジェクトが存続できないことを明示的に示す方法です。これは、インスタンスが別のクラスのメンバーであるかどうかについて何も想定せずにクラスを設計するのに適した方法です。インスタンスの寿命が他のインスタンスに直接リンクされていると想定するだけです。これにより、クラス インスタンスの使用方法を後で変更できます (new を使用する、ローカル インスタンスとして、クラス メンバーとして、マネージャーのメモリ プールによって生成されるなど)。
  • その他の場合にはポインタを使用する: メンバーを後で変更する場合は、ポインターまたは const ポインターを使用して、指し示されたインスタンスのみを読み取るようにしてください。その型がコピー可能であると想定されている場合、参照を使用することはできません。場合によっては、特別な関数呼び出し (たとえば init()) の後にメンバーを初期化する必要があり、その場合はポインターを使用する以外に選択肢がありません。ただし、間違ったポインター状態をすぐに検出するには、すべてのメンバー関数でアサートを使用してください。
  • オブジェクトの有効期間を外部オブジェクトの有効期間に依存させ、その型をコピー可能にする必要がある場合は、ポインタメンバーを使用し、コンストラクタでは引数を参照します。この方法では、構築時にこのオブジェクトの有効期間が引数の有効期間に依存することを示しますが、実装ではポインターを使用してコピー可能のままにします。これらのメンバーがコピーによってのみ変更され、型にデフォルト コンストラクターがない限り、型は両方の目的を満たす必要があります。

おすすめ記事