为什么使用初始化列表会快一些?

2021-02-27 02:15:17 +08:00
 yiouejv

查看下面两段代码:

// (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()
  1. classA a; 调用默认构造函数构造 a 对象
  2. classB(classA a) : mA(a) {}, classB 类的构造函数里的 classA a形参拷贝 1 声明的对象
  3. classB(classA a) : mA(a) {}, 初始化列表拷贝 2 里的形参 a 的对象
  4. 2 里的形参 a 析构
  5. 1 里的 a 析构
  6. 对象 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()
  1. classA a; 调用默认构造函数构造 a 对象
  2. classB(classA a) : mA(a) {}, classB 类的构造函数里的 classA a形参拷贝 1 声明的对象
  3. 初始化列表进行初始化,调用默认构造函数
  4. operator=, 函数体内赋值操作,把 2 里的 a 赋值给 mA
  5. 2 里的形参 a 析构
  6. 1 里的 a 析构
  7. 对象 b 里的 mA 析构

代码 2 相对于代码 1,少了一次默认的构造函数。 代码 1 直接调用拷贝构造,代码 2 先调用默认构造,再调用赋值函数。

所有初始化列表要快一点!

1730 次点击
所在节点    C++
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/756657

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX