危害:读取未初始化的值会导致不明确甚至是半随机化的行为。
最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化。
1 注意区分赋值和初始化:
从初始化的角度而言,这不是一个最佳的处理办法。虽然这会让对象的指最终为你期望的值,但是实际上,对象的成员变量的初始化动作发生在进入构造函数本体之前。而在构造函数本体之内,不是被初始化,而是被赋值。
2 较佳的写法:使用成员变量初始化列表
结果和上一个的最终结果相同,但是效率较高。
规定:总是在初值列表中列出所有成员变量,以免遗漏需要初始化的成员变量。即,总使用成员初始化列表。
一个特例再次印证了上句的价值:如果成员变量是const或reference,它们就一定需要初值,不能被赋值。
3 成员初始化次序:
一般地:

base classes更早于其derived classes被初始化,而class的成员变量总是以其声明次序被初始化。

特别低:

不同编译单元内定义的non-local static对象的初始化次序

解析:
1 non-local static:  包括:
  • global对象
  • 定义于namespace作用域内的对象
  • 在classes内、在file作用域内被声明为static的对象
  local static对象,指在函数内被声明为static的对象。
2 编译单元:产出单一目标文件的那些源码。基本上可以认为是一个源码文件加上它所包含的头文件。
问题:

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

原因:

决定它们的初始化次序相当困难,甚至是无解的。

解决:

reference-returning函数(示例如下)

原理:

C++保证,函数内的local static对象会在该函数被调用期间首次遇上该对象的定义式时被初始化。
所以以函数调用替换直接的对象访问,就保证获得一个已经初始化的对象的引用。
Demo:
可能会发生初始化次序问题的版本:
a.cpp 

b.cpp
 
 
改进后的版本:
          
 
 

小结:
  • 为内置类型对象进行手工初始化,以为C++不保证初始化它们;
  • 构造函数最好使用成员变量初始化列表,其排列次序应该和它们在class中的声明次序相同;
  • 为免除“跨编译单元之初始化次序”问题,请以local static对象(referance returning函数)替换non-local static对象。
参考资料:
《Effective C++ 3rd》

Effective C++(4) 确定对象被使用前已先被初始化的更多相关文章

  1. [Effective C++ --009]确定对象被使用前已先被初始化

    在确保对象在使用前已先被初始化这一条款的编码实践中,作者为我们总结了三条经验,它们分别是: ------------------------------------------------------ ...

  2. Effective C++ 之 Item 4:确定对象被使用前已先被初始化

    Effective C++ Chapter 1. 让自己习惯C++ (Accustoming Yourself to C++) Item 4. 确定对象被使用前已先被初始化 (Make sure th ...

  3. EC读书笔记系列之2:条款4 确定对象被使用前已先被初始化

    条款4:确定对象被使用前已先被初始化 记住: ★为内置对象进行手工初始化,因为C++不保证初始他们 ★构造函数最好使用初始化列表,而不要在构造函数本体内使用赋值操作.初始化列表列出的成员变量,其排列次 ...

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

    一.为内置类型对象进行手工初始化,因为C++不保证初始化它们. 二.对象初始化数据成员是在进入构造函数用户编写代码前完成,要想对数据成员指定初始化值,那就必须使用初始化列表. class A { pu ...

  5. EffectiveC++条款04:确定对象被使用前已先被初始化

    不要混淆赋值和初始化,对于大多数类型而言,比起先调用默认构造函数然后调用赋值操作符,只调用一次拷贝构造函数是高效的 对于内置类型,也需要成员初值列(member initialization list ...

  6. [effictive c++] 条款04 确定对象被使用前已被初始化

    成员初始化 在c和c++ 中,使用为初始化的类型经常会引发不可预料的错误,从而使得我们要花费巨大的时间用于调试查找问题,所以确定对象被使用前已被初始化是个非常好的习惯. 永远在使用之前对对象进行初始化 ...

  7. 读书笔记 effective c++ Item4 确保对象被使用前进行初始化

    Item4 确保对象被使用前进行初始化 C++在对象的初始化上是变化无常的,例如看下面的例子: Int x; 在一些上下文中,x保证会被初始化成0,在其他一些情况下却不能够保证.看下面的例子: Cla ...

  8. 条款4:确定对象被使用前已被初始化(Make sure that objects are initialized before they're used)

    其实 无论学何种语言 ,还是觉得要养成先声明后使用,先初始化再使用. 1.永远在使用对象之前先将其初始化. 内置类型: 必须手工完成. 内置类型以外的:使用构造函数完成.确保每一个构造函数都将对象的一 ...

  9. 【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化

    永远在使用对象之前先将它初始化.对于无任何成员的内置类型,你必须手工完成此事. 至于内置类型以外的任何其他东西,初始化责任落在构造函数身上.规则很简单:确保每一个构造函数都将对象的每一个成员初始化. ...

随机推荐

  1. windows 老掉牙CMD的命令

    再老,也得温习下: net use \\' /user:'administrator' //ipc连接 net use \\127.0.0.1\ipc$ /delete //退出ipc net use ...

  2. jenkins创建构建任务

    构建项目类型 点击 Jenkins 首页 “创建一个新任务” 的链接, 输入任务名称 Jenkins 提供了六种类型的任务. 构建一个自由风格的软件项目 这是Jenkins的主要功能.Jenkins ...

  3. TortoiseGit学习系列之TortoiseGit基本操作拉取项目(图文详解)

    前面博客 TortoiseGit学习系列之TortoiseGit基本操作克隆项目(图文详解) TortoiseGit学习系列之TortoiseGit基本操作修改提交项目(图文详解) TortoiseG ...

  4. java几个经典的算法题目----------查询子串和等于已知数字

    给出一个排序好的数组和一个数,求数组中连续元素的和等于所给数的子数组 public class testClockwiseOutput { public static void main(String ...

  5. 深入了解javascript的sort方法

    在javascript中,数组对象有一个有趣的方法 sort,它接收一个类型为函数的参数作为排序的依据.这意味着开发者只需要关注如何比较两个值的大小,而不用管“排序”这件事内部是如何实现的.不过了解一 ...

  6. 批量删除SVN文件

    开发过程中,有时需要将SVN目录中的SVN相关的信息去掉,有两种简单方法可以做到: 一,用SVN的export功能 二,将下面的这段文字写在.reg结尾的文本文件中,然后执行.这样你在每个文件夹右击的 ...

  7. Asp.Net 之Jquery知识点运用

    1.先把要用的body内的代码写好. <div id="ulBox"> <h3>下面的Ulid为"ulList1"</h3> ...

  8. sql sever 执行较大的文件脚本

    1.用管理员身份打开cmd工具 2.执行命令 osql -S  localhost -U sa -P 123456 -i D:/test.sql -S 服务器地址  本地可简写 . -U 用户名 -P ...

  9. Java基础教程(2)--Java开发环境

    一.JVM.JRE和JDK的概念   对于初学者来说,这三个术语出现的频率很高,而且有关这它们的问题在面试题中也会经常出现.因此,理解它们的定义.区别和联系就显得尤为重要.在学习这几个专业术语之前,我 ...

  10. 二、spark SQL交互scala操作示例

    一.安装spark spark SQL是spark的一个功能模块,所以我们事先要安装配置spark,参考: https://www.cnblogs.com/lay2017/p/10006935.htm ...