C++ Primer中在讲构造函数初始化列表的时候有这么一段话:
无论是在构造函数初始化列表中初始化成员,还是在构造函数体中对它们赋值,最终结果是相同的。不同之处在于,使用构造函数初始化列表的版本表示初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值。
首先把数据成员按类型分类
1、内置数据类型,复合类型(指针,引用)
2、用户定义类型(类类型
对于类型1,在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
对于类型2,结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体是已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,这是调用一次构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)
虽然大多数情况下,这两种初始化方式并没有太大差别,但其实更推荐使用成员初始化列表,尤其是有一些情况下必要的,另一个原因是出于效率。
第一个原因——必要性。设想你有一个类成员,它本身是一个类或者结构,而且只有一个带一个参数的构造函数。
class CMember {
public:
CMember(int x) { ... }
};
因为Cmember有一个显式声明的构造函数,编译器不产生一个缺省构造函数(不带参数)
无论是在构造函数初始化列表中初始化成员,还是在构造函数体中对它们赋值,最终结果是相同的。不同之处在于,使用构造函数初始化列表的版本表示初始化数据成员,没有定义初始化列表的构造函数版本在构造函数体中对数据成员赋值。
首先把数据成员按类型分类
1、内置数据类型,复合类型(指针,引用)
2、用户定义类型(类类型
对于类型1,在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
对于类型2,结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体是已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,这是调用一次构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)
虽然大多数情况下,这两种初始化方式并没有太大差别,但其实更推荐使用成员初始化列表,尤其是有一些情况下必要的,另一个原因是出于效率。
第一个原因——必要性。设想你有一个类成员,它本身是一个类或者结构,而且只有一个带一个参数的构造函数。
class CMember {
public:
CMember(int x) { ... }
};
因为Cmember有一个显式声明的构造函数,编译器不产生一个缺省构造函数(不带参数)