polymorphic copy construction (CRTP)
有时候我们会需要克隆对象。
如果每个子对象都实现Clone方法,显得冗余。
可以用CRTP实现,省去每个继承对象实现Clone方法的步骤。
// Base class has a pure virtual function for cloning class AbstractShape { public: virtual ~AbstractShape () = default; virtual std::unique_ptr<AbstractShape> clone() const = 0; }; // This CRTP class implements clone() for Derived template <typename Derived> class Shape : public AbstractShape { public: std::unique_ptr<AbstractShape> clone() const override { return std::make_unique<Derived>(static_cast<Derived const&>(*this)); } protected: // We make clear Shape class needs to be inherited Shape() = default; Shape(const Shape&) = default; Shape(Shape&&) = default; }; // Every derived class inherits from CRTP class instead of abstract class class Square : public Shape<Square>{}; class Circle : public Shape<Circle>{};
# 注意,AbstractShape是必要的,因为Shape是放不到Container中的。
One issue with static polymorphism is that without using a general base class like AbstractShape
from the above example, derived classes cannot be stored homogeneously – that is, putting different types derived from the same base class in the same container. For example, a container defined as std::vector<Shape*>
does not work because Shape
is not a class, but a template needing specialization. A container defined as std::vector<Shape<Circle>*>
can only store Circle
s, not Square
s. This is because each of the classes derived from the CRTP base class Shape
is a unique type. A common solution to this problem is to inherit from a shared base class with a virtual destructor, like the AbstractShape
example above, allowing for the creation of a std::vector<AbstractShape*>
.
# 来源:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern