确定对象使用前已经初始化

一、中心内容

1、为内置类型对象进行手工初始化,因为C++不保证初始化他们。

2、构造函数最好使用成员初始列表,而不要在构造函数本体内使用赋值操作。初始列表列出的成员变量,其排列次序应该和它们在class中的声明次序相同;

3、为免除“跨编译单元值初始化次序”问题,请以local static对象替换non-local static对象。


二、主要内容

(1)初始化的最佳方式是用初始化列表

e.g

class PhponeNumber{......}
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 num;
};
//第一个版本
ABEntry::ABEntry(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones)
{
	theName = name;
	theAddress = address;
	thePhones = phones;
	num = 0;
}
//第二个版本
ABEntry::ABEntry(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones)
	:theName(name), theAddress(address), thePhones(phones), num(0)
{}

note:

1)后者的效率通常比前者的较高,虽然结果一样。。。关键是:前者得事先调用成员变量的各个构造函数进行默认初始化,然后在赋予一个新值;而后者则直接调用构造函数,用给定的实参进行初始化!!!

2)然而对于内置类型来说,两种方法是一样的,即初始化和赋值的成本是一样的,因为其没有默认构造函数。。。但是也要将内置类型的成员变量列在列表中,所有的成员变量都得列入初始化列表中,以免引起不必要的错误;

3)总是使用列表初始化。(const和引用变量一定需要初值,而不能进行赋值)

4)由于一个类内可能有多个初始值列表,所以会产生一些重复的赋值工作。。。为解决这个问题,经常将那些“赋值和初始化一样成本”的成员变量在private里就进行初始化

5)初始化顺序按照声明的次序。


二、尽量用local static代替non-local static

(1)static对象包括两种:local对象,定义于函数内;non-local对象,定义于namespace作用域内、classes内或global对象。

(2)编译单元

指产出单一目标文件的单一源码文件+所含入的头文件。

note:

key问题:某编译单元的某个non-local static对象的初始化动作使用了另一个编译单元内的某个non-local static对象,它所用到的这个对象可能尚未被初始化,因为C++对“定义于不同编译单元内的non-local static对象”的初始化次序么有明确定义

e.g

class FileSystem {
public:
        ...
        std::size_t numDisks() const;
        ...
};
extern FileSystem tfs;
/*改为:
FileSystem& tfs()
{
    static FileSystem fs;
    return fs;
}*/

class Directory {
public:
	Directory(int params);
        ......
};

Directory::Directory(int params)
{
        ...
	std::size_t disks = tfs().numDisks();    //使用tfs对象.....红色括号为改进版
        ...
}
/*改为:
Directory& temDir()

{

    static Directory td;

    return td;

}*/

Directory tempDir(int params);



关于extern,见:

https://blog.csdn.net/csdnwei/article/details/51836182


说明:

上述代码中,temDir的构造函数可能会用到尚未初始化的tfs,但是temDir和tfs是定义于不同编译单元内的non-local static,初始化顺序无明确定义,会造成错误。

为了解决这个问题,做出以下改变:

基础:C++保证,函数内的local static对象会在“该函数被调用期间”“首次遇上该对象的定义式”时被初始化。

猜你喜欢

转载自blog.csdn.net/sumx2015/article/details/80087358