初始化

类的成员变量有三个位置进行初始化:

声明时初始化:

初始化列表初始化( 成员变量初始化的顺序是按照在那种定义的顺序)

以下三种情况下必须使用初始化成员列表
一、需要初始化的数据成员是对象,且该对象不能默认构造。(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化);因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。
二、需要初始化const修饰的类成员;(C++11后,声明时初始化也可以)
三、需要初始化引用成员数据;

对于一补充:

c++ primer P258

如果没有构造函数的初始化列表中显式地初始化成员,
则该成员将在构造函数体之前执行默认初始化.

所以对于类成员,我们需要定义默认初始化,或者在初始化列表中初始化

变量初始化顺序:

c++ primer

不过稍让人意外的是,构造函数初始值列表只用于初始化成员的值,而不限定初始化执行的顺序.
成员的初始化顺序与它们在类定义中的出现顺序一致:第一个成员先被初始化,然后第二个,以此类推. 构造函数初始化列表中初始化值的前后位置关系不会影响实际的初始化顺序.
一般情况下初始化的顺序没什么要求,如果如果一个成员使用另一个成员来初始化的,那么这两个成语啊你的初始化顺序就很关键了.
  举个例子,考虑下面这个类
class X{
  int i;
  int j;
  public:
  //未定义的,i在j之前初始化
  X(int val):j(val),i(j){}
  
  // 补充:  X(int val):i(val),j(i){}   OK
};
有些编译器具备一项比较友好的功能,即当构造函数和初始化列表中的数据成员顺序与这些成员声明的顺序不符时会生成一条警告信息.

构造函数内赋值初始化成员变量:

对于内置类型(char,int……指针等):

基本上是没有区别的,效率上也不存在多大差异

对于自定义类对象的成员初始化

  • 初始化列表是直接调用拷贝函数构造;
  • 构造函数内赋值是先调用默认构造函数构造(当然,你得保证你定义的类有无参构造函数),在调用重载赋值函数赋值
    所以使用初始化列表效率高很多。能使用初始化列表的时候尽量使用初始化列表