C++初始化成员列表

C++在类的构造函数中,可以两种方式初始化成员数据:

  • 在构造函数的实现中,初始类的成员数据。
  • 还可以定义初始化成员列表 (Initializer list) 来初始化成员数据。

 

那么我们在什么情况下该使用初始化成员列表呢?

  1. 需要初始化的数据成员是对象。
  2. 需要初始化的类成员是const对象或者引用对象。
  3. 解决没有默认构造函数的类成员对象的生成。
  4. 在继承里面,只有初始化列表可以构造父类的private成员。

 

 

1. 需要初始化的数据成员是对象。

 

Cpp代码   收藏代码
  1. #include <stdio.h>  
  2. class point  
  3. {  
  4.     protected:  
  5.         int m_x,m_y;  
  6.   
  7.     public:  
  8.         point(int m=0,int n=0)  
  9.         {  
  10.             m_x = m;  
  11.             m_y = n; 
  12.             printf("constructor called!\n"); 
  13.         }  
  14.   
  15.         point(point& p)  
  16.         {  
  17.             m_x = p.GetX();  
  18.             m_y = p.GetY();  
  19.             printf("copy constructor called!\n");
  20.         }  
  21.   
  22.         int GetX()  
  23.         {  
  24.             return m_x;  
  25.         }  
  26.   
  27.         int GetY()  
  28.         {  
  29.            return m_y;  
  30.         }  
  31. };  
  32.    
  33. class point3d  
  34. {  
  35.     private:  
  36.     point m_p;  
  37.     int m_z;  
  38.   
  39.     public:  
  40.         point3d(point p, int k)  
  41.         {  
  42.             m_p = p;  
  43.             m_z=k; 
  44.         }  
  45.   
  46.          point3d(int i,int j, int k):m_p(i,j)   // 相当于 point m_p(i,j)这样对m_p初始化  
  47.          {  
  48.              m_z=k;  
  49.          }  
  50.   
  51.          void Print()  
  52.          {  
  53.              printf("%d,%d,%d \n",m_p.GetX(),m_p.GetY(),m_z);  
  54.          }  
  55. };  

 

   我们可以使用如下进行初始化,它将调用拷贝构造函数:

   关于拷贝构造函数,可参见 http://www.cnblogs.com/BlueTzar/articles/1223313.html

 

Cpp代码   收藏代码
  1. void main()  
  2. {  
  3.     point p1(1,2);    //先定义一个2D坐标  
  4.     point3d p3d(p1,3);  
  5.     p3d.Print();  
  6. }  

 输出:

constructor called!
copy constructor called!
constructor called!
1,2,3 

为什么呢?

第一个constructor called!是构造p1;

第二个copy constructor called!是把p1传入函数p3d的p时,因为函数形参的赋值操作时一个使用拷贝构造函数的过程。会调用拷贝构造函数把p1拷贝到p;

第三个constructor called!是point3d p3d(p,3)这个构造函数执行时,首先按顺序初始化所有的成员列表,然后执行函数体。初始化列表时,虽然我们没有显示的告诉它怎么初始化,但是此时编译器会用默认值进行初始化,一般是0。对于其中的成员变量m_p,会采用默认的无参数构造函数。(如果没有默认的无参构造函数,此时编译会报错,解决方法是,在初始化列表里显示的使用有参构造)至于m_p=p这个怎么运行呢,这里不会调用拷贝构造函数,因为拷贝构造函数也是一种构造函数,只有在心间对象时会调用,此处调用的是=号运算符,如果我们没有定义这个运算符操作,则编译器会自己合成一个按位拷贝的=号操作运算函数。


   也可以使用初始化成员列表进行初始化:

 

Cpp代码   收藏代码
  1. void main()  
  2. {  
  3.     point3d p3d(1,2,3);  
  4.     p3d.Print();  
  5. }  

 

输出:

constructor called!
1,2,3 


只调用了一次constructor called!,这次调用是在上面那种里的第三个constructor called!,构造成员变量m_p,在初始化列表里,使用含参构造



   由于对象赋值比初始化要麻烦的多,因此也带来的性能上的消耗。所以使用初始化列表可以更高效地初始化成员变量是对象的情况。

 

 

2. 需要初始化的类成员是const对象或者引用对象。

 

对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,、因此只能用初始化列表对其进行初始化。

 

Cpp代码   收藏代码
  1. #include <stdio.h>  
  2. class base  
  3. {  
  4.     private:  
  5.         const int a;  
  6.         int& b;  
  7.   
  8.     public:  
  9.          // base(int m, int n)  
  10.          // {  
  11.          //  a = m;  
  12.          //  b = n;  
  13.          // }  
  14.   
  15.          base(int m, int n):a(m),b(n)  
  16.          {}  
  17. };  
  18.    
  19. void main()  
  20. {  
  21.     base b(1,2);  
  22. }  

 

其中,注释的部分将无法通过编译。

 

 

3. 解决没有默认构造函数的类成员对象的生成。

 

如果成员类型是没有默认构造函数的类。若没有提供显示初始化,则编译器隐式使用成员类型的默认构造函数,若该类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。

 

 

4. 在继承里面,只有初始化列表可以构造父类的private成员。

 

 

原文地址:http://blog.csdn.net/freedom0203/article/details/2805945

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值