非静态数据成员按什么顺序初始化?

问题描述 投票:0回答:3

在下面的代码中,当调用

X
的ctor时,会先调用
A
还是
B
的ctor?它们在类主体中的放置顺序是否控制这一点?如果有人可以提供一段来自 C++ 标准的文本片段来讨论这个问题,那就完美了。

class A {};
class B {};
class X
{
 A a;
 B b;
};
c++ initialization datamember order-of-execution class-members
3个回答
86
投票

顺序是它们在类定义中出现的顺序 - 这是来自 C++ 标准第 12.6.2 节:

5 初始化应在 以下顺序:

— 首先,且仅适用于 最派生的构造函数 如下所述的类,虚拟基 类应在初始化 它们出现的顺序是深度优先的 从左到右遍历 基数的有向无环图 类,其中“从左到右”是 基类的出现顺序 派生类中的名称 基本说明符列表。

——然后,直接 基类应在中初始化 声明顺序如出现在 基本说明符列表(无论 内存初始化器的顺序)。

— 那么,非静态数据成员应为 按照它们的顺序初始化 在类定义中声明 (同样无论顺序如何 内存初始化器)。

—最后是本体 的构造函数被执行。 [笔记: 申报令的授权是 确保基类和成员子对象 以相反的顺序被销毁 初始化。 ]


15
投票

初始化始终按照类成员在类定义中出现的顺序,因此在您的示例中

a
,然后
b

每个成员的初始化之间有一个序列点,您可以将对尚未初始化的成员的引用传递到类成员的构造函数中,但您只能以有限的方式使用它(例如如将其地址形成指针),其他用途很可能会导致未定义的行为。

类成员的销毁总是以与构造相反的顺序发生。

基类和成员的初始化顺序在 12.6.2 [class.base.init]/5 中定义。


0
投票

我将添加@niki-yoshiuchi 评论作为答案,因为我认为它值得更多的关注。

补充一点,如果你有一个像这样的 X 构造函数 - X(): b(), a() {} a 仍然首先初始化。

所以从OP的例子来看:

class A {};
class B {};

class X {
    private:
    A a;
    B b;
    public:
    // a will be initialized _before_ b
    X() : b(), a() {}
};
© www.soinside.com 2019 - 2024. All rights reserved.