【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化

原创 2015年07月06日 21:50:40

永远在使用对象之前先将它初始化。对于无任何成员的内置类型,你必须手工完成此事。

至于内置类型以外的任何其他东西,初始化责任落在构造函数身上。规则很简单:确保每一个构造函数都将对象的每一个成员初始化。

构造函数成员初始化列表:
这里有一个规则:总是在初始化列表中列出所有成员变量,即使有的成员变量是内置类型(内置类型的初始化和赋值成本相同)。

成员初始化顺序
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:确定对象被使用前已先被初始化

读取未初始化的值会导致不明确的行为。 在C语言中,全局变量和static变量一般会有初始化值,而对于局部变量没有定义初始化值。在C++中,有了class后,情况就更加复杂了。对于何时有初始化值,何时没...
  • u014558668
  • u014558668
  • 2017年05月01日 12:10
  • 76

《Effective C++读书笔记》--条款04:确定对象被使用前已先被初始化

对于C++来说,定义一个值未初始化,其值是一个不确定的数,而当我们使用未初始化的值会导致UB,在不同的平台上表现不一样,总之会给程序带来不可预知的行为,我们要尽力避免。所以对于内置类型来说,我们要尽量...
  • wingWC
  • wingWC
  • 2017年08月26日 10:16
  • 107

条款04:确定对象被使用前已先被初始化

结论1:为内置型对象进行手工初始化,因为C++不保证初始化它wx
  • u013540854
  • u013540854
  • 2014年05月30日 01:14
  • 461

Effective c++ 学习笔记——条款04:确定对象被使用前已先被初始化

Make sure that objects are initialized before they're used.      昨天就已经把第四条款看完了,初始化这篇内容非常非常丰富,讲解了很多,...
  • wallwind
  • wallwind
  • 2011年09月06日 00:04
  • 4387

[Effective C++]条款04 确定对象被使用前已先被初始化

为内置对象
  • Roger__King
  • Roger__King
  • 2014年09月14日 20:04
  • 325

Effective C++:条款04:确定对象被使用前已先被初始化

(一) 读取未初始化的值会导致不明确的行为;array不保证其内容被初始化,但是vector却有此保证; 最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化...
  • u010470972
  • u010470972
  • 2014年06月05日 19:27
  • 419

【Effective C++读书笔记】篇二(条款02~条款04)

条款02:尽量以 const,enum,inline 替换 #define                                                           #...
  • woxiaohahaa
  • woxiaohahaa
  • 2016年05月06日 22:05
  • 936

条款4:确定对象使用前已先被初始化

对于内置类型,必须手工完成这件事。 对于其他类型,则依赖于这个类型的构造函数。 首先,最好使用初始化列表而不是在函数体内部进行赋值。原因有两个 1.有些对象只能初始化,不能赋值:举一个简单的例子...
  • thefutureisour
  • thefutureisour
  • 2012年09月05日 22:04
  • 1449

Effective C++条款04解读:确定对象被使用之前已先被初始化

实际上, 在很多公司的编程规范(比如google, facebook等)中, 都要求: 变量/对象都必须初始化。 其实, 初始化就是为了避免让程序产生不确定的未定义行为, 避免让程序在不同平台下出现飘...
  • stpeace
  • stpeace
  • 2015年06月14日 10:46
  • 2061

Effective C++ 条款4——确定对象被使用前已先被初始化

得到的
  • a327939162
  • a327939162
  • 2013年11月18日 10:17
  • 618
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Effective C++ 读书笔记】条款04:确定对象使用前已先被初始化
举报原因:
原因补充:

(最多只允许输入30个字)