详解初始化列表

来源:互联网 发布:什么学英文软件 编辑:程序博客网 时间:2024/06/03 17:38

初始化列表

定义

构造函数有个特殊的初始化方式叫“初始化表达式表”(简称初始化列表)。初始化列表位于函数参数表之后,却在函数体 {} 之前。这说明该表里的初始化工作发生在函数体内的任何代码被执行之前。

Date(int year, int month, int day)//带参构造函数        :_year(year)        , _month(month)        , _day(day)    {}

构造函数的两个执行阶段

构造函数的执行可以分成两个阶段,初始化阶段和计算阶段,初始化阶段先于计算阶段。

初始化阶段:

所有类类型(class type)的成员都会在初始化阶段初始化,即使该成员没有出现在构造函数的初始化列表中。

计算阶段

一般用于执行构造函数体内的赋值操作。

为什么使用初始化列表

使用初始化列表主要是基于性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表,为什么呢?我们看例子:

使用构造函数函数体内赋值:

class Test1{public:    Test1()//无参的构造函数    {        cout << "Construct Test1" << endl;    }    Test1(const Test1& t1) // 拷贝构造函数    {        cout << "Copy constructor for Test1" << endl;    }    Test1& operator=(const Test1& t1)    {        cout << "operator=()" << endl;        a = t1.a;        return *this;    }protected:    int a;};class Test2{public:    Test1 test1;    Test2(Test1 &t1)    {        test1 = t1;    }};int main(){    Test1 t1;    Test2 t2(t1);    system("pause");    return 0;}

输出结果:
这里写图片描述

使用初始化列表赋值:

class Test1{public:    Test1()//无参的构造函数    {        cout << "Construct Test1" << endl;    }    Test1(const Test1& t1) // 拷贝构造函数    {        cout << "Copy constructor for Test1" << endl;    }    Test1& operator=(const Test1& t1)    {        cout << "operator=()" << endl;        a = t1.a;        return *this;    }protected:    int a;};class Test2{public:    Test1 test1;    Test2(Test1 &t1)        :test1(t1)    {}};int main(){    Test1 t1;    Test2 t2(t1);    system("pause");    return 0;}

输出结果:
这里写图片描述

从上面的两个代码比较可以看出使用初始化列表,直接调用拷贝构造函数初始化,省去了默认构造函数的过程。所以能使用初始化列表的时候尽量使用初始化列表。

哪些东西必须放在初始化列表中

  • 常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面。
  • 引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面。
  • 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。

成员变量的初始化顺序

成员是按照他们在类中声明的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的。例如:

class Date{public:    Date(int year, int month, int day)//带参构造函数        :_month(month)//第二个初始化        , _year(year) //第一个初始化        , _day(day)   //第三个初始化    {}private:    int _year; //第一个定义    int _month;//第二个定义    int _day;  //第三个定义};
原创粉丝点击