一、中心内容
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对象会在“该函数被调用期间”“首次遇上该对象的定义式”时被初始化。