为什么使用初始化列表会快一些?
查看下面两段代码:
// (1) class classA {...}; class classB { public: classB(classA a) {mA = a;} private: classA mA; };
// (2) class classA {...}; class classB { public: classB(classA a): mA(a) {} private: classA mA; };
为什么2的效率要高?
初始化列表的效率要高。
首先把数据成员按类型分类
- 内置数据类型,复合类型(指针,引用)
- 用户定义类型(类类型)
分情况说明:
- 对于类型1,在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的
- 对于类型2,结果上相同,但是性能上存在很大的差别
初始化列表,顾名思义,是对成员数据进行初始化,而不是赋值,赋值操作在构造函数体内!
好比:
classA a; classA b = a;
和
classA a; classA b; b = a;
的区别。
上述的代码1不够清晰,我们写成下面这样:
#include <iostream> using namespace std; class classA { public: classA() { cout << "classA()" << endl; } classA(const classA& a) { cout << "copy classA()" << endl; } ~classA() { cout << "~classA()" << endl; } classA& operator=(const classA& a) { cout << "operator=" << endl; return *this; } }; class classB { public: classB(classA a) : mA(a) {} private: classA mA; }; int main() { classA a; classB b(a); }
// 打印如下: //1 classA() //2 copy classA() //3 copy classA() //4 ~classA() //5 ~classA() //6 ~classA()
classA a;
调用默认构造函数构造a对象classB(classA a) : mA(a) {}
, classB类的构造函数里的classA a
形参拷贝1声明的对象classB(classA a) : mA(a) {}
, 初始化列表拷贝2里的形参a的对象- 2里的形参a析构
- 1里的a析构
- 对象b里的mA析构
4,5,6的析构顺序没有验证。
对于代码2
#include <iostream> using namespace std; class classA { public: classA() { cout << "classA()" << endl; } classA(const classA& a) { cout << "copy classA()" << endl; } ~classA() { cout << "~classA()" << endl; } classA& operator=(const classA& a) { cout << "operator=" << endl; return *this; } }; class classB { public: classB(classA a) { mA = a; } private: classA mA; }; int main() { classA a; classB b(a); }
// 打印如下: //1 classA() //2 copy classA() //3 classA() //4 operator= //5 ~classA() //6 ~classA() //7 ~classA()
classA a;
调用默认构造函数构造a对象classB(classA a) : mA(a) {}
, classB类的构造函数里的classA a
形参拷贝1声明的对象- 初始化列表进行初始化,调用默认构造函数
operator=
, 函数体内赋值操作,把2里的a赋值给mA- 2里的形参a析构
- 1里的a析构
- 对象b里的mA析构
代码2相对于代码1,少了一次默认的构造函数。 代码1直接调用拷贝构造,代码2先调用默认构造,再调用赋值函数。
所有初始化列表要快一点!