您的位置:首页 > 编程语言 > C语言/C++

C++的初始化列表(Initilization List)

2016-05-21 22:28 549 查看
        初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。第二种我们都比较熟悉了,来看看第一种情况。
       一、 为什么使用初始化列表(Initialization list)

       使用初始化列表一方面主要是基于性能问题,对于类类型来说,最好使用初始化列表,为什么呢?

        因为对于没有默认构造函数的类类型,使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。

我们可以看一下实例:
#include<iostream>
#include <stdlib.h>
#include <string.h>
using namespace  std;
class Father
{
public:
int x;
int y;
Father(int m=0,int n=0)
{
x=m;
y=n;
cout<<"this is constructor"<<endl;
}
Father(Father &fp)
{
this->x=fp.x;
this->y=fp.y;
cout<<"this is copy constructor"<<endl;
}
void  operator=(Father &f1)
{
this->x=f1.x;
this->y=f1.y;
cout<<"this is operator"<<endl;
}
void show1()
{
cout<<x<<" "<<y<<endl;
}
};
class Son
{
public:
Father ff;
int num;
Son(Father f2,int number)
{
ff=f2;
num=number;
cout<<"this is son constructor"<<endl;
}
Son(int i,int j,int k):ff(i,j),num(k)
{
cout<<"this is son constructor for init list"<<endl;
}
void show2()
{
cout<<num<<endl;
}
};
int main()
{
Father f1(1,2);//不使用初始化列表来实现son的构造函数;
Son s1(f1,44);
s1.ff.show1();
s1.show2();
system("pause");
return 0;
}

当不适用初始化列表是实现son的构造函数时,其结果为:



Son s1(1,2,44);  //使用初始化列表来实现son的构造函数;
s1.ff.show1();
s1.show2();


当使用初始化列表实现son的构造函数时,其结果为:



由结果对比可明显知道省去了调用默认构造函数的过程,提高了程序的运行效率。所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表。

二、另一方面,有些成员变量的初始化必须放在初始化列表里。哪些东西必须放在初始化列表中呢?

    构造函数初始化时必须采用初始化列表一共有三种情况,

        1.没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化(实例一可说明)。

        2.需要初始化const修饰的类成员;(因为const的成员不能改变所以不能对其进行复制,只能对其进行初始化)

        3.需要初始化引用成员数据;(引用一开始必须初始化,并且已经初始化的引用不能再变)

        2、3两点可以通过下面实例来解释:
class Father
{
public:
const  int x;  //常量变量
int &y;   //引用变量;
/*Father(int n=1)  //此种初始化方法会报错;
{
x=n;
y=x;
}*/
Father(int m,int n):x(m),y(n)  //必须的这样初始化;
{
}
};
三、成员变量的初始化顺序

    成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的,看代码。
class Father
{
public:
int x;
int y;
Father(int m):x(m),y(n){};  //OK 先初始化x,再初始化y;
};
   再看下面的代码
class Father
{
public:
int x;
int y;
Father(int m):x(y),y(m){};  //这里的x的值是未定义的;
};
  这里x的值是未定义的,虽然x在初始化列表里面出现在y前面,但是x先于y定义,所以先初始化x,但x由y初始化,此时y尚未初始化,所以导致x的值未定义。
  所以,一个好的习惯是,按照成员定义的顺序进行初始化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: