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 clone() const = 0;
};

// This CRTP class implements clone() for Derived
template 
class Shape : public AbstractShape {
public:
    std::unique_ptr clone() const override {
        return std::make_unique(static_castconst&>(*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{};

class Circle : public Shape{};

# 注意,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 does not work because Shape is not a class, but a template needing specialization. A container defined as std::vector*> can only store Circles, not Squares. 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.

# 来源:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern