构造/析构/复制
catch5 了解C++默认操作
编译器对空类class E{};自动编写一个默认构造函数E();一个拷贝构造函数E(const E& rhs){}一个析构函数~E(){}一个拷贝赋值操作符 E& operator =(const E& rhs){}
当E()内含引用成员进行赋值操作时,应该在初始化列表初始化,编译器不会为其生成copy assignment操作符;如果基类函数将copy assignment操作符声明为私有函数,同样滴子类也不会默认生成。
catch6 拒绝编译器自动生成函数的两种方法
将构造函数私有化且只声明不实现;或者继承自一个设计好的基类;
catch7 多态基类的析构函数写成virtual函数
一个类至少含有一个virtual函数时将其析构函数写成virtual函数,避免被继承时子类对象调用父类虚函数而形成“局部销毁”导致的内存泄漏;
但同时一个类不是为了作为基类或者实现多态,就不必把虚构函数声明为虚函数;
catch8 析构函数绝不吐出异常
catch 9 绝不在构造/析构过程中调用(基类和派生类共有的)virtual函数,构造函数调用的所有函数也同时服从这个约束。
这样会导致子类对象初始化时先调用父类构造初始化的是父类虚函数,子类虚函数不被构造函数初始化。对象内部含有未初始化的 成员,析构函数也同样如此
catch 10 令operator = 返回一个this*指针以实现连锁赋值
catch 11 operator =处理自我赋值
catch 12 拷贝构造和operator =自行编写时不要放过类的每个成员的覆盖,包含基类的成员
资源管理
catch 13 以对象管理资源 (用于代替)
资源管理时使用RAII对象,他们在构造函数中获取资源并在析构函数中释放资源,以防止动态分配的对象在delete环节被横插一杠,导致内存泄漏,确保大部分申请的资源总是能被释放。常用的RAII有auto_ptr 以及shared_ptr(智能指针)
catch 15 资源管理类对原始资源的访问(显式转换和隐式转换):get()
catch 16 new和delete形式统一
new一个空间时new std::string与new std::string[]对应要保证delete和delete []保持高度统一;同样的typedef的new也要用对应delete形式(或者可以不要常用typedef数组以免自己delete的时候忘记)
设计与声明:考虑class设计的细节
catch 18 避免接口被客户错误使用:接口一致性,内置行为兼容;
catch 19 像type一样去设计类
catch 20 以const reference传递常引用代替value传递:value传递本质是由copy构造函数实现的,在某些方面效率不高,这些规则不适用于内置类型以及STL 迭代器和函数对象
catch 21 函数返回值:用返回对象本身去代替 返回指针或者引用
catch 22 成员变量尽量用private替代protected和public:public意味着不封装,不封装几乎意味着不可改变;而protected的封装性不比public好
实现
catch 27 少写转型
catch 29 努力做到异常安全