5

可能重复:
成员字段、构造顺序

如果我的班级有两个这样的成员:

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

和的构造顺序是否未定义ab

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

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-initializers 的顺序如何)。

— 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管 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 回答