您的位置:首页 > 编程语言 > C语言/C++

effective C++ 条款 4:确定对象被使用前已先被初始化

2012-01-07 10:16 330 查看
对象的成员变量的初始化动作发生在进入构造函数本体之前。


ABEntry::ABEntry(const std::string& name, const std::list<PhoneNumber>& phones)

{

theName = name; //这些都是赋值,不是初始化

thePhones = phones;

numTimesConsulted = 0;

}

这个构造函数首先调用default构造函数为theName, thePhones设初值,然后立刻对他们赋予新值

ABEntry::ABEntry(const std::string& name, const std::list<PhoneNumber>& phones)

:theName(name), // 这些是初始化

thePhone(phones),

numTimesConsulted(0)

{}

本例中的构造函数分别以name等为初值进行copy构造。

class的成员变量总是以其声明的次序被初始化。跟初始化列表中的顺序无关


编译单元是指产出单一目标文件的那些源码。基本上是单一源码文件加上其所含的头文件。

static对象,从被构造出来到程序结束为止,析构函数会在main()结束时被自动调用。


函数内的static对象称为local static对象;其他的包括global对象,定义于namespace作用域内的对象,在class内、以及在file作用域内被声明为static的对象被称为non-local static对象。

c++对“定义于不同编译单元内的non-local static对象”的初始化次序并无明确定义。

class FileSystem{ //来自你的程序库

public:



std::size_t numDisk() const;



};

extern FileSystem tfs; //预备给客户用的对象

class Directory{ //由程序库客户建立

public:

Directory(params);



};

Directory::Directory(params)

{



std::size_t disks = tfs.unmDisks(); //使用tfs对象



}

Directory tempDir(params)

由于tempDir和tfs属于定义在不同编译单元内的non-local static对象,不能保证tfs在tempDir之前被初始化。

消除这个问题的方法是将每个non-local static对象搬到自己的专属函数内,换成local static对象,做法有点像Sigleton模式。

c++保证函数内的local static 对象会在该函数被调用期间,首次遇上该对象的定义式时被初始化。所以以函数调用(返回一个reference指向local static对象)来替换直接访问non-local static对象。这样保证获得一个经过初始化的对象。并且,如果从未调用过non-local static对象的“仿真函数”,就绝不会引发构造函数和析构函数成本; 真正的non-local static对象可没这么便宜。

//reference returning 函数防止初始化次序问题

class FileSystem{…};

FileSystem& tfs() //这个函数用来替换tfs对象

{

static FileSystem fs;

return fs;

}

class Directory{…};

Directory::Driectory(params)

{



std::size_t disks = tfs().numDisks();



}

Directory& tempDir() //这个函数用来替换tempDir对象

{

static Directory td;

return td;

}



任何non-const static对象不论是local或non-local,在多线程环境下“等待某事发生”都会有麻烦。处理这个麻烦的一种做法是:在程序的单线程启动阶段手工调用所有reference-returning函数,这可消除与初始化有关的“竞速形势”(race condition)。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: