C++的初始化列表(Initilization List)
2016-05-21 22:28
549 查看
初始化类的成员有两种方式,一是使用初始化列表,二是在构造函数体内进行赋值操作。第二种我们都比较熟悉了,来看看第一种情况。
一、 为什么使用初始化列表(Initialization list)
使用初始化列表一方面主要是基于性能问题,对于类类型来说,最好使用初始化列表,为什么呢?
因为对于没有默认构造函数的类类型,使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。
我们可以看一下实例:
当不适用初始化列表是实现son的构造函数时,其结果为:
当使用初始化列表实现son的构造函数时,其结果为:
由结果对比可明显知道省去了调用默认构造函数的过程,提高了程序的运行效率。所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表。
二、另一方面,有些成员变量的初始化必须放在初始化列表里。哪些东西必须放在初始化列表中呢?
构造函数初始化时必须采用初始化列表一共有三种情况,
1.没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化(实例一可说明)。
2.需要初始化const修饰的类成员;(因为const的成员不能改变所以不能对其进行复制,只能对其进行初始化)
3.需要初始化引用成员数据;(引用一开始必须初始化,并且已经初始化的引用不能再变)
2、3两点可以通过下面实例来解释:
成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的,看代码。
所以,一个好的习惯是,按照成员定义的顺序进行初始化。
一、 为什么使用初始化列表(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的值未定义。
所以,一个好的习惯是,按照成员定义的顺序进行初始化。
相关文章推荐
- 【转载】Qt Quick 之 QML 与 C++ 混合编程详解
- c++作业6
- 编码规范-如何写个优美的C++类
- 【步兵 c++】当模版遇上二进制
- C语言——通过指针如何操作字符串——储存和运算
- C++中的模板template <typename T>
- c++实验6-数组合并
- c++之继承1
- 【步兵 c++】教科书般的A*寻路算法
- C++实验6—矩阵求和
- C++为什么可以进行函数重载以及引起的二义性问题
- C++实验6—数组操作
- C++作业6
- C语言 pthread的使用
- -i++与i的值问题
- c++拾遗-----函数探幽
- 【VS开发】C++异常处理操作
- C++中的name mangling
- GeekBand c++學習筆記之二(帶指針的class中的必須要學的-Big Three法則)
- 2015第六届蓝桥杯B组C/C++决赛题解【2.5.6待解><】