2

次のコードがあります。

class A {
 public:
  A() { }
};

class B {
 private:
  const A &a;

 public:
  B() : a() { }
  B(const A &ina) : a(ina) { }
};

コンパイルすると、次のようになります。

ab.cpp: コンストラクター 'B::B()':

ab.cpp:11: 警告: 参照型を持つ「const A& B::a」のデフォルト初期化

これにより警告が表示されるのはなぜですか? また、どのように修正すればよいですか?

4

4 に答える 4

13

C++ 言語での参照は、他のオブジェクトの「代替名」と考えることができます。名前は常にオブジェクトを参照し、そのオブジェクトなしでは存在できません。つまり、参照は「何も参照」できません。これは、参照が作成された時点ですぐにターゲット オブジェクトに参照をバインドし、その参照が存在する限りそのオブジェクトにバインドし続ける必要があることを意味します。この言語は、そのルールを可能な限り適用するように特別に設計されています。非集約クラス型内の参照メンバーの場合、そのようなメンバーはコンストラクター初期化子リストで明示的に初期化する必要があります。

厳密に言えば、参照のデフォルトの初期化を呼び出すプログラムは形式が正しくありません。日常の命名法では、「警告」ではなく「エラー」と見なされます。したがって、ここでの本当の「理由」は、コンパイラが単なる警告を発行した理由です (正式には、不正なコードを報告するのに十分な診断メッセージがあります)。

于 2013-08-21T21:11:55.000 に答える
5

標準から:

8.5.3 参照 [dcl.init.ref]

  1. T& または T&& として宣言された変数、つまり「T 型への参照」(8.3.2) は、T 型のオブジェクトまたは関数、または T に変換できるオブジェクトによって初期化されます。

  2. [...]

  3. 初期化子は、パラメーター宣言 (8.3.5)、関数の戻り値の型の宣言、クラス定義内のクラス メンバーの宣言 (9.2)、および extern 指定子が明示的に指定されている場合にのみ、参照のために省略できます。使用済み。

のコンストラクターはB、内部的に参照の既定のコンストラクターを呼び出すため、間違っています。これは不可能です。

参照メンバーは、コンストラクターのメンバー初期化リストで初期化する必要があります。そのため、デフォルトのコンストラクターの形式が正しくありません。

于 2013-08-21T21:19:57.133 に答える
2

UBです。参照は常に初期化する必要があります。

于 2013-08-21T21:09:07.580 に答える
1

参照は常に変数を参照する必要があります。したがって、B の最初のコンストラクターでのデフォルトの初期化は意味がありません。実際には、デフォルトで初期化された参照を持つことは、まったく初期化されていないポインターを持つことと同じです。どちらもメモリ内のランダムな場所を参照 (またはポイント) します。したがって、警告。

于 2013-08-21T21:11:14.703 に答える