• C++对象模型(17)-- 构造函数语义学:成员初始化列表


    1、必须用初始化列表的场景

    (1)成员变量是引用类型,必须在初始化列表中初始化。

    (2)成员变量是const类型,必须在初始化列表中初始化。

    (3)如果类继承自一个父类,并且父类中有带初始化列表的构造函数,必须在初始化列表中初始化父类。

    1. class Base {
    2. public:
    3. Base(int i) { }
    4. };
    5. class Derive:public Base {
    6. public:
    7. Derive(int i) : Base(i){}
    8. };

    (4)成员变量是类类型,且这个类的构造函数带参数。

    1. class Item {
    2. public:
    3. Item(int i) { }
    4. };
    5. class MyDemo {
    6. public:
    7. MyDemo(int i) : item(i){}
    8. Item item;
    9. };

    2、初始化列表的执行时机

    初始化列表是在构造函数之前执行的。

    我们可以用下面的代码来验证:

    1. class Item {
    2. public:
    3. Item() { }
    4. Item(const Item& _item) {
    5. cout << " Item拷贝构造函数" << endl;
    6. }
    7. };
    8. class Derive {
    9. public:
    10. Derive() { cout << " Derive默认构造函数" << endl; }
    11. Derive(Item& _item) : item(_item) { cout << " Derive带初始化列表构造函数" << endl; }
    12. Item item;
    13. };
    14. int main()
    15. {
    16. Item _item;
    17. Derive derive(_item);
    18. return 0;
    19. }

    执行结果如下:

    从运行结果看,初始化列表是在构造函数之前运行的。

    3、按成员变量的声明顺序初始化,而不是根据初始化列表中的前后顺序。

    1. class X{
    2. public:
    3. X(int val) : j(val), i(j){}
    4. private:
    5. int i;
    6. int j;
    7. }

    其实在这个时候,构造函数是这么初始化的:

    1. X::X(int val){
    2. i = j;
    3. j = val;
    4. }

    所以最终的结果是j = val, 但i的值未知。

    4、初始化列表的优点

    一般地,放在构造函数初始化列表中进行初始化,比放在构造函数中初始化效率更高。

    我们可以通过代码来验证这个结论:

    (1)构造函数中初始化

    1. class Item {
    2. public:
    3. Item() {
    4. cout << " Item默认构造函数" << endl;
    5. }
    6. Item(int i) {
    7. cout << " Item(int)构造函数" << endl;
    8. }
    9. Item(const Item& _item) {
    10. cout << " Item拷贝构造函数" << endl;
    11. }
    12. Item& operator = (const Item& _item) {
    13. cout << " Item拷贝赋值运算符" << endl;
    14. return *this;
    15. }
    16. };
    17. class Derive {
    18. public:
    19. Derive(int i){
    20. item = Item(i);
    21. cout << " Derive带初始化列表构造函数" << endl;
    22. }
    23. Item item;
    24. };
    25. int main()
    26. {
    27. Derive derive(2);
    28. return 0;
    29. }

    运行结果:

    (2)初始化列表中初始化

    Derive(int i) : item(i){}

    运行结果:

    可以看到,初始化列表初始化时少了1次默认构造函数和1次拷贝赋值运算符。

  • 相关阅读:
    MySQL八股文背诵版(续)
    luffy配置相关
    Python---练习:求世界杯小组赛的总成绩(涉及:布尔类型转换为整型)
    英语——分享篇——每日200词——2401-2600
    c#快速入门~在java基础上,知道C#和JAVA 的不同即可
    SpringMVC(下)
    跨境电商运营的新趋势:自养号测评补单技术解析
    【微信小程序】scroll-view的基本使用
    理解RNN循环神经网络
    Kotlin协程的简单用法(GlobalScope、lifecycleScope、viewModelScope)
  • 原文地址:https://blog.csdn.net/mars21/article/details/133926086