Effective C++读书笔记
--By Nathan.Yu 2007-11-12--
1 让自己习惯C++(三)
条款04:确定对象被使用前已先被初始化
读取未初始化的值会导致不明确的行为。
最佳的处理方法:永远在使用对象之前先将它初始化。
对内置类型:手工初始化。
对自定义类型:确保每个构造函数都将对象的每一个成员初始化。
别混淆了赋值(assignment)和初始化(initialization)。
1、 成员初始化何时发生?
C++规定,对象的成员变量的初始化发生在进入构造函数本体之前。使用member initialization list(成员初值列表)替换在构造函数体中的赋值动作。
2、 为什么使用初始化列表效率较高?
初始化列表避免了先调用成员的default构造函数这一多余的过程。
3、 内置类型成员应选用初始化列表还是赋值进行初始化?
内置类型的“赋值表现像初始化一样好”,但为了一致,最好也通过成员初始列表来初始化内置类型。
【要点摘录】请立下规则:规定总是在初值列表中列出所有成员变量,以免还得记得哪些成员变量(如果它们在初值列表中被遗漏的话)可以无需初值。
4、 何时内置类型成员变量必须使用初值列表初始化?
当它们是const或references时,它们就一定需要初值,不能被赋值。
5、 有多个构造函数,且成员较多时怎么办?如何初始化?
在这种情况下,可以合理的在初值列表中遗漏那些“赋值表现像初始化一样好”对成员,改用它们的赋值操作,并将那些赋值操作移往某个函数(通常是private),共所有构造函数调用。这种做法在“成员变量的初值系由文件或数据库读入”时特别有用。
6、 成员的初始化顺序如何?
C++有十分固定的初始化次序:base classes更早于其derived classes被初始化,而classes当成员变量总是以其声明的次序初始化。
【要点摘录】为避免你或你的检阅者迷惑,并避免某些可能存在的晦涩的错误,当你在初始化列表中以声明的次序初始化各成员。
7、 static对象有哪些?
所谓static对象,其寿命从被构造出来直到程序结束为止,因此stack和heap对象都被排除。这种对象包括:global对象;定义于namespace作用域内的对象;在classes内、在函数内、以及在file作用域内被声明为static的对象。其中,函数中的static对象称为local static对象,其他static对象称为non-local static对象。static对象的析构函数会在main函数结束时被自动调用。
8、 什么是编译单元?
所谓编译单元(translation unit),是指产出单一目标文件的那些源码。基本上它是单一源码文件加上其所含入的头文件。
【要点摘录】C++对“定义于不同编译单元内的non-local static对象”的初始化次序并无明确定义。
【要点摘录】C++保证,函数内的local static对象在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化。
请记住:
1、为内置型对象进行手工初始化,因为C++不保证初始化它们。
2、构造函数最好使用成员初值列表,而不要在构造函数体内使用赋值操作。初值列表列出的成员变量,其排列次序该和它们在class中的声明次序相同。
3、为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static 对象。(使用reference-returning函数)。