构造函数没有返回类型
默认构造函数
参数列表为空
合成的默认构造函数
一些简单的类中没有显示地定义默认构造函数,编译器会为其隐式地生成默认构造函数,这个默认构造函数称为合成的默认构造函数。
但是有些类不能依赖于合成的默认构造函数,必须自定义默认构造函数。原因有三:
1.定义了其它的构造函数。
2.合成的默认构造函数可能会执行错误的初始化操作。例如,当对象中含有数组或指针类型的时候,被合成的默认构造函数进行初始化得到的数组或指针为未定义状态。
3.不能为某些类合成默认的构造函数。例如,当类中含有其他类成员且该成员没有默认构造函数
例子:
class Sales_data {
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
public:
Sales_data() = default;
Sales_data(const std::string &s): bookNo(s) { }
Sales_data(const std::string &s, unsigned n, double p):
bookNo(s), units_sold(n), revenue(p*n) { }
private:
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
初始值列表
构造函数参数列表后的冒号以及冒号和花括号之间的代码,这一部分称为构造函数的初始值列表。
Sales_data(const std::string &s): bookNo(s) { }
Sales_data(const std::string &s, unsigned n, double p):
bookNo(s), units_sold(n), revenue(p*n) { }
其中bookNo(s)就是对Sales_data的数据成员bookNo进行显示初始化。
这个列表是数据成员的一个列表以及各个成员的初始值,对这些成员进行显示初始化,倘若没有出现在此列表中的数据成员将以
与默认合成默认构造函数相同的方式隐式初始化。
倘若没有进行显示初始化,就会在构造函数体之前进行默认初始化。
例如:
Sales_data(const std::string &s, unsigned n, double p)
{
bookNo=s;
units_sold=cnt;
revenue=cnt*price;
}
这种构造函数就是省略了初始化值列表。这样在数据成员构造函数体之前会就进行默认初始化,再在构造函数中对数据成员进行
赋值操作。在这个构造函数中,两种方法的结果相同。
但是构造函数的从初始值有时必不可少。有时我们可以忽略数据成员初始化和赋值之间差异,但有时不可以。
初始化的顺序,与成员在初始化列表中的顺序无关,只与成员在类中的声明顺序有关。
必须使用初始化列表的情况
当数据成员是const、引用,或者属于某种未提供默认构造函数的类类型,我们必须通过构造函数初始值列表为这些数据成员提供初始值。
因为const不能进行赋值拷贝,引用必须被初始化,未提供默认构造函数的类类型不会进行默认初始化。
而且,进行赋值还会导致效率问题。先默认初始化再赋值
make_plural定义在C++primer第五版中,6.3.2中有返回值的函数中定义的。
make_plural.h
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr > 1) ? word + ending : word;
}
C++默认参数的设置
(1)当函数声明和函数定义同时存在时,默认参数只能在其中一个中进行指定;
(2)当没有函数声明时,在函数定义中指定默认参数;
(3)当有多个参数的时候,默认参数需要在无默认参数的参数右边;
(4)当调用的函数时,某个实参使用默认参数则其右边都使用默认参数
//例如, 一个函数声明如下
int f(int i1 = 1, int i2 =2, int i3 = 3);
//调用函数 f()
f(); //正确, i1=1, i2=2, i3=3
f(3); //正确, i1=3, i2=2, i3=3
f(2, 3); //正确, i1=2, i2=3, i3=3
f(4, 5, 6); //正确, i1=4, i2=5, i3=6
f(, 2, 3); //错误, i1默认,其右边的i2和i3没有默认