What is Single and Double Dispatch?

好久不见. 提交于 2019-12-01 03:58:18

In short, single dispatch is when a method is polymorphic on the type of one parameter (including the implicit this). Double dispatch is polymorphism on two parameters.

The typical example for the first one is a standard virtual method, which is polymorphic on the containing object's type. And the second one can be implemented via the Visitor pattern.

[update] I assume that in your example, floppyDisk, processor and computer each inherit from a common base class which defines accept as a virtual method. Similarly, the visit* methods should be declared virtual in equipmentVisitor, which should have some derived classes with different visit* implementations. [/update]

Assuming the above, accept is polymorphic on both this and equipmentVisitor. The floppydisk, processor and computer each have their own implementation of accept, so when the visitor calls accept, the cal is dispatched based on the type of the callee. Then the callee calls back the visitor's type specific visit method, and this call is dispatched based on the actual type of the visitor.

In theory there can be triple, quadruple etc. dispatch too, although I have never seen this implemented in practice (in languages that don't support double and higher dispatches by nature, that is - I seem to remember that Smalltalk does?). Double dispatch using Visitor in C++ and similar languages is already quite mind-boggling in itself, so the implementation of triple and higher dispatches would simply be too complicated to be used in real applications.

In your example, you are missing the basics of the mechanism: inheritance and virtuality. Let's assume the following class hierarchy, in addition to your code:

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

Now, imagine you have this piece of code in some function:

equipmentVisited* visited;
equipmentVisitor* visitor;
// ...
// Here you initialise visited and visitor in any convenient way
// ...
visited->accept(visitor);

Thanks to the double dispatch mechanism, this last line allows any equipmentVisited to accept any equipmentVisitor, no matter what their actual static types are. Eventually, the right function will be called for the right class.

To summarise:

  • The first dispatch calls accept() on the appropriate class
  • The second dispatch calls the appropriate function on the class selected by the first dispatch
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!