查看上面两段代码:
// (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 先调用默认结构,再调用赋值函数。
所有初始化列表要快一点!