查看下面两段代码:
// (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 的效率要高?
初始化列表的效率要高。
首先把数据成员按类型分类
分情况说明:
初始化列表,顾名思义,是对成员数据进行初始化,而不是赋值,赋值操作在构造函数体内!
好比:
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 的对象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 相对于代码 1,少了一次默认的构造函数。 代码 1 直接调用拷贝构造,代码 2 先调用默认构造,再调用赋值函数。
所有初始化列表要快一点!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.