#ifndef CLAUSE4_H
#define CLAUSE4_H
//条款4:确定对象被使用前已先被初始化
//知识点1 为内置对象进行手工初始化,因为C++并不保证初始化它们。
//因为读取未初始化的值会导致不明确的行为
int x=0;
const char* text="a-c-style sstring";
double d;
std::cin>>d;
//知识点2 构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作。
//初值列列出的成员变量,其排列次序应该和它们在class中声明的次序相同。
//使用初值列的方法通常效率比较高,对于在函数本体内使用赋值操作,它们先调用default构造函数(实参到形参)
//然后再调用copy assignment操作符,而初值列(其初始化早于这些成员的default构造函数被自动调用前)使用一次copy构造函数。对大多数类型来说,初值列的效率是比较高效的,有时甚至高效的多。
//有些情况下即使面对的成员变量属于内置类型(那么其初始化与赋值的成本相同),也一定得使用初值列。因为:如果成员变量时const或reference,它们就一定需要初值,不能被赋值。(注意!这是只能使用初值列的情况)
//C++有着十分固定的“成员初始化次序”。是的,次序总是相同:base classes更早于其derived classes被初始化。而class成员变量总是以其声明次序被初始化。
//知识点3 为免除“跨编译单元初始化次序”问题,请以local static对象替换non-local static对象
//目标文件1中
class FileSystem{
public:
std::size_t numDisk()const;
};
//目标文件2中
extern FileSystem tfs;
class Directory
{
public:
Directory(string params)
{
std::size_t disks=tfs.numDisk();
}
};
Directory temDir(params);
//问题是:除非tfs在temDir之前被初始化,否则tempDir的构造函数会用到尚未初始化的tfs
//解决方法:将每个non-local static对象搬到自己的专属函数内(该对象在此函数内被声明为static)
//这些函数返回一个reference指向它所含的对象。(有点像Singleton模式的设计)
//这个手法的基础在于:C++保证,函数内的local static对象会在 “该函数被调用期间”“首次遇上该对象之定义式”时被初始化。所以你以函数调用替换“直接访问non-local-static”对象,你就获得了保证
//目标文件1中
class FileSystem{};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
//目标文件2中
class Directory{};
Directory::Directory(string params)
{
std::size_t disks=tfs().numDisk();//原来的tfs改成了tfs()
}
Directory & tempDir()
{
static Directory td;
return td;
}
#endif
本文探讨了C++中对象初始化的三个关键方面:为内置对象手工初始化、使用成员初值列表进行构造函数初始化以及通过局部静态对象避免跨编译单元初始化顺序问题。
1560

被折叠的 条评论
为什么被折叠?



