【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上的 ...
随机推荐
- oracle用分隔符分割字段,并转为多行
作用:当判断是否满足条件,而条件字段又是用","分割的时候. 如果数据库中一个字段插入数据,并且以","分割.有点像行转列 4804510101,4946645 ...
- Hibernate课程 初探一对多映射3-2 单向多对一的配置
1 多方实体类中加入,一方类和getset方法 //多方定义一个一方的引用 private Grade grade; public Grade getGrade() { return grade; } ...
- Vue Element-ui 框架:路由设置 限制文件类型 表单验证 回车提交 注意事项 监听事件
1.验证上传文件的类型: (1)验证图片类型 <template> <el-upload class="avatar-uploader" action=" ...
- Js仿腾讯微博效果
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 【起航计划 028】2015 起航计划 Android APIDemo的魔鬼步伐 27 App->Preferences->Launching preferences 其他activity获取Preference中的值
前给例子介绍了如何使用PreferenceActivity 来显示修改应用偏好,用户对Preferences的修改自动存储在应用对应的Shared Preferences中. 本例介绍了如何从一个Ac ...
- APP常用检测
检测设备.微信平台和app是否安装 // 检测是否安装了APP var isappinstalled = (function () { ); }()), // 检测ios设备 isIOS = (fun ...
- Azure SQL的DTU和eDTU到底是个什么鬼
可以从上表上对应于本地数据库的性能采集的指标,可以估算出应该使用什么样级别的AZURE SQL. 当然服务层选择后仍然可以进行更改. 对于自己应用应该用多大规模的DTU,可以进行详细的评估,可以使用下 ...
- 使用QJM实现HDFS的HA配置
使用QJM实现HDFS的HA配置 1.背景 hadoop 2.0.0之前,namenode存在单点故障问题(SPOF,single point of failure),如果主机或进程不可用时,整个集群 ...
- 基于FPGA的VGA显示设计(二)
上一篇:基于FPGA的VGA显示设计(一) 参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码 的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...
- Selenium入门系列3 单个元素的定位方法
UI自动化首先要识别对象,再操作对象,最后判定实际结果与预期结果是否一致. 这一节学习的是识别单个对象,webdriver提供了8种方式. <a id="idofa" cla ...