成员初始化列表

C++为类中提供类成员的初始化列表

类对象的构造顺序是这样的:
1.分配内存,调用构造函数时,隐式/显示的初始化各数据成员
2.进入构造函数后在构造函数中执行一般计算

使用初始化列表有两个原因:

1.必须这样做:

《C++ Primer》中提到在以下三种情况下需要使用初始化成员列表:

  • 需要初始化的数据成员是对象的情况;
  • 需要初始化const修饰的类成员;
  • 需要初始化引用成员数据;

如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。

class ABC
{
public:
         ABC(int x,int y,int z);
private:
         int a;
         int b;
         int c;
};
class MyClass
{
public:
        MyClass():abc(1,2,3)...{}
private:
        ABC abc;
};

因为ABC有了显式的带参数的构造函数,那么他是无法依靠编译器生成默认构造函数的,所以没有三个int型数据,就无法创建ABC的对象。
ABC类对象是MyClass的成员,想要初始化这个对象abc,那就只能用成员初始化列表,没有其他办法将参数传递给ABC类构造函数。
另一种情况是这样的:当类成员中含有一个const对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。

2.效率要求这样做:

类对象的构造顺序显示,进入构造函数体后,进行的是计算,是对他们的赋值操作,显然,赋值和初始化是不同的,这样就体现出了效率差异,如果不用成员初始化类表,那么类对自己的类成员分别进行的是一次隐式的默认构造函数的调用,和一次赋值操作符的调用,如果是类对象,这样做效率就得不到保障。
注意:构造函数需要初始化的数据成员,不论是否显式的出现在构造函数的成员初始化列表中,都会在该处完成初始化,并且初始化的顺序和其在声明时的顺序是一致的,与列表的先后顺序无关,所以要特别注意,保证两者顺序一致才能真正保证其效率。
为了说明清楚,假设有这样一个类:

class foo{
private :
    int a, b;
};

1、foo(){}和foo(int i = 0){}都被认为是默认构造函数,因为后者是默认参数。两者不能同时出现。
2、构造函数列表的初始化方式不是按照列表的的顺序,而是按照变量声明的顺序。比如foo里面,a在b之前,那么会先构造a再构造b。所以无论 foo():a(b + 1), b(2){}还是foo():b(2),a(b+1){}都不会让a得到期望的值。如果先声明b再声明a则会更好。

还有一种必须使用初始化列表的情况就是,在C++在继承里面,只有初始化列表可以构造父类的private成员。比如说

class child : public foo{};

foo里面的构造函数是这样写的:foo (int x) { a = x; }.
而在child里面写child(int x){ foo(x); }是通过不了编译的。只有把父类初始化改为foo(int x) : a(x){}而子类构造写作child (int x) : foo(x){}才可以。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 它用于初始化类的成员变量,只能用于构造函数中,并且最重要的一点在于它是在类的代码执行前,即对象构造阶段完成的,这会...
    Stroman阅读 982评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,288评论 19 139
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,558评论 1 51
  • 当类的成员中有其他类的对象时,C++要求先构造其他类的对象,如下图所示: 所以当在构造函数中的成员初始化列表中指定...
    Stroman阅读 248评论 0 0
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,334评论 9 118