• 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 };
  • 相关阅读:
    总结:多校1
    简易数论练习
    2017 多校1
    简易数论函数变换学习
    petrozavodsk1
    Permutacja
    图片上传阿里云oss 数据存入redis List
    tp5实现月统计数据
    es6 新特性
    es6 新特性总结
  • 原文地址:https://www.cnblogs.com/wangjzh/p/4064034.html
Copyright © 2020-2023  润新知