《剑指offer》—请写出如下代码的输出
#include <iostream>
using namespace std;
class A
{
private:
int n1;
int n2;
public:
A() : n2(0), n1(n2 + 2)
{
}
void Print()
{
cout << "n2="<<n2 << " n1=" << n1 << endl;
}
};
int main()
{
A a;
a.Print();
return 0;
}
电脑输出结果为:
如果把class A 中的 private 变量调整顺序为:
private:
int n2;
int n1;
或者把 class A 中构造函数改成:
A()
{
n2 = 0;
n1 = n2 +2;
}
那么此时输出结果为:
分析:
使用初始化列表初始化成员变量时,成员变量的初始化顺序只与类中声明的顺序顺序有关,与初始化列表中的顺序无关。因为成员变量的初始化次序由变量在内存中次序决定,而内存中的排列顺序早在编译期就根据变量的定义次序决定了(参见 EffectiveC++)。
如果不使用初始化列表初始化,而在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。
扩展
- 类成员在定义时,不能初始化
- 类中const成员常量,必须在构造函数初始化列表中初始化
- 类中static成员变量,必须在类外初始化
- 静态变量进行初始化顺序是基类的静态变量先初始化,然后是它的派生类。直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有“作用域”的全局变量。在一切初始化工作结束后,main函数会被调用,如果某个类的构造函数被执行,那么首先基类的成员变量会被初始化。
总结
变量的初始化顺序:
- 基类的静态变量或全局变量
- 派生类的静态变量或全局变量
- 基类的成员变量
- 派生类的成员变量