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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM