如果我有一个有两个这样的成员的课程:
class A
{
int a;
int b;
A() {}
};
构建a
和b
的订单 未定义?
如果我使用cl
,那么无论我调用构造函数的顺序如何,成员总是按照它们在类中声明的顺序构造。在这种情况下,它始终为a
然后b
,即使我为A
定义构造函数,如:
A() : b(), a() {}
但我假设这只是特定编译器的行为。
答案 0 :(得分:13)
没有。成员按照声明的顺序构建。
建议您按照相同的顺序安排初始化列表,但不要求您这样做。如果你不这样做会非常混乱,并可能导致难以发现的错误。
示例:
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的顺序如何)。
答案 1 :(得分:2)
初始化的顺序与类中声明的顺序相同。
如果构造函数初始化列表中的顺序不同,则编译器通常会发出警告。例如,对于班级:
class A {
public:
A() : b(1), a(b) {}
private
int a;
int b;
};
海湾合作委员会将警告:
$ 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
的值将不会指定。