成员初始化列表
语法
成员初始化器列表紧接在构造函数的括号之后,以冒号开头,后跟一系列以逗号分隔的成员初始化器。如果使用初始化列表将会直接进行拷贝构造,不用默认构造再赋值,在某些情况下可以加快程序运行效率。
具体怎么写看代码:
class Pig
{
private:
const std::string name;
int age;
};
Pig::Pig(std::string n, int a) : name(n), age(a){}
冒号后接类中的成员,括号内写传入的形参对其进行初始化。
值得一提的是:最好养成按照类中的声明顺序进行初始化的习惯。因为先声明的成员会先初始化,所以初始化顺序不一样的话可能出错。
必须要用的初始化器列表的时候
- 常量成员。因为常量成员只能初始化不能进行赋值,所以必须放在初始化器列表里面。
- 引用类型。因为引用必须在定义的时候初始化,并且不能重新赋值,所以必须使用初始化器。
- 缺少无参构造函数的类成员。由于该类成员缺少无参构造函数,必须使用有参构造函数初始化,初始化列表恰好可以使用有参构造函数初始化。
下面是一个例子:
class NumberDispaly {
private:
const int limit;
int value;
public:
NumberDispaly() = default;
NumberDispaly(int,int=0);
};
class ClockDisplay {
private:
NumberDispaly hour;
NumberDispaly minute;
public:
ClockDisplay();
ClockDisplay(int hour,int minute);
};
我们注意到ClockDisplay中的成员为NumberDispaly类,所以在写ClockDisplay的构造函数时应该使用初始化器列表
ClockDisplay::ClockDisplay() : hour(24, 0), minute(60, 0){}
ClockDisplay::ClockDisplay(int hour,int minute): hour(24, hour), minute(60, minute){}
若未使用初始化列表则会出现以下报错:
error: use of deleted function 'NumberDispaly::NumberDispaly()'
初始化列表的结合使用
我们注意到,在初始化列表之后还有一个大括号
Test() : k(10) {}
这个大括号并不是摆设,你可以在大括号中添加内容,这样在调用该构造函数时也会一并执行括号内的语句。k为常量成员所以必须使用初始化器列表,i,j则可以在之后进行赋值。
class Test
{
int i;
int j;
const int k;
public:
Test() : k(10)
{
std::cout << "invoke consttuctor!" << std::endl;
i = 1;
j = 2;
}
};
由于学习不精,文章有不正确的地方望读者指正。