Loki库里的Acyclic Visitor

已经知道,使用 Visitor有这样那样的不便。Loki为了避免这些提供了两个方案,之一就是Acyclic的类库化。

class  BaseVisitor
{
public:
    
virtual    ~BaseVisitor(){};
}
;

template    
< class  T,typename R  =   void >
class  Visitor
{
public:
    typedef    R    ReturnType;
    
virtual    ReturnType    Visit(T&)    = 0;
}
;

你的访问者必须继承这两个类,具体的情况可能是:

class  MyVisitor
    :
public     BaseVisitor
    ,
public     Visitor < A >
    ,
public     Visitor < B >
{
public:
    
void    Visit(A&);    //visit A
    void    Visit(B&);    //visit B
}

使用起来很简单,记得继承和根据自己的特定类编写特定Visit方法就可以了。对于Visitable:

template     < typename    R  =   void >
class     BaseVisitable
{
public:
    typedef    R    ReturnType;
    
virtual    ~BaseVisitable(){};
    
virtual    ReturnType    Accept(BaseVisitor&)    = 0;
protected:
    template    
<class T>
    
static    ReturnType    AcceptImpl(T& visited,BaseVisitor& guest)
    
{
        
if (Visitor<T>* p = dynamic_cast<Visitor<T>*>(&guest))
        
{
            
return    p->Visit(visited);
        }

        
return    ReturnType();
    }

}
;

#define     DEFINE_VISITABLE()    
    
virtual     ReturnType    Accept(BaseVisitor &  guest)    
    
{return    AcceptImpl(*this,guest);}

你已经猜到,你的Visitable必须继承BaseVisitable,但是,Visit是要动态转换的,这个调用地方必须在子类中,放在基类中动态转换没有任何意义。为了提供侵入用户类的方便手段,loki定义了DEFINE_VISITABLE()宏,如果你对MFC有一定了解的话,你一定会觉得这种手法很熟悉。

当然,侵入宏只是为了只是动态转换,如果你需要,自己写也没什么,你还可以获得应有的自由度。

这样,一般的使用BaseVisitable的方法是:

class  A    : public     BaseVisitable <>
{
public:
    DEFINE_VISITABLE()
}
;

把宏替换为它的定义代码,修改Accept的实现就可以自定义AcceptImpl的行为。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值