危害:读取未初始化的值会导致不明确甚至是半随机化的行为。
最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化。
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. python-五个面试题

    问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...

  2. ibatis插入正确但查询不出数据的问题

    现在,使用打印的sql在oracle数据库客户端能查询出结果,但执行ibatis查询语句不行,ibatis插入可以. 解决问题的历程: 1. 去掉sql中的where语句,仍然查找不到,确定不是sql ...

  3. 一些Android的博客,没事翻翻

    深入剖析Android系统(推荐) 深入浅出Android系统移植与平台开发系列(推荐) Android系统开篇(小米工程师对系统的整体分析,推荐) Android6.0Framework源码解析系列 ...

  4. guava快速入门(二)

    Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] .缓存 [caching] .原生类型支持 [primitives support] ...

  5. 关于对javaUtils封装和三层架构的笔记

    1.什么是三层架构: 三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer).业务逻辑层(Business ...

  6. hdu 2199 Can you solve this equation? 二分

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  7. Java 时区转换(UTC+8 到 UTC 等等)

    前言:需要做时区转换,知道北京为UTC+8,东京为UTC+9,世界标准时间为UTC,所以下面的代码是只需要知道时区是+8还是+9还是0就可以了,不需要使用"CTT". " ...

  8. Tomcat的下载安装及使用

    macOS Sierra Version 10.13.2 环境下Tomcat的下载与安装以及InterlliJ IDEA 2017.2 环境下配置Tomcat 与创建Web项目 一.Tomcat的下载 ...

  9. Django框架model实现数据库增删查改

    1.创建Django工程 https://www.cnblogs.com/CK85/p/10159159.html 2.在model.py中配置生成表格的类对象. from django.db imp ...

  10. Java中的继承:父类和子类的关系

    一.父类引用指向子类对象时 1.若子类覆盖了某方法,则父类引用调用子类重新定义的新方法 2.若子类未覆盖某方法,则父类引用调用父类本身的旧方法 3.若子类覆盖了某属性,但父类引用仍调用父类本身的旧属性 ...