危害:读取未初始化的值会导致不明确甚至是半随机化的行为。
最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化。
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. 《Algorithms算法》笔记:元素排序(4)——凸包问题

    <Algorithms算法>笔记:元素排序(4)——凸包问题 Algorithms算法笔记元素排序4凸包问题 凸包问题 凸包问题的应用 凸包的几何性质 Graham 扫描算法 代码 凸包问 ...

  2. 使用Java Servlet进行简单登录

    效果图 登录页面代码:login.html <%@ page language="java" contentType="text/html; charset=UTF ...

  3. JavaScript设计模式-5.接口

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. Maven项目版本继承 – 我必须指定父版本?

    问题描述 我有两个项目:父项目:A,子项目:B 在A /pom.xml中: <groupId>com.dummy.bla</groupId> <artifactId> ...

  5. C#的托管和非托管的简单理解

    应该说“托管”一词是和.net概念一起出生的, 我们都知道以前的开发工具无论是Delphi.VB编译出的dll或exe文件都是二进制文件, 可以被操作系统直接识别.而微软为了和JAVA火拼,实现跨平台 ...

  6. linux运维人员成长

    原文地址:https://blog.csdn.net/kwame211/article/details/78059331 初级篇 linux运维人员常用工具拓扑详见: 1rsync工具 很多地方经常会 ...

  7. MUI框架 picker日期选择器实例

    MUI官方文档点我 (一)准备工作,下载相关的js.cs文件,地址 (二)新建普通html页面 1)引入相关js.cs文件 2) 一个input,记录下id: <form> <lab ...

  8. NET 知识体系结构

    以下是我根据自身的情况来总结的ASP.NET 知识体系 ASP.NET 知识体系 1.语言C#——C#-知识梳理 2.ASP.NET 3.WinForm 4.ASP.NET MVC 5.EF

  9. SqlServer常用语句

    首先,写这个的原因是我其实sql语句不太行,总觉得自己写得很乱,好像也没有系统学习过,借此复习和与大家探讨 No.1 关于查询时间区间是否重叠的sql语句 问题是这样:插入之前,想查询同User是否其 ...

  10. nodejs搭建简易的rpc服务

    这里主要使用的是jayson包,使用jayson实现rpc server端十分简单,如下: var jayson = require('jayson') // create a server var ...