zoukankan      html  css  js  c++  java
  • 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 }

    !总结:初始化列表中,先声明数据不依赖后声明数据来初始化。

  • 相关阅读:
    移动端开发-禁止横屏
    奇葩的对象创建方式(更新中)
    每日积累之8.8
    每日积累 8.6
    折半查找
    linux中的amount的解释
    Redis集群错误
    每日积累 8.6
    Redis中在程序中的应用
    每日积累 8.4
  • 原文地址:https://www.cnblogs.com/pbendan/p/4589209.html
Copyright © 2011-2022 走看看