Effective C++学习笔记 条款04:确定对象被使用前已先被初始化

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

二、对象初始化数据成员是在进入构造函数用户编写代码前完成,要想对数据成员指定初始化值,那就必须使用初始化列表。

 1 class A
 2 {
 3 public:
 4     A(const string &str)
 5     {
 6         m_str = str;     //m_str 的初始化是在进入构造函数中用户自定义编写代码前完成的,所以这里的m_str = str,执行的不是初始化,而是赋值
 7     }
 8 private:
 9     string m_str;
10 };

  在数据成员的默认初始化,然后再在构造函数中进行赋值,这样效率较低。下面就是用户直接给数据成员指定初始化值的例子:

1 class A
2 {
3 public:
4     A(const string &str): m_str(str)  //这里调用的是string的构造函数,直接指定初始化值
5     {
6     }
7 private:
8     string m_str;
9 };

  这时的效率比之前的方法要高。因为前者是初始化再赋值,后者直接用指定的值初始化要初始化的对象了。

三、初始化列表中,对于数据成员的初始化顺序,是按照数据成员的在class中声明的顺序,而不是按照在初始化列表中出现的先后顺序。

1 class B
2 {
3 public:
4     B(const string &str1, const string &str2): m_b(str1), m_a(str2) {}   
5     //这里的初始化顺序是先m_a, 后m_b,因为m_a声明在先
6 private:
7     string m_a;
8     string m_b;
9 };

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

  static对象,指寿命从被构造出来直到程序结束为止,因此排除stack和heap-based对象。其中包括global对象,定义于namespace作用域内的对象,在class内,在函数内以及在file作用域内被声明为static的对象。(注:static对象不只是声明为static的对象)。函数内定义的static对象称为local static对象,其他的static对象就称为non-local static对象

  第一个文件:

1 class FileSystem
2 {
3 public:
4 5     size_t numDisks() cosnt;
6 };
7 extern FileSystem tfs;

  第二个文件中:

 1 class Directory
 2 {
 3 public:
 4     Directory(params)
 5     {
 6  7         size_t disks = tfs.numDisks();  //
 8         ...
 9     }
10 };

  当你定义Directory tempDir(params);

  这时由于C++对于定义于不同编译单元的non-local static对象”的初始化次序无明确定义。所以可能在定义 tempDir时,tfs还没有初始化,那么程序就会出现问题

五、对于上述的问题,为免除“跨编译单元之初始化次序”问题,可以使用local static对象替换non-loacl static对象。

 1 class FileSystem {...};
 2 FileSystem& tfs()
 3 {
 4     static FileSystem fs;
 5     return fs;
 6 }
 7 class Directory
 8 {
 9     Directory(params)
10     {
11 12         size_t disk = tfs().numDisks();    //这样就保证每次使用的时候fs一定初始化了
13         ...
14     }
15 };
原文地址:https://www.cnblogs.com/wangjzh/p/4064034.html