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

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

当我们声明 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 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可以解决这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值