性能问题之外,有些时场合初始化列表是不可或缺的,以下几种情况时必须使用初始化列表
- 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
-
Error1(constchar* constmsg) :data(msg)
{
//data = msg;
}
- 引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
- 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。
-
classError2
{
constchar* const data;
public:
Error2(constchar* constmsg = 0) :data(msg){}//Error2()
};
classError1
{
constchar* const data;
Error2 e2;
public:
Error1(constchar* constmsg=0) :data(msg)
{
// e2 = e2Out;
//data = msg;
}
//Error1(const char* const msg = 0) :data(msg){}
Error1(constchar* constmsg, Error2 & e2Out) :data(msg), e2(e2Out)
{
//e2 = e2Out;
//data = msg;
}
};
if not, there will be a waring, - 但是对于类类型来说,最好使用初始化列表,为什么呢?由上面的测试可知,使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。同样看上面的例子,我们使用初始化列表来实现Test2的构造函数
struct Test2 {Test1 test1 ;Test2(Test1 &t1):test1(t1){} }
-
-
使用同样的调用代码,输出结果如下。
第一行输出对应 调用代码的第一行。第二行输出对应Test2的初始化列表,直接调用拷贝构造函数初始化test1,省去了调用默认构造函数的过程。所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表。
-