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

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

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

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

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

#include 
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 constructor
A'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可以解决这个问题。

你可能感兴趣的:(effective C++ 读后感(四) 确定对象被使用之前已被初始化)