1) static const变量的初始化
请参考
http://blog.csdn.net/yeming81/archive/2010/05/31/5637717.aspx
2) 全局变量初始化的依赖性
l 引出问题
1.cpp
ofstream out(“a.txt”);
2.cpp
extern ofstream out;
class A
{
public:
A()
{
out<<”hello”<<endl;
}
}
A a;
问题描述:
编译时,没有问题;
链接时,链接器会找到out对象的定义。但是,a和out都是全局对象,因为属于不同的文件(编译单元),谁先初始化不一定的。这时就会出现问题。
l 解决
1) 尽量避免使用它
2) 实在不行只能避免出现问题
当第一次使用时,对它进行初始化,可以用一个static变量控制。
3) 局部变量
l 函数里的局部变量是随机值
void Func()
{
//自定义结构体 (int year, int month, int day)
Date date; //随机值
}
4) 初始化列表
l 初始化顺序
初始化顺序取决于声明顺序,而不是在初始化列表中的顺序。
因为:构造函数有多个,如果初始化列表中初始化顺序不一样,那么析构顺序如何确定!!!
以下必须在列表里初始化
l 用于const成员的初始化
构造函数也是函数,所以,编译器必须保证在所有函数有机会用到const成员前初始化,以后的修改赋值都将视为违法。
l 用户引用的初始化
构造函数也是函数,所以,编译器必须保证在所有函数有机会用到reference成员前初始化,以后的任何二次初始化都将视为违法。
l 用于基类构造函数的调用 – 如果没有默认构造函数
因为:
构造函数不只一个,所以编译器不可能随便调一个初始化,况且还有参数值。
也不能放进构造函数,因为父类基类构造是有顺序的,为了避免用户在初始化成员后才调用基类构造,在子类构造函数调用之前,基类构造函数必须调用,只能在子类构造之前找个地方初始化基类。
class A
{
public:
A(int){};
};
class B: public A
{
public:
B(): A(1){}//如果A只有默认构造函数,不写编译
器也会给调用的。
};
l 用于用户类成员的初始化 – 如果用户成员没有默认构造函数
理由同上。
可在构造函数里初始化
l 用户类成员的初始化
如果在构造函数里直接赋值,编译器先调用默认构造函数,然后调用的是拷贝赋值重载(operator=);
但,如果在初始化列表里,直接调用构造或者拷贝构造,省略了一个函数,效率更高。
l 内置类型的初始化
为了统一,一般在初始化列表里初始化,效率没有区别。
注意:析构函数就没有什么初始化列表,因为只有一个默认析构函数,而且没有参数,编译器可以搞定。