危害:读取未初始化的值会导致不明确甚至是半随机化的行为。
最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化。
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. Strut2 ognl取出存放在request,session,application和对象栈的中的值

    1.取出request,session,applicaiton中的值 a.往里面加入request,session,application中加入值 public String testServlet( ...

  2. CentOS/Linux 解决 SSH 连接慢

    现在连接linux服务器一般都是使用SSH远程连接的方式.最近新装了一台服务器,发现telnet时速度很快,ping时一切也正常,但SSH连接的时候却很慢.经过网上资料查询,大致是有以下几种原因: 1 ...

  3. [中英对照]Booting Process in Linux RHEL 7 | Linux RHEL 7启动过程

    Booting Process in Linux RHEL 7 | Linux RHEL 7启动过程 In this post, I will guide you booting process in ...

  4. spingAOP在springMVC中的使用(我用在拦截controller中的方法。主要用于登录控制)

    首先截取了网上的一张配置execution的图片 我在项目中关于aop的配置:如果拦截controller的方法,需要在spring-mvc.xml文件中加入(如果在spring.xml中加入则无法拦 ...

  5. memcached 学习笔记 4

    memcached真实项目中的应用 1 缓存式的Web应用程序架构 有了缓存的支持,我们可以在传统的app层和db层之间加入cache层,每个app服务器都可以绑定一个mc, 每次数据的读取都可以从m ...

  6. 各种数据库maven的pom文件编写与ibernate链接配置

    各种数据库Hibernate链接配置 Derby db driver maven dependency <dependency>         <groupId>org.ap ...

  7. BEA WebLogic平台下J2EE调优攻略--转载

    BEA WebLogic平台下J2EE调优攻略   2008-06-25 作者:周海根 出处:网络   前 言 随着近来J2EE软件广泛地应用于各行各业,系统调优也越来越引起软件开发者和应用服务器提供 ...

  8. ios手势识别代理

    之前做优质派时写了个仿网易新闻导航的第三方,由于当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0 ...

  9. python——高级特性(2)

    迭代 在python中迭代是通过for ....in...完成的,只要是可迭代对象都可以迭代 #!usr/bin/python #-*- coding:UTF-8 -*- #tuple迭代 t=[(1 ...

  10. Docker学习之基本概念

    Docker学习之基本概念 作为一个后端noder,不了解docker有点说不过去,这节开始,学习一些docker层面的东西. 什么是docker Docker最初是dotCloud公司创始人Solo ...