一、中心内容
1、为内置类型对象进行手工初始化,因为C++不保证初始化他们。
2、构造函数最好使用成员初始列表,而不要在构造函数本体内使用赋值操作。初始列表列出的成员变量,其排列次序应该和它们在class中的声明次序相同;
3、为免除“跨编译单元值初始化次序”问题,请以local static对象替换non-local static对象。
二、主要内容
(1)初始化的最佳方式是用初始化列表
e.g
class PhponeNumber{......}
class ABEntry { public: ABEntry(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones); private: std::string theName; std::string theAddress; std::list<PhoneNumber> thePhones; int num; };
//第一个版本 ABEntry::ABEntry(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones) { theName = name; theAddress = address; thePhones = phones; num = 0; }
//第二个版本
ABEntry::ABEntry(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones) :theName(name), theAddress(address), thePhones(phones), num(0) {}
note:
1)后者的效率通常比前者的较高,虽然结果一样。。。关键是:前者得事先调用成员变量的各个构造函数进行默认初始化,然后在赋予一个新值;而后者则直接调用构造函数,用给定的实参进行初始化!!!
2)然而对于内置类型来说,两种方法是一样的,即初始化和赋值的成本是一样的,因为其没有默认构造函数。。。但是也要将内置类型的成员变量列在列表中,所有的成员变量都得列入初始化列表中,以免引起不必要的错误;
3)总是使用列表初始化。(const和引用变量一定需要初值,而不能进行赋值)
4)由于一个类内可能有多个初始值列表,所以会产生一些重复的赋值工作。。。为解决这个问题,经常将那些“赋值和初始化一样成本”的成员变量在private里就进行初始化
5)初始化顺序按照声明的次序。
二、尽量用local static代替non-local static
(1)static对象包括两种:local对象,定义于函数内;non-local对象,定义于namespace作用域内、classes内或global对象。
(2)编译单元
指产出单一目标文件的单一源码文件+所含入的头文件。
note:
key问题:某编译单元的某个non-local static对象的初始化动作使用了另一个编译单元内的某个non-local static对象,它所用到的这个对象可能尚未被初始化,因为C++对“定义于不同编译单元内的non-local static对象”的初始化次序么有明确定义
e.g
class FileSystem { public: ... std::size_t numDisks() const; ... }; extern FileSystem tfs; /*改为: FileSystem& tfs() { static FileSystem fs; return fs; }*/ class Directory { public: Directory(int params); ...... }; Directory::Directory(int params) { ... std::size_t disks = tfs().numDisks(); //使用tfs对象.....红色括号为改进版 ... } /*改为: Directory& temDir() { static Directory td; return td; }*/ Directory tempDir(int params);
关于extern,见:
https://blog.csdn.net/csdnwei/article/details/51836182
说明:
上述代码中,temDir的构造函数可能会用到尚未初始化的tfs,但是temDir和tfs是定义于不同编译单元内的non-local static,初始化顺序无明确定义,会造成错误。
为了解决这个问题,做出以下改变:
基础:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象的定义式”时被初始化。