条款 04:确定对象被使用前已被初始化
Make sure that objects are initialized before thre’re used.
c++ 不保证下面语境初始化
int x;
class Point
{
int x, y;
};
Point p;
某些语境会被初始化为0,某些语境不能保证。
一般的,如果是 C part of C++,而且初始化会招致运行期成本,那么就不保证初始化。non-C part of C++ 又有不同。
所以 array 不保证初始化内容 而 vector 保证。
使用 member initialization list(成员初值列)初始化成员
A::A(const std::string& name, const std::string& Address)
{
theName = name;
theAddress = Address;
}
A::A(const std::string& name, const std::string& Address)
: theName(name)
, theAddress(Address)
{}
第一段中,会先调用 default 构造函数为 theName 和 theAddress 赋初值,再使用 copy assignment 对其赋值
第二段中,直接使用 copy 构造为 theName 和 theAddress 赋值。
一般情况下,下者更优。对于内置类型成本相同,但为了一致性相同最好也用成员初值列。
当继承层次过多,成员初值列导致代码大量重复时,可以考虑将性能影响少的初始化移至专门的初始化函数(通常是private)供构造函数调用
C++ 成员初始化顺序
- base class 优于 derived class
- 成员变量按照申明顺序初始化,与成员初值列顺序无关
不同编译单元的 non-local static 对象初始化次序
- C++ 对于不同编译单元的 non-local static 对象初始化次序无明确定义。这很难,最常见的,多个编译单元内的 non-local static 对象经由“模板隐式具现化(implict template instantiations)”形成。
- 一个简单的解决方法,可以把 non-local static 对象搬到专属函数,作为 local static 对象,该函数返回 reference 指向该对象,用户直接调用函数而非对象,最常见的就是单例模式的实现。
- 该方法的理论基础是:C++ 保证函数内的 local-static 对象会在“访问函数”、“首次遇上对象定义式”时被初始化