在c ++中是否未定义类的成员变量的构造顺序?

时间:2012-09-05 16:14:42

标签: c++

  

可能重复:
  Member fields, order of construction

如果我有一个有两个这样的成员的课程:

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

构建ab订单 未定义

如果我使用cl,那么无论我调用构造函数的顺序如何,成员总是按照它们在类中声明的顺序构造。在这种情况下,它始终为a然后b,即使我为A定义构造函数,如:

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

但我假设这只是特定编译器的行为。

2 个答案:

答案 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的值将不会指定。