Effective C++ 学习笔记 条款04 确定对象被使用前已先被初始化

读取未初始化的值会导致不明确行为。某些平台上读取未初始化的值就会使程序终止运行。

永远在使用对象前对其进行初始化。

构造函数体中可用=给数据成员赋值,也可以在构造函数初始化列表中对数据成员初始化。使用构造函数初始化列表效率较高,因为前者在初始化后又进行了赋值操作。

构造函数初始化列表中也能使用默认构造函数初始化类类型成员。

总是应该在构造函数初始化列表中列出所有成员变量,虽然类类型的变量会使用默认构造函数初始化,但写出来以避免还得记住哪些成员变量不需显式初始化。内置类型变量的赋值和初始化成本相当,但最好也在构造函数初始化列表中列出,因为const或引用成员必须初始化而不能赋值。

如一个类中有多个构造函数,所有成员每次都要在初始化列表中重复初始化,写起来很麻烦,此时我们可以将那些赋值表现得像初始化一样好的成员变量放到一个private函数中完成,在各个构造函数体中调用这个函数即可。

类的构造函数初始值列表总是先初始化基类,再初始化该类,同一类中数据成员的初始化顺序与其在类中声明的顺序相同。初始值列表中基类和该类成员初始化的顺序最好与以上所述顺序相同。

static对象寿命从构造出来到程序结束为止,main结束时会调用析构函数销毁static对象。这种对象包括global对象、定义在namespace中的对象、class或函数或file作用域内被声明为static的对象。

编译单元指产出单一目标文件的源码。它基本上是单一源码文件加上其含有的头文件。

不同编译单元内non-local static对象的初始化次序问题至少涉及两个源码文件,每一个内至少含一个non-local static对象。问题在于如果某个编译单元内的non-local static对象的初始化动作使用了另一编译单元内的某个non-local static对象,它所用到的对象可能并未初始化,因为C++对这两个对象的初始化次序没有明确定义。

我们可以通过把non-local static对象放到一个函数中解决,这个函数返回一个static对象的引用,这样用户调用这些函数就能获取该对象。这是Singleton模式的常见实现手法。这个函数中的static对象会在该函数首次被调用时被初始化,这样就能保证获得的引用永远是已被初始化的对象,并且,当你没有用这个函数时,也就省下了这个对象的构造和析构成本。并且可以定义这个返回static对象的函数只有对象创建和return语句,并声明为inline。但在多线程环境下,可能会有多个线程同时调用该函数发生竞速形势,可通过在程序的单线程启动阶段手动调用所有的reference-returning函数解决。

你可能感兴趣的:(Effective,C++(第三版))