Loki给你一个选择,你可以使用经典GoF描述的Visitor模式,但是,使用这个模式获得效率的同时使你的修改更为麻烦,其实理想的办法是是使用Acyclic模式,当稳定后要优化的时候再改为Cyclic模式。
我这个给一个使用Cyclic模式的完整代码(头文件和名称空间要自己处理)。
class
VA;
class VB;
class VC;
typedef CyclicVisitor < void ,LOKI_TYPELIST_3(VA,VB,VC) > MyVisitor;
class VBase
... {
public:
virtual void Accept(MyVisitor& v) = 0;
public:
virtual void say()...{cout<<"I am base class"<<endl;}
} ;
class VA : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
void say()...{cout<<"I am VA"<<endl;}
} ;
class VB : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
void say()...{cout<<"I am VB"<<endl;}
} ;
class VC : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
//void say(){cout<<"I am VC"<<endl;}
} ;
class ConcretVisitor : public MyVisitor
... {
public:
void Visit(VA& vb)
...{
vb.say();
}
void Visit(VB& vb)
...{
vb.say();
}
void Visit(VC& vb)
...{
vb.say();
}
} ;
int _tmain( int argc, _TCHAR * argv[])
... {
ConcretVisitor cv;
VA va;
VB vb;
VC vc;
va.Accept(cv);
vb.Accept(cv);
vc.Accept(cv);
return 0;
}
class VB;
class VC;
typedef CyclicVisitor < void ,LOKI_TYPELIST_3(VA,VB,VC) > MyVisitor;
class VBase
... {
public:
virtual void Accept(MyVisitor& v) = 0;
public:
virtual void say()...{cout<<"I am base class"<<endl;}
} ;
class VA : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
void say()...{cout<<"I am VA"<<endl;}
} ;
class VB : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
void say()...{cout<<"I am VB"<<endl;}
} ;
class VC : public VBase
... {
public:
LOKI_DEFINE_CYCLIC_VISITABLE(MyVisitor)
public:
//void say(){cout<<"I am VC"<<endl;}
} ;
class ConcretVisitor : public MyVisitor
... {
public:
void Visit(VA& vb)
...{
vb.say();
}
void Visit(VB& vb)
...{
vb.say();
}
void Visit(VC& vb)
...{
vb.say();
}
} ;
int _tmain( int argc, _TCHAR * argv[])
... {
ConcretVisitor cv;
VA va;
VB vb;
VC vc;
va.Accept(cv);
vb.Accept(cv);
vc.Accept(cv);
return 0;
}