#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();
由结果对比可明显知道省去了调用默认构造函数的过程,提高了程序的运行效率。所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表。
二、另一方面,有些成员变量的初始化必须放在初始化列表里。哪些东西必须放在初始化列表中呢?
构造函数初始化时必须采用初始化列表一共有三种情况,
1. 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化(实例一可说明)。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的值未定义。
所以,一个好的习惯是,按照成员定义的顺序进行初始化。