C++ 成员初始化列表

——调用构造函数时,对象将在括号中的代码执行前被创建,因此无法在括号内初始化对象的常量成员。

Queue::Queue(int qs)
{
    front = rear = NULL;
    items = 0;
    qsize =qs;    // not acceptable! qsize是一个常量成员
}

因此C++提供了一种特殊的语法来完成上述工作——成员初始化列表

  • 由逗号分隔的初始化列表组成(前面带冒号)。
  • 位于参数列表的右括号之后、函数体左括号之前。
  • 如果数据成员的名称为mdata,并需要将它初始化为val,则初始化器为mdata(val)。
    1 Queue::Queue(int qs) : qsize(qs), items(0) // initialize qsize to qs, 0 to items
    2 {
    3     front = rear = NULL;
    4 } 

    初值可以是常量或构造函数的参数列表中的参数,并且初始化并不只限定用于常量

何时使用:

  • 只有构造函数可以使用种初始化列表语法,不能将成员初始化列表用于构造函数之外的其它类方法
  • 对于本身就是类对象的成员来说,使用成员初始化列表的效率更高(直接调用复制构造函数或转换函数,代替了【调用默认构造函数,再使用赋值运算符给目标对象赋值】或【未重新定义赋值运算符时:调用默认构造函数,再调用转换函数构造临时对象,最后将临时对象赋给目标对象】【重新定义赋值运算符后:调用默认构造函数,再使用定义的赋值运算符给目标对象赋值】的步骤)
  • 非静态const成员必须使用这种语法(在C++11之前)
  • 被声明为引用的类成员必须使用这种语法

特点

  • 数据成员被初始化的顺序于它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关
  • 成员初始化列表使用的括号方式也可用于常规初始化
    • 即可将
      int games = 162;
      double talk = 2.17828;

      替换为

      int games(162);
      double talk(2.17828);

C++11:

——C++11允许以更直观的方式进行初始化(非静态const成员,非静态成员):

class Classy
{
    int mem1 = 10;    // in-class initialization
    const int mem2 = 20;    // in-class initialization
    ...
};

  如果调用了使用成员初始化列表的构造函数,在这种情况下,实际列表将覆盖这些默认初始值