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

Make sure that objects are initialized before they're used.      昨天就已经把第四条款看完了,初始化这篇内容非常非常丰富,讲解了很多,...

effective C++读书笔记 条款四 确定对象被使用前已经被初始化

在C part of C++中,声明一个变量,不一定会被初始化,而一旦进入non-C part of C++,规则有些变化。这就很好的解释了为什么array(来自C part of C++)不被初始化...

《Effective C++》学习笔记条款04 确定对象被使用前被初始化

确定对象被使用前已先被初始化

Effective C++读书笔记版-条款03、04

Effective C++读书笔记版-条款03、04

Effective C++读书笔记之确定对象被使用前已被初始化

为内置型对象进行手工初始化,因为c++不保证初始化它们。构造函数最好使用成员初值列(member initialization list ),而不要在构造函数本体内使用赋值操作(assignment ...

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

得到的

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

C++的对象在声明的时候是无初值的,为了避免在对象初始化之前过早的使用它们,你需要做三件事情:         第一,手工初始化内置类型的变量。         第二,使用成员初始化列表来初始化...

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

条款02:尽量以 const,enum,inline 替换 #define                                 ...

Effective C++ Item 04-确定对象被使用前以先被初始化

Item 04-确定对象被使用前以先被初始化(Make sure that object are initialized before they're used) 对象初始化,C++不一定保...

effective c++条款4(确定对象被使用前先被初始化)

确保声明的变量都要先初始化,若不初始化,会产生异常值 初始化的方式有手动初始化或者用input stream初始化 除了内置类型之外,我们写的构造函数也要确保将对象的每个成员初始化初始化和赋值...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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