条款04:确定对象使用前已被初始化
一、使用初始化列表
我们前边提到了C++分为几个语言联邦,C++的C部分是无法确定的是否初始化的,而一些其他部分比如STL通常会帮我们进行初始化。为了不出现问题,我们最好选择所有情况都进行手动初始化。
除了一些基本内置类型比如数组,Int型等,我们自己定义的数据类型则需要完成构造函数。在构造函数中对成员初始化推荐使用初始化列表而不是赋值运算符。
比如:
class B {
int num;
B() : num(0) {
// TODO ...
}
// 或者
B() {
num = 0;
}
};
通常前一种方法的效率会更好一些,因为前一种方法直接对值进行了初始化;而后一种方法则会对值进行默认的初始化,然后再用赋值运算符进行覆盖。
Notice: 最好总是在初值列中列出所有的变量,以免发生遗漏造成不确定的行为。 当然,代码优雅优先。
二、初始化次序
C++有着比较固定的初始化次序
- Base Class 先于 Derived Class 被初始化
- 成员变量会以声明时的顺序进行初始化
所以最好初始化列表也按照声明顺序来写
三、使用local-static代替访问static
还是涉及到初始化次序的问题
比如我们有一个FileSystem
的类,还有一个Directory
的类。
当Directory
的类执行时,很正常的,他需要一个FileSytem
类辅助它完成操作,假设此时需要访问一个FileSystem
的static
变量。
此时会造成一个初始化顺序的问题,因为C++并没有对不同文件的static
顺序做出设定。
因此我们可以参照单例的设计方式,改为一下的样子:
class FileSystem {
FileSystem tfs() {
static FileSystem tfs;
return tfs;
}
};
这样的引用就可以保证初始化顺序了。