zoukankan      html  css  js  c++  java
  • C++中类成员变量在初始化列表中的初始化顺序

    引子:我们知道,C++中类成员变量的初始化顺序与其在类中的声明顺序是有关的。

    先看代码:

     1 class TestClass1
     2 {
     3 public:
     4     TestClass1() {
     5         cout << "TestClass1()" << endl;
     6     }
     7     TestClass1(const TestClass1&) { cout << "TestClass1(const TestClass1&)" << endl; }
     8     TestClass1& operator=(const TestClass1&) { cout << "TestClas1s& operator=(const TestClass1&)" << endl; return *this; }
     9     ~TestClass1() {
    10         cout << "~TestClass1()" << endl;
    11     }
    12 };
    13 
    14 class TestClass2
    15 {
    16 public:
    17     TestClass2() {
    18         cout << "TestClass2()" << endl;
    19     }
    20     TestClass2(const TestClass2&) { cout << "TestClass2(const TestClass2&)" << endl; }
    21     TestClass2& operator=(const TestClass2&) { cout << "TestClass2& operator=(const TestClass2&)" << endl; return *this; }
    22     ~TestClass2() {
    23         cout << "~TestClass2()" << endl;
    24     }
    25 };
    26 
    27 class Test
    28 {
    29 public:
    30     Test() = default;
    31     Test(TestClass1& tc1, TestClass2& tc2) :m_tc2(tc2), m_tc1(tc1){}
    32 private:
    33     TestClass1 m_tc1;
    34     TestClass2 m_tc2;
    35 };
    1 int main()
    2 {
    3     Test t;
    4 }

    程序结果为:

    现象:先调用TestClass1的构造函数,再调用TestClass2的构造函数。

    原因:在类Test中,m_tc1变量声明在m_tc2变量之前,故m_tc1在m_tc2之前初始化。

    问题:在列表初始化的构造函数中,将m_tc2放在m_tc1之前,是否可以让m_tc2在m_tc1之前初始化?

    代码设计

    int main()
    {
        TestClass1 tc1;
        TestClass2 tc2;
        cout << "/**************************************************************************************/" << endl;
        Test t(tc1, tc2);
    }

    运行结果为:

    可以看到:仍然是TestClass1的构造函数先被调用,TestClass2的构造函数接着被调用。

    结论:C++中类成员变量的初始化顺序与其在类中的声明顺序是有关的,而与其在初始化列表中的顺序无关。

    再举一个例子:

    然后我将代码写成这样:

     1 class Test
     2 {
     3 public:
     4     Test() = default;
     5     Test(TestClass1& tc1, TestClass2& tc2):m_tc2(tc2){}
     6 private:
     7     TestClass1 m_tc1;
     8     TestClass2 m_tc2;
     9 };
    10 
    11 int main()
    12 {
    13     TestClass1 tc1;
    14     TestClass2 tc2;
    15     cout << "/**************************************************************************************/" << endl;
    16     Test t(tc1, tc2);
    17 }

    注意与之前代码的差别:我们在初始化列表中只初始化了m_tc2,没有动m_tc1。

    运行结果:

    结果分析:在初始化Test的对象t时,由于m_tc1的声明顺序在m_tc2的声明顺序之前,所以t会想要先初始化m_tc1,但是它在初始化列表中没有找到初始化m_tc1的内容,于是它只好调用m_tc1的默认构造函数了,完成m_tc1的初始化后,再根据初始化列表中的内容初始化m_tc2。

  • 相关阅读:
    Mysql的相关命令
    设置数据窗口的过滤与排序
    org.springframework.web.servlet.DispatcherServlet noHandlerFound
    tomcatPluginV321.zip
    js获取modelandview的值
    cintanotes
    暗手机
    TASKCITY
    win commands
    book
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/11602011.html
Copyright © 2011-2022 走看看