-
26-10-2019 - |
質問
コードサンプルが与えられた場合:
class B {
//Some contents.
};
class C {
private:
B& b;
};
class A {
private:
B b;
C c;
};
クラスCにはABへの参照があるため、それを初期化する必要があります。クラスAには、BのインスタンスとCのインスタンスが含まれています。
私の質問は、bインスタンスでaでcインスタンスを初期化することができますか?第二に、AでBの明示的な初期化を実行する必要がありますか、それともクラス内のクラスタイプであるため、デフォルトの初期化されていますか?
解決
メンバー変数は、クラス宣言で宣言される順序で初期化されます(コンストラクターの初期化リストに別の順序でそれらを持っていても)、そう、時までに c
初期化されています、 b
初期化され、使用できます b
初期化します c
.
リカルド・カーデネスが指摘しているように、あなたが宣言してもそれはまだ機能します c
前 b
クラス定義で(つまり、合格することを意味します C::C
無知の参照 B
)ただし、あなたは未定義の動作を引き起こします 使用する 内部のオブジェクト C::C
. 。宣言する方が安全です b
まず、使用できないかもしれませんが b
中身 C::C
今、あなたは将来、参照が無知のものを指すことを忘れるかもしれません B
, 、そしてUBを引き起こします。
いいえ、明示的に初期化する必要はありません b
(そうでない限り ポッド)デフォルトの構成を望まない限り。したがって、このコードはあなたが望むものになるでしょう(もう一度、 B
ポッドではありません):
A::A() : c(b) { }
他のヒント
最初の質問に:このようなコンストラクターを書くことで初期化できます。
C::C(B& bInst): b(bInst){}
A::A():b(), c(b) {}
もちろん、あなたのコンストラクターの場合 C
実際に使用します b
(そのアドレスのみではなく)、初期化順序が同じままであることを確認する必要があります。 b
前に宣言する必要があります c
, 、メンバーは順序で初期化されるため、宣言されています(初期zaitonリストが別の順序で配置されていても)。
また、BBを明示的に初期化する必要はありません。これは、そうでない場合にデフォルトで構築されるためです。もちろん、bがポッドである場合、これはそれが非初期化されたままであることを意味します(一方 b()
の初期化リストで A()
に初期化します 0
).
bインスタンスでAでcインスタンスを初期化できますか(コンストラクターを入れることを気にしたと仮定します)
もちろん。
第二に、AでBの明示的な初期化を実行する必要がありますか、それともクラス内のクラスタイプであるため、デフォルトの初期化されていますか?
いいえ、それは大丈夫です。
はい、CにはA Bへの参照のみが含まれており、別のインスタンスではないため、コンストラクターをCに配置してACB参照ABにすることができます
Aのインスタンスを作成すると、A内のBとCは両方とも自動的にインスタンス化/構築されます。