可能重复:
成员字段、构造顺序
如果我的班级有两个这样的成员:
class A
{
int a;
int b;
A() {}
};
和的构造顺序是否未定义?a
b
如果我使用cl
,那么无论我以何种顺序调用构造函数,成员总是按照它们在类中声明的顺序构造。在这种情况下,它总是a
then b
,即使我定义了如下构造函数A
:
A() : b(), a() {}
但我假设这只是特定编译器的行为。
不,成员是按照声明它们的顺序构造的。
建议您以相同的顺序排列初始化列表,但您不需要这样做。如果您不这样做,那将非常令人困惑,并且可能导致难以检测的错误。
例子:
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-initializers 的顺序如何)。
— 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管 mem-initializers 的顺序)。
初始化的顺序与类中的声明顺序相同。
如果构造函数的初始化列表中的顺序不同,那么编译器通常会发出警告。例如对于类:
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
将是未指定的。