C++:構築および初期化順序の保証
-
22-09-2019 - |
質問
C++ での構築順序と初期化順序の保証については、いくつか疑問があります。たとえば、次のコードには 4 つのクラスがあります。 X
, Y
, Z
そして W
. 。main 関数はオブジェクトをインスタンス化します。 class X
, のオブジェクトが含まれています。 class Y
, 、から派生します class Z
, したがって、両方のコンストラクターが呼び出されます。さらに、 const char*
に渡されるパラメータ X
のコンストラクターは暗黙的に のオブジェクトに変換されます。 class W
, 、 それで W
のコンストラクターも呼び出す必要があります。
C++ 標準では、コピー コンストラクターの呼び出し順序に関してどのような保証が与えられていますか?あるいは、同様に、このプログラムで何を印刷できるのでしょうか?
#include <iostream>
class Z {
public:
Z() { std::cout << "Z" << std::endl; }
};
class Y {
public:
Y() { std::cout << "Y" << std::endl; }
};
class W {
public:
W(const char*) { std::cout << "W" << std::endl; }
};
class X : public Z {
public:
X(const W&) { std::cout << "X" << std::endl; }
private:
Y y;
};
int main(int, char*[]) {
X x("x");
return 0;
}
編集:これは正しいです?
W |
/ \ |
Z Y |
\ / |
X V
解決
は、すべてのクラスでは、建設順序が保証されてベースクラスを、正しい順序でメンバ変数に続いて左から指定されたクラス定義で宣言されました。その拠点とメンバーの構造の全てが完了したら、クラスのコンストラクタ本体が実行されます。
あなたの例のX
ではZ
由来しY
ベースオブジェクトは、まずZ
部材Y
、y
のコンストラクタ本体の実行にX
の完了の次に構造を構築しているようX
が含まれる。
一時的W
は、それがX
の建設が始まる前に構築され、x
の完了の初期化後に破棄されますので、x
のコンストラクタに渡すために必要とされます。
だから、プログラムが印刷する必要があります:
W
Z
Y
X
他のヒント
1)まず、引数を計算するために必要とされます。
2)をこのベースクラスが構成されている。
その後メンバーは、クラスの宣言に出現順に構成されている3)。
4)次に、Xのコンストラクタが呼び出された
- W オブジェクトは、X へのコンストラクターが呼び出される前に構築されます。
- Z は X の基本クラスとして、X のメンバーより前に初期化されます。
- Y はメンバーの初期化中に初期化されます
- X のコンストラクターが実行されます。
。私は常に順序が何であるかを忘れて、IBMのサイトは仮想塩基が最初に初期化されますが、私はちょうどそれがトリビアよりも実際にはもっとだ場合に実行したことがありませんと言います。
ルールを要約すると次のようになります。
- 引数 (右から左へ)
a.一番右
b.右から2番目 - 基本クラス
- バーチャルベース
- 基本クラスを左から右へ
- クラス内の宣言順のメンバー
- 呼び出されるクラスのコンストラクター