1.使用=default生成默认构造函数
在C++11新标准中,如果我们需要默认的行为,那么可以通过在参数列表后面写上=default来要求编译器生成构造函数。其中,=default既可以和声明一起出现在类的内部,也可以作为定义出现在类的外部。和其他函数一样,如果=default在类的内部,则默认的构造函数是内联的;如果它在类的外部,则该成员默认情况下不是内联的。
2.默认初始化
如果内置类型的变量未被显示初始化,它的值由定义的位置决定。定义在任何函数体外面的值被初始化为0.定义在函数体内部的内置变量不被初始化。一个未被初始化的内置类型变量是未定义的。如果师徒拷贝或者以其他形式访问词类值将引发错误。
新标准规定:可以为数据成员提供一个类内初始值。创建对象时,类内初始值将用于初始化数据成员,没有初始值的成员将被默认初始化。
当我们初始化类类型成员时,需要为构造函数传递一个符合成员类型的实参。类内初始值必须使用=的初始化形式(初始化类的数据成员时所用)或者花括号括起来的直接初始化形式。
例如
class Screen{
private:
int cursor=0;
int height=0;
string contents;
}
class Window{
private:
vector<Screen> screens{Screen(24,80," ")};
}
委托构造函数
一个委托构造函数使用了它所属类的其他构造函数执行它的初始化过程,或者说它把它自己的一些(或者全部)的职责委托给了其他的构造函数。
和其他构造函数一样,一个委托构造函数也有一个成员初始值的列表和一个函数体。在委托构造函数内,成员初始值列表只有一个唯一的入口,就是类名本身。和其他成员初始值一样,类名后面紧跟圆括号括起来的参数列表,参数列表必须与类中另一个构造函数匹配。
class Sales_data{
public:
Sales_data(string s, unsigned cnt, double price) :bookNo(s), units_sold(cnt), revenue(cnt*price){}
Sales_data() :Sales_data("", 0, 0){}
Sales_data(string s) :Sales_data(s, 0, 0){}
Sales_data(istream &is) :Sales_data(){ read(is, *this); }
};
在这个Sales_data中,除了第一个构造函数外,其他的构造函数都委托了他们的工作。第一个构造函数接受三个实参,使用这些实参初始化数据成员。然后结束工作(函数体为空,所以没有执行动作)。我们定义的默认构造函数使用接受三个实参的构造函数完成初始化工作,他也无须执行其他任务。接受一个string的构造函数同样委托了三参数的构造函数版本。
接受istream&的构造函数也是委托函数,它委托了默认构造函数,默认构造函数接着委托给三参数的构造函数。当这些受委托的构造函数执行完后,接着执行istream&构造函数体内的内容。它的构造函数体调用read函数读取给定的istream.
当一个构造函数委托给另一个构造函数时,受委托的构造函数的初始值列表和函数体被一次执行。在Sale_data类中,受委托的构造函数体恰是空的。假如函数体包含有代码的话,将先执行这些代码,然后控制权才会还给委托者的函数体。