合理的做法时,当定义一个变量时,我们应该立即对其初始化,而不是先定义,再初始化。考虑如下两个代码:
class A{ public: int a; int &b; const int c; A(int i):a(i), b(i), c(i) {} } class B{ public: int a; int &b; const int c; B(int i) { a = i; b = i;//无法堆引用赋值 c = i;//c没有初始化 } }
赋值操作的深层影响取决于数据成员的类型,此外直接初始化的效率要高于先初始化再赋值。如果数据成员是const 或 引用的话,必须对其初始化,而不能对其赋值。另外,初始化的顺序跟构造函数初始值列表的顺序无关,只跟成员变量在class中出现的先后顺序一致。
我们也可以为构造函数提供默认实参。当一个构造函数中的所有参数都有默认实参的话,实际上也就提供了默认构造函数。
此外,在C++11中扩展了构造函数的功能,我们可以定义所谓的委托构造函数。
class TT {
public:
int tmp = 1;
int b;
string str;
TT(int i, int j): tmp(i), b(j) {
cout<<1<<endl;
}
TT(int i):TT(i, 1) {
cout<<2<<endl;
}
TT(string in): TT(2) {
cout<<3<<endl;
}
};
执行顺序是先执行 受委托 的构造函数的初始值列表,然后执行其函数题,最后将控制权交给委托者的函数题。比如上面TT这个类,使用
TT test("123");
将依次打印出:
1 2 3