构造函数初始化列表评估顺序


252

我有一个带有一些参数的构造函数。我以为它们是按照列出的顺序构造的,但是在一种情况下,看来它们是反向构造的,从而导致中止。当我反转参数时,程序停止中止。这是我使用的语法示例。事实是,在这种情况下,a_需要在b_之前初始化。能保证施工顺序吗?

例如

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};

6
您说的是在询问构造函数参数,但是在到达构造函数之前先对它们进行了评估,并且它们以未指定的,由编译器确定的顺序进行评估。但是,您实际上是在询问初始化列表的顺序,所以我为您更改了问题标题。
罗伯·肯尼迪

Answers:


278

它取决于类中成员变量声明的顺序。因此a_b_在您的示例中,第一个将成为第二个。


22
实际上,如果声明中的顺序与构造函数的初始化程序列表的顺序不同,则好的编译器会发出警告。例如,请参见-Wreordergcc。
2009年

236
之所以以成员声明顺序而不是按照构造函数中的顺序构造它们,是因为一个可能有多个构造函数,但是只有一个析构函数。破坏者以重新构建的顺序破坏成员。
AProgrammer

3
我们的意思是……声明的相反顺序。不是“构造”的,析构函数可能无法查看构造函数是否知道?
康拉德·B

196

引用标准以进行澄清:

12.6.2.5

初始化应按以下顺序进行:

...

  • 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(同样,无论mem-initializer的顺序如何)。

...


18

现在,其标准参考为12.6.2第13.3节:

(13.3)—然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样,无论mem-initializer的顺序如何)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.