zoukankan      html  css  js  c++  java
  • 条款04:确定对象在使用前已经被初始化

    读取未初始化的值会造成不明确的行为。

    • 对于内置类型来说,我们必须手工完成初始化。
    • 对于类类型来说,这个责任由构造函数来承担,所以构造函数要确保所有的数据成员有被初始化。

    例如下面这个构造函数:

    ABEntity::ABEntity(const std::string& name, const std::string& address,

                                         const std::list<PhoneNumber>& phones)

                       {

                                theName = name;

                                theAddress = address;

                                thePhones = phones;                         

                       }

    注意这是我们新手比较容易犯的一个错误,我们以为上面这个构造函数对成员进行了初始化。其实,这不是初始化,这是赋值。虽然ABEntity可以得到你期望的值。

             C++规定初始化的动作发生在进行构造函数本体之前。

    比较好的一个做法是使用成员初始化列表:

    ABEntity::ABEntity(const std::string& name, const std::string& address,

                                                                                         const std::list<PhoneNumber>& phones)

                                                                                         : theName(name),

    theAddress(address),

                                                                                          thePhones(phones){}

    基于赋值的那个版本,首先调用default构造函数为theName,theAddress,thePhones设初始值,然后,在函数体内再进行赋值。所以说default构造函数所做的一切都没有用。

    而基于成员初始值列表的做法是直接调用theName,theAddress,thePhones的copy构造函数。

    对于大多数而言,第二种方式每个成员只调用一次copy构造函数的方式高效的多。而对于内置类型来说,采用成员初始化列表与在构造函数内进行赋值的代价是一样的,但为了统一,也把内置类型的初始化放在成员初始化列表。

    问为什么内置类型的初始化,两种方式一样?

    初始化是两个过程:内存分配,填写值。

    对于第一种方式,在函数体内进行赋值,是先内存分配,再赋值。对于在成员初始化列表中初始化也是先分配内存,再赋值。两种作法的步骤都一样。

    而类成员,第一种方式会导致调用默认构造函数无用功。

  • 相关阅读:
    省市区三级联动
    VUE项目PC端实现自适应rem
    (课堂笔记)第十三章GLSB涉及负载均衡算法
    LTM理解及配置笔记记录
    实验演示---GSLB部分(DC1)
    F5实验模拟拓扑
    (课堂笔记)第十三章:DNS 全局站点
    AbstractList类_Iterator内部类
    Oracle 时间格式化异常:无效数字
    Maven库镜像
  • 原文地址:https://www.cnblogs.com/loveyakamoz/p/2772371.html
Copyright © 2011-2022 走看看