• 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次拷贝赋值运算符。

  • 相关阅读:
    第二十七讲.动态设置相关参数(replication为2和blocksize为10字节)
    在不同版本的linx编译erLang时出现./configure使用--prefix指定路径后,总在指定的另前多了/usr/local路径
    为什么选择VR全景进行企业宣传,如何将VR全景运用在企业展示
    MySQL 主从复制与读写分离
    怎么分辨CN2 GIA,CN2 GT,CTG,163直连,国际线路?
    android源码添加adb host支持
    软件测试工具
    Redisson 3.17.4 发布
    CSS第一节
    数据结构之顺序表习题讲解
  • 原文地址:https://blog.csdn.net/mars21/article/details/133926086