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

程序员杨小哥

查看下面两段代码:

// (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. 用户定义类型(类类型)

分情况说明:

  • 对于类型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先调用默认构造,再调用赋值函数。

所有初始化列表要快一点!
在这里插入图片描述

阅读 1.7k

C_CPP
C/C++学习,和我一起成长哦!
18 声望
2 粉丝
0 条评论
18 声望
2 粉丝
文章目录
宣传栏