乐趣区

关于c++:为什么使用初始化列表会快一些

查看上面两段代码:

// (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 先调用默认结构,再调用赋值函数。

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

退出移动版