C++初始化列表


C++初始化列表

定義一個類對象時,常常使用初始化列表實例化一個對象,在進入構造函數函數體之前對成員變量完成初始化操作。普通成員變量既可以在初始化中初始化,也可以在函數體重賦值;const成員變量只能在初始化列表中賦值。下面對初始化列表進行一個簡單介紹:

  • 使用初始化列表
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int x,int y,int z) : a(x),b(y),c(z){}
 8 public:
 9     void Print() const{
10         cout<<"a = "<<a<<endl;
11         cout<<"b = "<<b<<endl;
12         cout<<"c = "<<c<<endl;
13     }
14 private:
15     int a;
16     int b;
17     int c;
18 };
19 
20 int main(int argc, char** argv)
21 {
22     InitTest test(10,20,30);
23     test.Print();
24 
25     return 0;
26 }

成員變量被正確賦值,輸出:

  • 初始化列表必須使用場景1——const成員變量
 1 class InitTest{
 2 public:
 3     InitTest(int x,int y,int z){
 4     
 5     a = x; // error C2758: “InitTest::a”: 必須在構造函數基/成員初始值設定項列表中初始化      
 6     b = y;
 7     c = z;
 8     }
 9 private:
10     const int a;
11     int b;
12     int c;
13 };    
 1 class InitTest{
 2 public:
 3     InitTest(int x,int y,int z) : a(x){ // OK
 4         b = y;
 5         c = z;
 6     }
 7 public:
 8     void Print() const{
 9         cout<<"a = "<<a<<endl;
10         cout<<"b = "<<b<<endl;
11         cout<<"c = "<<c<<endl;
12     }
13 private:
14     const int a;
15     int b;
16     int c;
17 };

 

  • 初始化列表必須使用場景2——成員變量或基類未聲明默認構造函數

成員變量未聲明默認構造函數

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int x,int y,int z) : a(x),b(y),c(z){}
 8 public:
 9     void Print() const{
10         cout<<"a = "<<a<<endl;
11         cout<<"b = "<<b<<endl;
12         cout<<"c = "<<c<<endl;
13     }
14 private:
15     int a;
16     int b;
17     int c;
18 };
19 
20 class HaveInitTest{
21     InitTest test1;
22 public:
23     HaveInitTest(){}
24 };
25 
26 int main(int argc, char** argv)
27 {
28     HaveInitTest havetest; // error C2512: “InitTest”: 沒有合適的默認構造函數可用
29 
30     return 0;
31 }
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int x,int y,int z) : a(x),b(y),c(z){}
 8 public:
 9     void Print() const{
10         cout<<"a = "<<a<<endl;
11         cout<<"b = "<<b<<endl;
12         cout<<"c = "<<c<<endl;
13     }
14 private:
15     int a;
16     int b;
17     int c;
18 };
19 
20 class HaveInitTest{
21     InitTest test1;
22 public:
23     HaveInitTest() : test1(0,0,0){}
24 };
25 
26 int main(int argc, char** argv)
27 {
28     HaveInitTest havetest; // OK 29 
30     return 0;
31 }

基類未聲明默認構造函數

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int x,int y,int z) : a(x),b(y),c(z){}
 8 private:
 9     int a;
10     int b;
11     int c;
12 };
13 
14 class DerivedFromInitTest : public InitTest{
15 public:
16     DerivedFromInitTest(){}
17 };
18 
19 int main(int argc, char** argv)
20 {
21     DerivedFromInitTest dervetest; // error C2512: “InitTest”: 沒有合適的默認構造函數可用
22 
23     return 0;
24 }
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int x,int y,int z) : a(x),b(y),c(z){}
 8 private:
 9     int a;
10     int b;
11     int c;
12 };
13 
14 class DerivedFromInitTest: public InitTest{
15 public:
16     DerivedFromInitTest() : InitTest(0,0,0){}
17 };
18 
19 int main(int argc, char** argv)
20 {
21     DerivedFromInitTest derivetest; // OK 22 
23     return 0;
24 }

最簡單的解決方法是將InitTest的構造函數聲明為:InitTest(int x = 0,int y = 0,int z = 0)。

  • 初始化列表必須使用場景3——聲明為引用類型的成員變量
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(int &x, int y, int z){
 8         a = x; // error C2758: “InitTest::a”: 必須在構造函數基/成員初始值設定項列表中初始化
 9         b = y;
10         c = z;
11     }
12 private:
13     int &a;
14     int b;
15     int c;
16 };

 

 1 class InitTest{
 2 public:
 3     InitTest(int &x, int y, int z) : a(x){ // OK
 4         b = y;
 5         c = z;
 6     }
 7 private:
 8     int &a;
 9     int b;
10     int c;
11 };

 數據成員初始化順序

數據成員按照他們在類中的聲明順序來初始化,而不是按照在初始化列表中出現的順序。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(const int a, const int b) : x(a),y(b){}
11 private:
12     int x;
13     int y;
14 };
15 
16 int main(int argc, char** argv)
17 {
18     InitTest test(10,20); // test.x = 10, test.y = 20
19 
20     return 0;
21 }
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class InitTest{
 6 public:
 7     InitTest(const int a, const int b) : y(b),x(a + y){}
 8 private:
 9     int x;
10     int y;
11 };
12 
13 int main(int argc, char** argv)
14 {
15     InitTest test(10,20); // test.x未初始化, test.y = 20
16 
17     return 0;
18 }

!總結:初始化列表中,先聲明數據不依賴后聲明數據來初始化。


免責聲明!

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



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