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

Posted

技术标签:

【中文标题】构造函数初始化列表评估顺序【英文标题】:Constructor initialization-list evaluation order 【发布时间】:2010-11-17 14:07:21 【问题描述】:

我有一个带有一些参数的构造函数。我曾假设它们是按列出的顺序构建的,但在一种情况下,它们似乎是反向构建的,导致中止。当我颠倒参数时,程序停止中止。这是我正在使用的语法示例。问题是,在这种情况下,a_ 需要在 b_ 之前初始化。能保证施工顺序吗?

例如

class A

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

    OtherClass a_;
    AnotherClass b_;
;

【问题讨论】:

您说您在询问构造函数参数,但在您到达构造函数之前对它们进行了评估,并且以未指定的编译器确定的顺序对它们进行评估。但是您确实是在询问初始化列表的顺序,所以我为您更改了问题标题。 我在一次采访中被问到这个问题:) 面试官可能从这里得到了问题:) 【参考方案1】:

这取决于类中成员变量声明的顺序。所以a_ 将是第一个,然后b_ 将是您示例中的第二个。

【讨论】:

事实上,如果您在声明与构造函数初始化列表中的顺序不同,好的编译器会发出警告。例如,请参阅 gcc 中的-Wreorder 之所以按成员声明顺序而不是按构造函数中的顺序构造它们的原因是,一个可能有多个构造函数,但只有一个析构函数。析构函数按照构造的重新排序顺序销毁成员。 我们的意思是...相反的声明顺序。不是“构造”,析构函数不可能看透构造函数知道吗?【参考方案2】:

引用标准,澄清一下:

12.6.2.5

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

...

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

...

【讨论】:

【参考方案3】:

standard reference 现在似乎是 12.6.2 第 13.3 节:

(13.3) — 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化 (同样不管内存初始化器的顺序)。

【讨论】:

以上是关于构造函数初始化列表评估顺序的主要内容,如果未能解决你的问题,请参考以下文章

Dart类(构造函数、单例)

C++构造函数的初始化列表

继承中的构造析构函数调用顺序

初始化列表中元素的求值顺序

条款04:确定对象使用前已被初始化

第20课.初始化列表