访问者模式与访问者模式之间的差异双发 [英] Difference betwen Visitor pattern & Double Dispatch

查看:29
本文介绍了访问者模式与访问者模式之间的差异双发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读关于访问者模式的信息,它看起来与 Double Dispatch 相同.两者有什么区别吗.这两个词的意思是一样的.

I am reading about visitor pattern, and it appears the same like Double Dispatch. Is there any difference between the two. Do the two terms means the same thing.

参考:http://www.vincehuston.org/dp/visitor.html

推荐答案

简而言之

它们来自不同的概念,在一些本地不支持双分派的语言中,导致访问者模式作为连接两个(或更多)单分派的一种方式,以便有一个多分派代理.

In short

they come from to different conceptualizations that, in some languages where double dispatch is not natively supported, lead to the visitor pattern as a way to concatenate two (or more) single dispatch in order to have a multi-dispatch surrogate.

多重分派的想法 - 本质上 - 允许像这样的调用

The idea of multiple dispatch is - essentially - allow a call like

void fn(virtual base_a*, virtual base_b*);(注意:不是作为类成员:这不是 C++!)

void fn(virtual base_a*, virtual base_b*); (note: not as a class member: this is NOT C++! )

可以重写为

void fn(virtual derived_a1*, virtual derived_b1*);
void fn(virtual derived_a2*, virtual derived_b1*);
void fn(virtual derived_a1*, virtual derived_b2*);
void fn(virtual derived_a2*, virtual derived_b2*);

这样,在调用时

fn(pa, pb)

调用被重定向到与 papb 的实际运行时类型相匹配的覆盖.(您可以将其推广到任意数量的参数)

the call is redirected to the override that matches the actual runtime type of both pa and pb. (You can generalize this to whatever number of parameters)

在像 C++、C#、Java 这样的语言中,这种机制不存在,运行时类型分派基本上只使用一个参数(只有一个参数,通过使函数本身成为类的成员而隐含在函数中:

In language like C++, C#, Java, this mechanism does not exist and runtime type dispatching basically works with just one parameter (that, being just one, is made implicit in the function by making the function itself member of the class:

换句话说,就是伪代码

void fn(virtual base_a*, base_b*) 

成为(真正的 C++)

becomes the (real C++)

class base_a
{
public:
    virtual void fn(base_b*);
}

注意这里在 base_b 前面没有更多的 virtual,从现在开始是静态的.像这样的电话

Note that here there is no more virtual in front of base_b, that from now is static. A call like

pa->fn(pb) 如果 pa 指向一个衍生_a2 并且 pb 指向一个衍生_b1 将被分派到派生_a2::fn(base_b*),不管里面是否有派生_a2::fn(派生_b1*):不考虑pb指向的对象的运行时类型.

pa->fn(pb) if pa points to a derived_a2 and pb to a derived_b1 will be dispatched to derived_a2::fn(base_b*), no matter if there is a derived_a2::fn(derived_b1*) in there: the run-time type of the object pointed by pb is not taken into account.

访问者模式的想法是您调用一个对象的虚拟分派,该对象调用(最终返回)另一个对象的虚拟分派:

The idea of the visitor patter is that you call the virtual dispatch of an object that calls (eventually back) the virtual dispatch of another:

class base_a
{
public:
   virtual void fn(base_b*)=0;
   virtual void on_visit(derived_b1*)=0;
   virtual void on_visit(derived_b2*)=0;
};

class base_b
{
public:
   virtual void on_call(derived_a1*)=0;
   virtual void on_call(derived_a2*)=0;
};

//forward declarations, to allow pointers free use in other decls.
class derived_a1;
class derived_b1;


class derived_a1: public base_a
{
public:
   virtual void fn(base_b* pb) { pb->on_call(this); }
   virtual void on_visit(derived_b1* p1) { /* useful stuff */ }
   ...
};

class derived_b1: public base_b
{
public:
  virtual void on_call(derived_a1* pa1) { pa1->on_visit(this); }
  ... 
};

现在,像pa->fn(pb)这样的调用,如果pa指向derivative_a1,pb指向derivative_b1,最终会去derived_a1::on_visit(derived_b1*).

now, a call like pa->fn(pb), if pa points to derived_a1 and pb to derived_b1, will finally go to derived_a1::on_visit(derived_b1*).

这篇关于访问者模式与访问者模式之间的差异双发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆