Hei*_*bug 5 c++ double-dispatch visitor
考虑以下层次结构:
class Base
{
virtual void Method() = 0;
virtual void Accept(Visitor *iVisitor) = 0;
};
class Derived1: public Base
{
virtual void Method(){//impl}
virtual void Accept(Visitor *iVisitor)
{
iVisitor->Visit(this);
}
};
class Derived2: public Base
{
virtual void Method(){//impl}
virtual void Accept(Visitor *iVisitor)
{
iVisitor->Visit(this);
}
};
Run Code Online (Sandbox Code Playgroud)
和访客班:
class VisitorInterface
{
virtual void Visit(Derived1 * param);
virtual void Visit(Derived2 * param);
}
class Visitor: public VisitorInterface
{
void Visit(Derived1 * param){}
void Visit(Derived2 * param){}
}
Run Code Online (Sandbox Code Playgroud)
通常我使用访问者模式来实现双重调度,当重载方法取决于参数类型,但我只有指向基类的指针.
例如:
void foo(Visitor *visitorPtr, Base * basePtr)
{
basePtr->Accept(visitorPtr);
}
Run Code Online (Sandbox Code Playgroud)
我认为这是实现双重调度的唯一方法,因为虚函数的动态绑定应仅在调用方法的对象上发生,而不是在其参数(派生类型)上发生.
现在我遇到了一种新情况,我需要在多个参数上进行一种Access方法重载.像这样的东西:
class VisitorInterfaceMultiple
{
virtual void Visit(Derived1 * param1, Derived2 * param2);
virtual void Visit(Derived2 * param1, Derived3 *param2);
}
Run Code Online (Sandbox Code Playgroud)
我不能使用经典的访问者模式解决方案,因为只在其中一个参数上调用accept方法.
我的问题是:确实存在我可以在这种情况下使用的任何类似的访问者模式解决方案或类似的东西吗?(我需要使用精确的2个参数重载访问,不超过2个).
我为你创建了"三重"调度模式:http://ideone.com/FoXNW 这很容易.主要部分如下:
class Derived1;
class Derived2;
class Visitor;
class Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1) = 0;
virtual void Accept(Visitor &iVisitor, Derived1& param2) = 0;
virtual void Accept(Visitor &iVisitor, Derived2& param2) = 0;
};
class Visitor
{
public:
virtual void Visit(Derived1 & param1, Derived1 ¶m2) { cout << "11\n"; }
virtual void Visit(Derived1 & param1, Derived2 ¶m2) { cout << "12\n"; }
virtual void Visit(Derived2 & param1, Derived1 ¶m2) { cout << "21\n"; }
virtual void Visit(Derived2 & param1, Derived2 ¶m2) { cout << "22\n"; }
};
class Derived1: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
class Derived2: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
void Visit(Visitor& visitor, Base& param1, Base& param2)
{
param2.Accept(visitor, param1);
}
Run Code Online (Sandbox Code Playgroud)
请注意,Derived1和Derived2的实现完全相同.如果您有更多派生,可以将其括在宏中.