web-dev-qa-db-ja.com

クラスデータメンバーの初期化順序

次のコードでは、Xのc​​torが呼び出されると、AまたはBのc​​torが最初に呼び出されますか?クラスの本文に配置される順序でこれを制御しますか?誰かがこの問題について話すC++標準からのテキストのスニペットを提供できれば、それは完璧です。

class A {};
class B {};
class X
{
 A a;
 B b;
};
40
Nikhil

順序は、クラス定義に表示される順序です。これは、C++標準のセクション12.6.2からのものです。

5初期化は次の順序で行われます。

—最初に、以下で説明する最も派生したクラスのコンストラクターについてのみ、仮想基本クラスは、基本クラスの有向非循環グラフの深さ優先の左から右へのトラバーサルに現れる順序で初期化されます。 「左から右」は、派生クラスbase-specifier-list内の基本クラス名の出現順序です。

—次に、直接基底クラスは、(mem-initializersの順序に関係なく)base-specifier-listに出現する宣言順に初期化されます。

—次に、非静的データメンバーは、クラス定義で宣言された順序で初期化されます(これも、mem-initializerの順序に関係ありません)。

—最後に、コンストラクターの本体が実行されます。 [注:ベースとメンバーのサブオブジェクトが初期化の逆の順序で破棄されるように、宣言の順序が義務付けられています。 ]

66
anon

初期化は常にクラスメンバーがクラス定義に現れる順序で行われるため、例ではa、次にbの順になります。

各メンバーの初期化とあなたの間にはシーケンスポイントがありますcanまだ初期化されていないメンバーへの参照をクラスメンバーのコンストラクターに渡しますが、それを使用できるのは限られた方法(アドレスを取得してポインタを形成するなど)では、他の用途で未定義の動作が発生する可能性があります。

クラスメンバーの破棄は、常に構築の逆の順序で行われます。

ベースとメンバーの初期化の順序は、12.6.2 [class.base.init]/5で定義されています。

12
CB Bailey