5

重複の可能性:
メンバーフィールド、構築の順序

このような2人のメンバーがいるクラスがある場合:

class A
{
    int a;
    int b;
    A() {}
};

とが構築される順序未定義ですか?ab

を使用する場合cl、コンストラクターを呼び出す順序に関係なく、メンバーは常にクラスで宣言されている順序で構築されます。この場合、コンストラクターを次のように定義したとしても、常にそうaなります。bA

A() : b(), a() {}

しかし、それは特定のコンパイラの動作にすぎないと思います。

4

2 に答える 2

14

いいえ。メンバーは、宣言された順序で作成されます。

初期化子リストを同じ順序で配置することをお勧めしますが、そうする必要はありません。そうしないと、非常に混乱し、検出が困難なエラーにつながる可能性があります。

例:

struct Foo {
    int a; int b;
    Foo() : b(4), a(b) { }  // does not do what you think!
};

初期化子で初期化されていない変数を読み取っているため、この構造は実際には未定義の動作ですa(b)


標準リファレンス(C ++ 11、12.6.2 / 10):

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

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

于 2012-09-05T16:16:39.403 に答える
2

初期化の順序は、クラスでの宣言の順序と同じです。

コンストラクターの初期化リストの順序が異なる場合、コンパイラーは通常、警告を発行します。たとえば、クラスの場合:

class A {
public:
    A() : b(1), a(b) {}
private
    int a;
    int b;
};

GCCは次のように警告します。

$ g++ -Wall c.cc
c.cc:5: error: expected `:' before ‘int’
c.cc: In constructor ‘A::A()’:
c.cc:6: warning: ‘A::b’ will be initialized after
c.cc:5: warning:   ‘int A::a’
c.cc:3: warning:   when initialized here

これは、エラーが発生しやすいためです。上記の例では、の値はa指定されていません。

于 2012-09-05T16:16:39.107 に答える