参考までに、動作は C++03 の § 12.7 2-3 で指定されています。
2) クラス X のオブジェクトを参照するポインタ (左辺値) を、X の直接的または間接的な基底クラス B へのポインタ (参照) に明示的または暗黙的に変換するには、X の構築と、その直接または間接のすべての構築B から直接的または間接的に派生する間接ベースが開始され、これらのクラスの破棄が完了していない必要があります。そうでない場合、変換によって未定義の動作が発生します。
this
へのポインタDerived
です。InはBase::Base()
、this
暗黙的に aBase*
にキャストされます。これは、Derived の構築が開始され、 から派生する他のベースがないため許可されBase
ます。
§ 12.7 2 続き:
オブジェクト obj の直接の非静的メンバーへのポインターを形成する (またはその値にアクセスする) には、obj の構築が開始され、その破棄が完了していない必要があります。それ以外の場合、ポインター値の計算 (またはメンバー値へのアクセス) は完了していません未定義の動作が発生します。
最後に、§ 12.7 3 も重要です。
3) 仮想関数 (10.3) を含むメンバー関数は、構築または破棄 (12.6.2) 中に呼び出すことができます。仮想関数がコンストラクター ( mem-initializerを含む) から直接または間接的に呼び出された場合データ メンバの場合) またはデストラクタから、および呼び出しが適用されるオブジェクトが構築中または破棄中のオブジェクトである場合、呼び出される関数は、コンストラクタまたはデストラクタ自身のクラスまたはそのベースの 1 つで定義されている関数ですが、コンストラクタまたはデストラクタのクラスから派生したクラスでそれをオーバーライドする関数、または最も派生したオブジェクトの他の基本クラスの 1 つでそれをオーバーライドする関数 (1.8)。仮想関数呼び出しが明示的なクラス メンバ アクセス (5.2.5) を使用し、object-expression が構築中または破棄中のオブジェクトを参照しているが、その型がコンストラクタまたはデストラクタ自身のクラスでもその基底の 1 つでもない場合、呼び出しは未定義です。
これらの 2 つの句は、一貫性のない状態にある可能性がありますが、コンストラクターが開始されると、のインスタンスがDerived
完全に機能することを意味します。Base
Base