V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yiouejv
V2EX  ›  C++

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

  •  
  •   yiouejv · 2021-02-27 02:15:17 +08:00 · 1891 次点击
    这是一个创建于 1397 天前的主题,其中的信息可能已经有所发展或是发生改变。

    查看下面两段代码:

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

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

    在这里插入图片描述

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4406 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 01:03 · PVG 09:03 · LAX 17:03 · JFK 20:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.