第三章 构造函数,析构函数和赋值操作符
条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
原因:系统默认的拷贝构造函数和赋值操作符是直接内存拷贝,不安全。
条款12: 尽量使用初始化而不要在构造函数里赋值
原因:“从纯实际应用的角度来看,有些情况下必须用初始化。特别是const和引用数据成员只能用初始化,不能被赋值。”“其次的原因在于效率。当使用成员初始化列表时,只有一个string成员函数被调用。而在构造函数里赋值时,将有两个被调用。”
条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同
原因:“游戏规则:类成员是按照它们在类里被声明的顺序进行初始化的,和它们在成员初始化列表中列出的顺序没一点关系。”“只是非静态数据成员的初始化遵守以上规则。”“基类数据成员总是在派生类数据成员之前被初始化”
条款14: 确定基类有虚析构函数
原因:虚函数表游戏规则造成的,基类一定要有虚析构函数,非基类最好不要用虚析构函数。纯虚析构函数是实现某些抽象类的一种好模式。
条款15: 让operator=返回*this的引用
原因:为了实现连等。返回引用比返回对象效率高。还是照着代码范版来吧,否则就需要对特殊情况进行预测分析。
条款16: 在operator=中对所有数据成员赋值
原因:为什么事情做一半?作者强调了一下容易出错的继承类忘记对基类进行赋值的问题。
条款17: 在operator=中检查给自己赋值的情况
原因:容易发生的bug。