条款4 确定对象使用前先被初始化
这里的初始化主要包括三个方面的内容:
1.对C++内置的类型进行手动的初始化。
2.构造函数使用成员初始化列表来进行初始化。
3.跨编译单元的对象初始化顺序,以local static 对象替换non-local static 对象。
构造函数使用成员初始化列表来进行初始化
这里需要注意不要在函数体内进行赋值操作,这样的话程序会先调用一次默认构造函数再调用一次,赋值操作。初始化顺序是先调用父类的构造函数,再以声明的次顺调用成员的构造函数,没在初始化列表中明确构造的函数会调用其默认构造函数。
跨编译单元的对象初始化顺序,以local static 对象替换non-local static 对象。
首先明确non local static对象:global对象 定义在namespace 以及class 内 file作用域内的static对象
local static 对象:定义在函数内的static对象。
以一段代码来阐述这一个问题:
第一个文件:
class FileSys
{
public:
size_t numDisks() const;
};
extern FileSys tfs;
第二个文件:
class Diectory
{
public:
Directory(param);
};
Directory::Directory(param)
{
size_t disks=tfs.numDisck();
}
Directory tempDir(params);
在这两个文件中都有一个non local的static 对象,在tempDir的构造函数里面调用了tfs的函数,但是我们并不知道现在tfs是否被初始化了,这样就会造成不明确的行为。
正确的做法是利用一个函数返回static对象,并且把non local static 对象替换为local static 对象,这样只有在第一次调用函数时才会初始化对象,具体代码见下面:
第一个文件:
class FileSys
{
public:
size_t numDisks() const;
static FileSys & tfs();
};
FileSys& FileSys::tfs()
{
static FileSys fs;
return fs;
}
第二个文件:
class Diectory
{
public:
Directory(param);
};
Directory::Directory(param)
{
size_t disks=FileSys::tfs().numDisck();
}
Directory tempDir(params);
这样在调用函数的时候即使没有初始化fs,也会首先初始化fs.