【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化
永远在使用对象之前先将它初始化。对于无任何成员的内置类型,你必须手工完成此事。
至于内置类型以外的任何其他东西,初始化责任落在构造函数身上。规则很简单:确保每一个构造函数都将对象的每一个成员初始化。
构造函数成员初始化列表:
这里有一个规则:总是在初始化列表中列出所有成员变量,即使有的成员变量是内置类型(内置类型的初始化和赋值成本相同)。
成员初始化顺序
base classes 早于 derived classes 被初始化,class 的成员变量总是以其声明次序被初始化
一个编译单元内定义的”non-local static对象“的初始化次序
static 对象,其寿命从被构造出来知道程序结束为止。
static 对象包括 global 对象、定义于 namespace 作用域内的对象、在class内、在函数内、以及在file 作用域内被声明为 static 的对象。
函数内的 static 对象称为 local static 对象,其他的称为 non-local static 对象。
程序结束时 static对象会被自动销毁。
编译单元是指产出单一目标文件的那些源码。基本上是单一源文件加上其所含入的头文件。
如果某个编译单元内的 non-local static 对象的初始化动作使用了另一个编译单元内的某个 non-local static 对象,他所用到的这个对象可能尚未被初始化。
举个实例加以理解:
//file1: Filesystem.cpp
//
class FileSystem{
public:
std:size_t numDisks() const
};
extern FileSystem tfs;
//file2:Directory.cpp
//
class Directory{
public:
Directory(params);
};
Directory::Directory(params)
{
std::size_t disks = tfs.numDisks(); //使用 tfs 对象
}
int main()
{
Directory tempDir( params );
}
//这个时候初始化的重要性显现出来了,tfs必须在tempdir之前被初始化,否则tempDir的构造函数就会用到尚未初始化的tfs。
//但是C++对于不同编译单元内的 non-local static对象的初始化相对次序并无明确定义。
//为了消除这个问题:
//采用 设计模式中的 Singleton 模式的一个常见实现手法:将每个 non-local static 对象搬到自己的专属函数内(该对象在此函数内被声明为static)
//
//这个手法的基础就是:C++ 保证,函数内的 local static对象会在“该函数被调用期间”“首次遇上该对象之定义式”时被初始化,这样就保证你所获得的reference将指向一个历经初始化的对象
//
//将此技术实施于 tfs 和 tempDir 身上:
//file1: Filesystem.cpp
//
class Filesystem { ... }; //同前
FileSystem& tfs()
{
static FileSystem fs;
return fs;
}
//file2:Directory.cpp
class Directory{ ... };
Directory::Directory( params )
{
std::size_t disks = tfs().numDisks();
}
Directory& tempDir()
{
static Directory td;
return td;
}
【请记住:】
- 为内置类型对象进行手工初始化,因为 C++ 不保证初始化它们。
- 构造函数最好使用成员初始化列表,而不要在构造函数本体内使用赋值操作。
- 构造函数初始化列表中的成员变量排列次序应该和他们在 class 中的声明次序相同。
- 为免除 ”跨编译单元值初始化次序“问题,请以 local static 对象替换 non-local static 对象。
【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化的更多相关文章
- effective C++ 读书笔记 条款14 以对象管理资源
如果我们使用一个投资行为的程序库: #include "stdafx.h" #include <iostream> #include <memory> us ...
- Effective C++学习笔记 条款04:确定对象被使用前已先被初始化
一.为内置类型对象进行手工初始化,因为C++不保证初始化它们. 二.对象初始化数据成员是在进入构造函数用户编写代码前完成,要想对数据成员指定初始化值,那就必须使用初始化列表. class A { pu ...
- effective C++ 读书笔记 条款08
条款08 别让异常逃离析构函数: 假设在析构函数其中发生了异常,程序可能会过早结束或者导致不明白行为(异常从析构函数传播出去) 看代码: #include <iostream> usin ...
- effective C++ 读书笔记 条款11
条款11: 在operator= 中处理"自我赋值" 在实现operator=时考虑自我赋值是必要的就像 x=y .我们不知道变量x与y代表的值是否为同一个值(把x和y说成是一个指 ...
- Effective Java2读书笔记-创建和销毁对象(三)
第5条:避免创建不必要的对象 本条主要讲的是一些反面教材,希望大家引以为鉴. ①无意中使用自动装箱导致多创建对象. public class Sum { public static void main ...
- Effective Java2读书笔记-创建和销毁对象(一)
第1条:考虑用静态工厂方法代替构造器 通常情况下,我们创建一个对象采取new的形式,但是还有一种方法也是经常使用到的,它的名称叫做静态工厂方法. 例如,java中基本类型boolean的包装类Bool ...
- 《Effective C++》——条款04:确定对象使用前已先被初始化
读取未初始化的值会导致不明确的行为.在某些平台上,仅仅只是读取未初始化的值,就可能让你的程序终止运行.更可能的情况是读入一些“半随机”bits,污染了正在进行读取动作的那个对象,最终导致不可预知的程序 ...
- Effective Java读书笔记--创建和销毁对象
1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build() ...
- Effective Java2读书笔记-创建和销毁对象(四)
第7条:避免使用终结方法 这一条讲的简直是不知所云.先简单记下来其中说出的几条: ①显式终止方法的典型例子有InputStream.OutputStream和java.sql.Connection上的 ...
随机推荐
- 修改model,映射到表中
1. 当使用EF code first创建数据表后,数据库中会自动创建一个名为:dbo.__MigrationHistory的系统数据表, 如果尚未启用数据库迁移功能,那么每次在应用程序运行时,都会对 ...
- Spring课程 Spring入门篇 3-3 Spring bean装配(上)之aware接口
课程链接: 本节主要介绍了以下内容: 1 aware介绍 2 代码演练 3 课程总结 1 aware介绍 1.1 为什么要使用aware? 在java类中,可以方便的获取xml配置文件中的bean的各 ...
- OMD开源监控软件
参考 Best Monitoring Solution - OMD (Nagios + Check_MK) 官网 mathias-kettner.com OMD labs.consol.de Conf ...
- linux单机限速工具
wondershaper是国外人开发的一款在Linux内核下基于TC工具的对整块网卡的限度工具. http://lartc.org/wondershaper/ 安装wondershaper: [roo ...
- 使用sqlyog连接ubuntu mysql server错误解决方案
现在很多服务都部署在linux环境中,但是在开发阶段,使用windows远程连接工具,直观,这对开发人员更友好. 下面是我在ubuntu16.04使用mysql- server时,遇到了一下的问题,以 ...
- API:相关词语笔记
1.SDK 软件开发套件,接口服务器把接口开发之后,把怎么使用的示范代码弄出来给API客户端的开发者参考. 2.头部信息 对头部信息的特殊符号有要求,例如: 持续更新中....
- ring0 暴力枚举进程
原理:遍历进程ID,然后openprocess,能打开的都枚举出来 ring0 : #include "EnumProcessByForce.h" extern char* PsG ...
- 双击易语言没有反应,按住shift再双击可解决
参考资料:http://tieba.baidu.com/p/2987732743 的7楼.
- April 5 2017 Week 14 Wednesday
Today is a perfect day to start living your dream. 实现梦想,莫如当下. Miracles may happen every day. If you ...
- 如何处理用代码创建SD Sales order时遇到的错误消息KI 180
错误消息KI 180:You must enter a company code for transaction Create sales document 代码: REPORT zcreate_so ...