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 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<AbstractShape*>.

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

posted @ 2022-01-11 17:06  xuyv  阅读(44)  评论(0编辑  收藏  举报