CppCoreGuidelines C.22 保持默认操作一致性
10 August 2022
“Make default operations consistent”
理由
默认操作,是一组概念上匹配的操作集。其语义是相关联的。如果 copy/move 构造函数、 copy/move 赋值函数的逻辑行为不一致,会让用户很抓狂。如果构造和析构函数对资源的操作不一致,用户会觉得很惊讶。如果复制和移动操作和构造和析构操作不对应,用户也会很惊讶。
坏例子
class Silly { // BAD: Inconsistent copy operations class Impl { // ... }; shared_ptr<Impl> p; public: Silly(const Silly& a) : p(make_shared<Impl>()) { *p = *a.p; } // deep copy Silly& operator=(const Silly& a) { p = a.p; } // shallow copy // ... };
以上,构造函数和复制构造函数的操作不一致,一个是深复制,一个是浅复制。这会导致误解,产生bug。
强化
- (复杂)复制/移动构造函数与对应的复制/移动赋值函数要在成员变量的同一层级进行读写操作。
- (复杂)任何在复制/移动构造函数中改写的成员变量要在其他构造函数中初始化。
- (复杂)如果复制/移动构造函数对一个成员变量进行深复制,析构函数也应该修改此成员变量。
- (复杂)如果析构函数要修改一个成员变量,这个变量必须是在其他复制/移动构造或赋值函数中修改过。