nic*_*las 9 c++ design-patterns double-dispatch visitor-pattern
我写了访客模式如下,但我不明白什么是单一和双重调度.AFAIK,单个调度是基于调用者类型调用方法,其中double dispatch根据调用者类型和参数类型调用方法.
我想双重调度是在单个类层次结构中发生的,但是为什么访问者类有两个类层次结构但它仍然被认为是双重调度.
void floppyDisk::accept(equipmentVisitor* visitor)
{
visitor->visitFloppyDisk(this);
}
void processor::accept(equipmentVisitor* visitor)
{
visitor->visitProcessor(this);
}
void computer::accept(equipmentVisitor* visitor)
{
BOOST_FOREACH(equipment* anEquip, cont)
{
anEquip->accept(visitor);
}
visitor->visitComputer(this);
}
void visitFloppyDisk(floppyDisk* );
void visitProcessor(processor* );
void visitComputer(computer* );
Run Code Online (Sandbox Code Playgroud)
请使用我提供的示例代码进行解释.
AFAIK,第一次调度发生在调用accept的对象上,第二次调度发生在调用visit方法的对象上.
谢谢.
简而言之,单个调度是指一个方法在一个参数的类型(包括隐式this)上是多态的.双重调度是两个参数的多态性.
第一个示例的典型示例是标准虚拟方法,它对包含对象的类型具有多态性.第二个可以通过访问者模式实现.
[更新]我假定在你的例子,floppyDisk,processor和computer各自从一个共同的基类定义继承accept作为虚拟方法.类似地,visit*应该将方法声明为virtual in equipmentVisitor,其中应该有一些具有不同visit*实现的派生类.[/更新]
假设上面的,accept是在两个多态this和equipmentVisitor.floppydisk,处理器和计算机都有自己的实现accept,因此当访问者调用时accept,将根据被调用者的类型调度cal.然后被叫方回叫访问者类型特定的访问方法,并根据访问者的实际类型调度此调用.
理论上也可以有三重,四重等调度,虽然我从未见过这在实践中实现过(在不支持双重和更高调度的语言中,就是 - 我似乎记得Smalltalk有吗?).使用C++和类似语言的Visitor进行双重调度本身已经非常令人难以置信,因此三重和更高调度的实现过于复杂,无法在实际应用中使用.
在您的示例中,您缺少该机制的基础知识:继承和虚拟.除了代码之外,我们假设以下类层次结构:
class equipmentVisited
{
virtual void accept(equipmentVisitor* visitor) = 0;
}
class floppyDisk : public equipmentVisited
{
virtual void accept(equipmentVisitor* visitor);
}
class processor : public equipmentVisited
{
virtual void accept(equipmentVisitor* visitor);
}
class computer : public equipmentVisited
{
virtual void accept(equipmentVisitor* visitor);
}
class equipmentVisitor
{
virtual void visitFloppyDisk(floppyDisk* );
virtual void visitProcessor(processor* );
virtual void visitComputer(computer* );
}
// Some additional classes inheriting from equipmentVisitor would be here
Run Code Online (Sandbox Code Playgroud)
现在,想象一下你在某些函数中有这段代码:
equipmentVisited* visited;
equipmentVisitor* visitor;
// ...
// Here you initialise visited and visitor in any convenient way
// ...
visited->accept(visitor);
Run Code Online (Sandbox Code Playgroud)
由于双重调度机制,最后一行允许任何equipmentVisited人接受任何equipmentVisitor,无论他们的实际静态类型是什么.最终,将为正确的类调用正确的函数.
总结一下:
accept()适当的类