我故意创建以下代码,让我轻松提出问题。
问题>所有变量的初始化顺序是什么?
#include <iostream>
int iGlobal = 10;
class A {
public:
A(int _a) : m_a_a(_a) {}
private:
int m_a_a;
};
class B : public A
{
public:
B() : m_b_b(40), A(20), m_b_a(30) {}
private:
static int m_b_static_a;
int m_b_a;
int m_b_b;
int m_b_c; // this variable is NOT initialized in the B::B() initialization list
static int m_b_static_b;
};
int B::m_b_static_a = 11;
int B::m_b_static_b = 12;
int main(void)
{
B b;
return 0;
}
首先,我列出所有变量如下:
iGlobal, m_a_a, m_b_static_a, m_b_a, m_b_b, m_b_c, m_b_static_b
以下是我认为我是对的。
m_a_a < m_b_a < m_b_b < m_b_c (i.e. X < Y iff X is initialized early than Y)
m_b_static_a < m_b_static_b
的Rule1&GT; C ++保证编译单元(.cpp文件)中的变量按声明顺序初始化。
规则2&GT;初始化列表中列出的顺序不控制初始化的顺序。
我在全局变量,静态变量和非静态变量中排序有问题。
答案 0 :(得分:4)
在编译单元中,全局变量的初始化顺序与它们声明的顺序相同。但是,订单在不同的编译单元中未指定(请参阅What's the "static initialization order fiasco"?)。
课程初始化顺序:
成员初始化遵守声明顺序,无论初始化列表中使用的顺序如何。
拥有class C : public A, public B
,初始化A
,然后B
,然后C
。它们的破坏以相反的顺序发生。
注意:虚拟基类不遵守上述顺序。
引用C ++ 03标准中的§12.6.2/ 5:
初始化应按以下顺序进行:
- 首先,仅适用于派生程度最高的类的构造函数 如下所述,虚拟基类应在中初始化 命令它们出现在深度优先从左到右的遍历中 基类的有向非循环图,其中“从左到右”是 派生类中基类名称的出现顺序 基说明符列表。
- 然后,直接基类应按声明顺序初始化 因为它们出现在base-specifier-list中(无论顺序如何) mem-initializers)。
- 然后,非静态数据成员应按其顺序初始化 在类定义中声明(再次无论顺序如何) 记忆初始化者。)
- 最后,执行构造函数的主体。
结束,订单将是:
iGlobal (global)
B::m_b_static_a (static)
B::m_b_static_b (static)
A::m_a_a (base class member)
B::m_b_a (class member)
B::m_b_b (class member)
答案 1 :(得分:2)
不,所有“全局”都将在main
之前初始化:
iGlobal, m_b_static_a, m_b_static_b, m_a_a, m_b_a, m_b_b
,m_b_c
永远不会被初始化。
答案 2 :(得分:0)
规范初始化顺序是:
这是我在VC ++ 2005中观察到的初始化顺序:
iGlobal
之前的全球数据(main()
== 10)B::m_b_static_a
== 11,B::m_b_static_b
== 12)A::m_a_a
== 20)B::m_b_a
== 30,B::m_b_b
== 40) B::m_b_c
仍然未初始化(设置为0xcccccccc
)。