条款四:确认对象被使用前已先被初始化

当我们定义一些值的时候比如:

class Point{
int x,y;
}
...
Point p;

上述的x,y有时候被初始化为0,有时候不会,读取未初始化的值会导致不明确的行为。所以我们要保证初始化每一个被定义的值。

1.class成员函数的初始化
对于非内置类型,我们一般采用构造函数对其进行初始化,但是有一点我们很容易忽略:

ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones)
{
theName=name;
theAdress=address;
thePhones=phones;
numTimesConsulted=0;
}

以上这些并不是初始化而是赋值,一般我们先构造theName等变量然后再利用其赋值构造函数进行赋值,这样会降低运行效率,真正的初始化如下:

 ABEntry::ABEntry(const std::string& name,const std::string& address,const std::list<PhoneNumber>& phones):theName(name),
    theAdress(address),
    thePhones(phones)
    numTimesConsulted(0)
    {}

以上使用初始化列表的构造函数才是真正的初始化。
注意:
1.在初始化时,无论初始化列表的次序怎么样,变量被初始化的次序总是其在类里面被定义的次序。所以尽量将两者的次序保持一致。
2.当我们的类有多个构造函数,且变量众多时,初始化列表会显得很麻烦,浪费时间,所以一般是将初始化写成一个函数,然后供构造函数调用,但是这里还是建议初始化列表的使用。

不同编译单元内定义之non-local static对象
所谓static对象,其寿命从被构造出来直到程序结束为止,这种对象包括global对象,定义于namespace作用域里面的对象,在class内,函数内,以及在file作用域内被声明static的对象。
函数内的static对象被称为local static对象(因为它们对函数而言是local),其他static对象被称为non-local static对象。

但是对于C++而言,定义于不同编译器单元内的non-static static对象的初始化相对次序并无明确定义,所以可能出现我们在一个文件类使用另一个文件的non-static对象,而那个对象却还没有初始化的情况。

但是C++保证,函数内的local static 对象会在“该函数被调用期间”“首次遇上该对象之之定义式”时被初始化,所以我们将每个non-local static 对象搬到自己的专属函数内(该对象在此函数内被声明为static)。这些函数返回一个reference指向它所含的对象,然后用户调用这些函数,而不直接指涉这些对象,换句话说non-static 对象被local static对象替换了。
例如:
class FileSystem{…};
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
上述方法针对于单线程,而不是多线程。

猜你喜欢

转载自blog.csdn.net/Du_Shuang/article/details/82992880