条款4 确定对象被使用前已经初始化
1.无任何成员的内置类, 手动完成初始化
2.内置类型以外的在构造函数中初始化,即确保构造函数都将每一个成员初始化。
3.对象初始化发生在进入构造函数体之前,在构造函数体内,成员变量不是被初始化, 而是被赋值
class PhoneNumber{
};
class ABEntry{
public:
ABEntry(const string &name, const string &address, const list<PhoneNumber>&phones):
theName(name),theAddress(address), thePhones(phones),numTimesConsulted(0){
}//推荐写法
private:
string theName;
string theAddress;
list<PhoneNumber> thePhones;
int numTimesConsulted;
};
写法1:
ABEntry(const string &name, const string &address, const list<PhoneNumber>&phones):
{
theName=name;
theAddress = address;
thePhones = phones;
numTimesConsulted = 0;
}
进入ABEntry之前, 对4个成员变量初始化, 进入ABEntry之后, 对四个成员变量进行赋值copy,
写法2:
ABEntry(const string &name, const string &address, const list<PhoneNumber>&phones):
theName(name),theAddress(address), thePhones(phones),numTimesConsulted(0){
}//推荐写法
进入ABEntry之前, 直接对4个成员变量赋值初始化, 相较于写法1, 少了在函数体中进行赋值操作, 所以效率要高些。
注意:
1.内置型对象进行手工初始化
2.构造函数最好使用初始值列, 不在构造函数中赋值, 初始化时,与类中声明排列次序保持一致。
3.为避免初始化次序问题, 以local static 对象替换non-local static 对象。
条款5 了解c++默默编写并调用哪些函数
定义一个类class Empty{}; 默认生成如下函数:
class Empty{
public:
Empty(){} //default 构造
Empty(const Empty&rhs){} //copy 构造函数
~Empty(){} //析构函数
Empty & operator=(const Empty&rhs){} //copy assignment 拷贝赋值操作
};
Empty e1; //default 构造, 析构函数
Empty e2(e1); //copy构造
e2 = e1; //copy assignment
如果类中存在带参的构造函数, 则编译器不会再创建default构造函数。
template<typename T>
class NamedObject{
public:
NamedObject(const char *name, const T&value):nameValue(name),objectValue(value){}
NamedObject(const string &name, const T&value):nameValue(name),objectValue(value){}
private:
string nameValue;
T objectValue;
};
NamedObject没有声明 copy构造和copy assignment构造函数, 所以编译器会自动生成。
如下用法编译可以通过
int main(){
char *name = "hello";
int value = 10;
NamedObject obj1(name, value);
NamedObject obj2 = obj1;
NamedObject obj3(obj1);
return 0;
}
编译器生成copy构造函数和copy assignment构造函数的条件是:
- name 与obj1.nameValue有copy 构造。
- value 与obj1.objectValue(T为int)是个内置类,是按照每一个bits来完成初始化。