コンストラクタの初期化リストの評価順序


252

いくつかの引数を取るコンストラクターがあります。リストされた順序で構築されていると想定していましたが、逆に構築されているために中止されたようです。引数を逆にすると、プログラムは異常終了しました。これは私が使用している構文の例です。この場合、a_はb_の前に初期化する必要があります。施工順序は保証できますか?

例えば

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};

6
あなたはコンストラクターの引数について尋ねていると言いますが、それらはコンストラクターに到達する前に評価され、それらは不特定のコンパイラーによって決定された順序で評価されます。しかし、あなたは本当に初期化リストの順序について質問しているので、質問のタイトルを変更しました。
ロブ・ケネディ

回答:


278

これは、クラス内のメンバー変数宣言の順序によって異なります。したがって、例a_では最初の1つ、次にb_2番目の1つになります。


22
実際、適切なコンパイラーは、宣言とコンストラクター初期化リストの順序が異なる場合に警告します。たとえば-Wreorder、gccを参照してください。
グレッグヒューギル

236
コンストラクターの順序ではなく、メンバー宣言の順序で構築されるのは、コンストラクターが複数ある場合がありますが、デストラクターが1つしかないためです。そして、デストラクタは、構造の逆の順序でメンバーを破壊します。
AProgrammer 2009

3
...宣言の逆の順序を意味しましたか?「コンストラクション」ではなく、デストラクタがコンストラクタを調べてそれを知ることはできないのでしょうか。
コンラッドB

196

明確にするために、標準を引用するには:

12.6.2.5

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

...

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

...


18

これに対する標準的な参照は、12.6.2セクション13.3のようになります。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.