条款4:确定对象被使用前已先被初始化
初始化有的会认为进行了,有的却不认为,有的次语言被初始化,而有的不会,所以最佳处理办法为:
== 永远在使用对象之前先进行初始化,无论任何成员的内置类型,必须手工完成此事==
int x = 0; //对int进行手工初始化
double d;
std::cin >> d; //以读取input stream的方式初始化
对于内置类型以外的任何其他的东西,初始化的责任落在构造函数身上,确保每一个构造函数都将对象的每一个成员初始化。
赋值和初始化的区别:
详见网站链接
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 numTimesConsulted;
};
ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones)
{
theName = name;
theAddress = address; //这些为赋值而不是初始化
thePhones = phones;
numTimesConsulted = 0;
}
C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。
上的最佳写法为**成员初值列**替换赋值操作:
ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones)
:theNmae(name),theAddress(address),thePhones(phones),numTimesConsulted(0)
{
}
内置类型如果成员变量是const
或references
,则需要初值而不是被赋值
为了避免需要记住成员变量何时必须在成员初值列中初始化,何时不需要,最简单的做法是:总是使用成员初值列
成员初始化次序,
- 基类更早于派生类
- class成员变量以声明次序初始化class成员变量以声明次序初始化
- 不同编译单元内定义之non-local对象
编译单元:产出单一目标文件的源码,基本上是单一文件加上其所含入的头文件
需要做的是:将每一个non-local static对象搬到自己专属函数内(该函数在此函数内被声明为static)。这些函数返回一个引用只想它所含的对象,用户调用这些函数而不是直接直涉这些对象。换句话说,non-local被local static对象替换了。这是设计模式的单例模式的一种常见的实现手法。这个手法基于:C++保证,函数体内的local static对象会在“给函数被调用期间”首次遇上该对象之定义式时被初始化。所以如果你以“函数调用”(返回一个reference指向local static对象)替换“直接访问non-local static 对象”,你就得到保证,保证你所获得的那个引用将指向一个经历初始化的对象。
class FileSystem
{
public:
...
std::size_t numDisks() const;
...
};
extern FileSystem tfs;
----------------------------------------------------------
calss Directory{
public:
Directory(params);
...
};
Directory::Directory(params)
{
...
std:size_t disks = tfs.numDisks();
...
}
--------------------------
Directory tempDir(params);
修改为:
class FileSystem{...};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
class Directory{...};
Directory::Directory(params)
{
...
std::size_t disks = tfs().numDisks();
...
}
Directory& tempDir()
{
ststic Directory td;
return td;
}
唯一不同的是现在使用tfs()、tempDir()
而不是tfs,tempDir
,也就是说使用函数返回的“指向static对象”的引用,而不是static本身。
总结
1. 为内置型对象进行手工初始化,因为C++不保证初始化他们;
2. 构造函数嘴还是用尘缘初值列,而不要再构造函数本体内使用赋值操作。初值列列出的成员变量其排列次序应该和他们在class中的声明次序相同;
3. 未免除“夸编译单元之初始化次序”的问题,请以local static对象替换non-local static对象。