C++构造函数详解
1. 构造函数的定义
a. 类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数(constructor);
b. 构造函数的任务是初始化类的数据成员,无论何时只要类的对象被创建,就会执行构造函数;
c. 构造函数的名字与类名相同,且没有返回类型 ,构造函数也有一个(可能为空的)参数列表和一个(可能为空的)函数体;
d. 当类包含多个构造函数时,和其他重载函数一样,不同的构造函数之间必须在参数数量或参数类型上有所区别。
2. 构造函数的类型
2.1 合成的默认构造函数
a. 如果类没有显式地定义构造函数,那么编译器就会为该类隐式地定义一个默认构造函数。
b. 合成的默认构造函数初始化规则:
- 如果存在类内的初始值,用它来初始化成员;
- 否则,默认初始化该成员(例如2.2中的bookNo将被初始化为空string对象,而units_sold和revenue将是0);
c. 某些类不能依赖于合成的默认构造函数
- 编译器只有在发现类内不包含任何构造函数的情况下才会生成一个默认的构造函数;
- 含有内置类型或复合类型成员的类应该在类的内部初始化这些成员,或者定义一个自己的默认构造函数,否则创建对象时可能得到未定义的值;
- 如果类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数,编译器将无法初始化该成员;
2.2 构造函数初始值列表
a. 在定义变量时我们习惯于立即对其进行初始化,而非先定义,再赋值;就对象的数据成员而言,初始化和赋值也有类似的区别。
// C++ primer 5 P237
Sales_data(const std::string &s, unsigned n, double p):
bookNo(s), units_sold(n), revenue(p*n) { }
b. 如果成员是const或者是引用以及成员属于某种类类型且该类没有定义默认构造函数的话,必须将其初始化!
// C++ primer 5 P258
class ConstRef{
public:
ConstRef(int ii);
private:
int i;
const int ci;
int &ri;
};
//错误:ci和ri必须被初始化
ConstRef::ConstRef(int ii)
{
//赋值
i = ii; //正确
ci = ii; //错误:不能给const赋值
ri = i; //错误:ri没被初始化
}
//正确:显示地初始化引用和const成员
ConstRef::ConstRef(int ii): i(ii), ci(ii), ri(i) { }
c. 成员初始化的顺序与它们在类定义中的出现顺序一致。
class X{
int i;
int j;
public:
//i在j之前被初始化
X(int val): j(val), i(j) { }
};