【问题标题】:Way to remove visitor pattern redundancy?消除访客模式冗余的方法?
【发布时间】:2019-10-22 05:22:15
【问题描述】:

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

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 引用特定的派生类指针而无需强制转换?

【问题讨论】:

  • 如果派生类的行为方式与基类完全相同,那么它是多余的,你可以去掉它。如果他们不这样做,那么这不是多余的。如果它们不同,请不要忘记 virtual 关键字。
  • @user4581301 问题是 this 必须是 derved* 而不是 object* 类型。
  • 访问者模式应该适用于任何类型的组合。为什么仅仅因为您使用派生类就期望它的工作方式有所不同?

标签: c++ design-patterns visitor-pattern


【解决方案1】:

*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>
    {};

【讨论】:

    猜你喜欢
    • 2011-03-13
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    • 1970-01-01
    相关资源
    最近更新 更多