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

    一.标记清除 标记清除的主要思想是先建立各个对象的关联,然后从根节点出发,使用广度优先搜索依次标记所有对象,那些不能被标记的对象就应该作为垃圾回收. 这种方式的主要缺点就是如果某些对象被清理后,内存是 ...

  2. vue测试安装和配置

    npm install --save-dev @vue/test-utils mocha mocha-webpack npm install --save-dev jsdom jsdom-global ...

  3. EF4.4增删改查实例

    第一.先创建一个名为Store数据库,将下面脚本代码执行创建表: USE [Store] GO /****** Object: Table [dbo].[Category] Script Date: ...

  4. OSI及TCP/IP的概念和区别

    什么是TCP/IP协议 TCP/IP协议(Transfer Controln Protocol/Internet Protocol)叫做传输控制/网际协议,又叫网络通讯协议,这个协议是Internet ...

  5. R语言函数

    函数是一个组织在一起的一组以执行特定任务的语句.R语言有大量的内置函数,用户也可以创建自己的函数. 在R语言中的函数是一个对象,所以R语言解释器为能够通过控制到该函数,带有参数可能是函数必要完成的操作 ...

  6. Elastic Kibana - Install as windows service

    #1 通过windows sc 服务命令安装 sc create "Kibana661" binPath= "{path}\kibana.bat" depend ...

  7. 屏幕置顶(WindowManager服务)

    https://www.cnblogs.com/mythou/p/3244208.html

  8. shell通过ping检测整个网段IP的网络状态脚本

    要实现Ping一个网段的所有IP,并检测网络连接状态是否正常,很多方法都可以实现,下面简单介绍两种,如下:脚本1#!/bin/sh# Ping网段所有IP# 2012/02/05ip=1 #通过修改初 ...

  9. C# 多维数组

    int[, ,] shuzu = new int[4, 3, 2]; //有四个二维数组,每个二维数组里面有3个1维数组,每个1维数组里面有2个元素

  10. git merge后,后悔了如何回退

    今天将feature分支的代码merge到develop分支后我后悔了,因为feature分支的功能还没有全部开发完成,我在feature分支上commit是可以的,但是这之后我又把它merge到了d ...