CRTP 避免代码重复
在示例访问者模式提供了一个引人注目用例为 CRTP:
struct IShape
{
virtual ~IShape() = default;
virtual void accept(IShapeVisitor&) const = 0;
};
struct Circle : IShape
{
// ...
// Each shape has to implement this method the same way
void accept(IShapeVisitor& visitor) const override { visitor.visit(*this); }
// ...
};
struct Square : IShape
{
// ...
// Each shape has to implement this method the same way
void accept(IShapeVisitor& visitor) const override { visitor.visit(*this); }
// ...
};
IShape
的每个子类型都需要以相同的方式实现相同的功能。这是一个额外的打字。相反,我们可以在层次结构中引入一个新类型,为我们执行此操作:
template <class Derived>
struct IShapeAcceptor : IShape {
void accept(IShapeVisitor& visitor) const override {
// visit with our exact type
visitor.visit(*static_cast<Derived const*>(this));
}
};
现在,每个形状只需要从接受者继承:
struct Circle : IShapeAcceptor<Circle>
{
Circle(const Point& center, double radius) : center(center), radius(radius) {}
Point center;
double radius;
};
struct Square : IShapeAcceptor<Square>
{
Square(const Point& topLeft, double sideLength) : topLeft(topLeft), sideLength(sideLength) {}
Point topLeft;
double sideLength;
};
不需要重复的代码。