effective C++ 读后感(四) 确定对象被使用之前已被初始化

来源:互联网 发布:不给转出域名怎么处理 编辑:程序博客网 时间:2024/04/29 10:53

四、确定对象被使用之前已被初始化

当我们声明 int x时,x是否会被初始化为0呢?事实上,这与我们当前用的是C++的哪个部分有关,如果用的是C部分(见effective C++ 读后感(一) 视C++为一个语言联邦),则不保证会初始化,因为C追求的是程序运行速度。而在其他部分,就不这样了。这就能解释为了数组不会被初始化,但vector会。

为了避免使用未初始化的对象而使程序运行结果出错甚至崩溃,但保险的方式就是手工对其进行初始化。比如 int x = 0。对于非内置类型,初始化任务就交给构造函数来完成。一个类的构造函数应该要确保它的所有成员都初始化了。

1.注意区分赋值与初始化

#include <iostream>using namespace std;class A {public:A() {cout << "A's constructor" << endl;}};class B {A a;public:B() {a = A();    //这是赋值,不是初始化}};int main() {B b;return 0;}

在上面的例子中,类B有成员a,我们在B的构造函数中对a进行的是赋值,不是初始化。

运行结果为:

A's constructorA's constructor

在C++中对象的成员变量初化是发生在构造函数之前。上例虽然最终生成了我们想要的对象,但出现了额外的开销。

最好是利用成员初值列来代替赋值,进行初始化。如:

class A {int num;public:A(): num(0) {}A(int n): num(n) {}};

这样效率会高一些。

初始化顺序与声明先后一致,与初值列的顺序无关。


不同编译单元内non-local static 对象的初始化顺序

函数内的static对象称为local static对象,其他static对象为non-local static对象。编译单元是单一源码文件加上其所含头文件。如果有多个源码文件,它们之间如果存在依赖关系,那么被使用的对象可能还没有被初始化,因为这时候对象初始化的先后顺序是不确定的。

通过Singleton可以解决这个问题。

0 0
原创粉丝点击