CppCoreGuidelines C.130 多态类的深拷贝,建议使用虚clone函数,而不要用公开的拷贝构造赋值函数
14 December 2022
C.130: For making deep copies of polymorphic classes prefer a virtual clone function instead of public copy construction/assignment
理由
不建议进行多态类的拷贝,因为这样会导致切片问题(slicing problem),参考 C.67。如果你确实需要拷贝语义,请进行深拷贝:提供一个虚的 clone 函数,该函数对继承链末端的类型进行实际拷贝,并返回一个指向新对象的所有权指针(owing pointer),并且在继承类返回共变式( covariant )继承类型。
例子
class B { public: B() = default; virtual ~B() = default; virtual gsl::owner<B*> clone() const = 0; protected: B(const B&) = default; B& operator=(const B&) = default; B(B&&) = default; B& operator=(B&&) = default; // ... }; class D : public B { public: gsl::owner<D*> clone() const override { return new D{*this}; }; };
一般来说,建议使用智能指针表示所有权(参考R.20)。但是,根据语言规则,共变式( covariant )返回类型不能是智能指针:当 B::clone
返回
unique_ptr<B>
的时候D::clone
不能返回unique_ptr<D>
。因此,要么你在所有的重载函数中,始终如一地返回unique_ptr<B>
,要么使用 Guidelines
Support Library 中的owner<>
工具。