如何消除访客模式冗余?

Way to remove visitor pattern redundancy?

本文关键字:冗余 模式 访客 何消      更新时间:2023-10-16

所以我第一次尝试访问者模式,想知道为什么我必须为每个派生类多次编写 accept 函数。

class object
{
public:
virtual void accept(visitor *v) { v->visit(this); }
// ....
};
class derived : public object
{
public:
void accept(visitor *v) override { v->visit(this); } // redundancy in my eyes!!
// ...
};

我真的必须为每个可访问对象定义该接受函数吗?有没有办法在基类中只写一次,让它引用特定的派生类指针而不必强制转换?

不多余的是*this的类型。在基类中,*this的类型为object。在派生类中,*this的类型为derived。这种差异使访客模式有用。

借助 CRTP,您可以避免在所有派生类中重新实现函数:

class base_acceptor{
public:
virtual void accept(visitor *v) {v->accept(*this);}
};
template<class Derived, class...Bases>
class acceptor_implementer
: public Bases...
{
void accept(visitor *v) override {
assert(dynamic_cast<Derived*>(this)!=nullptr);
v->accept(static_cast<Derived&>(*this));
}
};
class acceptor1
:acceptor_implementer<acceptor1,base_acceptor>
{};
class acceptor2
:acceptor_implementer<acceptor2,base_acceptor>
{};
class acceptor11
:acceptor_implementer<acceptor11,acceptor1>
{};