问题标签 [double-dispatch]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
126 浏览

c# - 双重派送

可能重复:
C# 中的双重分派?

有人可以用C#中的一个简单示例详细解释什么是Double Dispatch 模式吗?

我知道关于这个主题已经有一些关于 SO 的问题,但我不明白反射示例的意义。我相信还有其他场景可以更容易地解释双重调度。

0 投票
1 回答
2360 浏览

c++ - 具有多个可访问参数的 C++ 中的访问者模式

考虑以下层次结构:

和访客类:

通常当重载方法依赖于参数类型时,我使用访问者模式来实现双重调度,但我只有指向基类的指针。

例如:

我认为这是实现双重调度的唯一方法,因为虚拟函数的动态绑定应该只发生在调用方法的对象上,而不是其参数(派生类型)上。

现在我遇到了一个新情况,我需要一种在多个参数上重载的 Visit 方法。像这样的东西:

我不能使用经典的访问者模式解决方案,因为仅在其中一个参数上调用了接受方法。

我的问题是:是否存在任何类似的访问者模式解决方案或类似的东西,我可以在这种情况下使用?(我需要用确切的 2 个参数重载 Visit,不超过 2 个)。

0 投票
3 回答
16206 浏览

c++ - 了解双重调度 C++

我试图了解双重调度是如何工作的。我创建了一个从抽象类 Creature 派生的怪物和战士可以战斗的示例。类 Creature 有方法“fight”,它在派生类中定义,并且在每个派生类中定义了如果战士与战士或怪物等战斗会发生什么。我编写了以下代码:

这会导致编译器错误,我预见到:

ex12_10.cpp:在成员函数'virtual void Monster::fight(Creature&)'中:ex12_10.cpp:17:30:错误:'class Creature'没有名为'fightwho'的成员

ex12_10.cpp:在成员函数'virtual void Warrior::fight(Creature&)'中:ex12_10.cpp:24:29:错误:'class Creature'没有名为'fightwho'的成员</p>

但我不知道如何从这里开始......请帮忙。

0 投票
3 回答
410 浏览

c++ - 在几何库中分离算法和数据(需要三次调度?)

我在设计处理几何的应用程序部分时遇到问题。特别是,我希望有一个层次结构的类和交叉的单独方法。

问题

层次结构将是这样的:

  • 几何学
    • 参数
      • 盒子
      • 领域

相交方法类似于:

这很简单。现在问题出现了,当我想将所有几何图形一起存储在一个结构中时,例如一个std::vector(或 KD-Tree,或其他)。

为此,我需要使用std::vector<Geometry*>. 但是,从这个向量中读取会得到Geometry*对象,因此我无法调用适当的交集函数。

问题示例:

如果我在几何对象中实现算法,问题可以通过访问者和一些非常奇怪的函数调用弹跳来解决。

但是,我想将交集算法保留在几何类之外。原因是:

  • 避免决定哪个应该拥有所有权(例如,你在哪里实现盒子和球体之间的交集,在Box还是在Sphere?)

  • 为了避免使几何对象混乱,可以对几何做所有的事情,这是相当多的(仅举几例:体素化它,计算交叉点,应用构造几何运算符......)。因此,在这里将逻辑与数据分离是非常可取的。

另一方面,我需要有一个层次结构而不是模板,因为对于某些事情,可以抽象出特定的几何图形......(例如,将其存储在 astd::vector或 KD-Tree 或......)。

你会如何解决这个问题?有没有适合这个的设计模式?我尝试查看一些库,但最终我更加困惑,我已经...

最简单的方法(有时使用)是使用 RTTI(或伪造它)和向下转换,但这并不完全可维护......(添加新几何意味着通过所有代码更改大量 switch 语句)。

有什么想法吗?

非常感谢你提前。

0 投票
2 回答
5321 浏览

java - Java示例中的双重调度

我正在阅读关于DD的 Wikipedia 文章,然后跳到最后给出的“Java 中的双重调度和示例”链接。以下 Serializable 示例的描述对我来说似乎相当混乱:

这是描述:

为了序列化A,ObjectOutputStream首先查看该方法是否writeObject( ObjectOutputStream oos)存在。如果是这样,那么它以自身作为参数调用该方法。然后该writeObject方法将调用分派回ObjectOutputStream(从而使其成为双重分派)。在进行这个非常简单的回调时,ObjectOutputStream他说:“我将把你的状态写入这个流的责任委托给你”。在做出这个简单的选择时,ObjectOutputStream它已经从我们的对象中解耦了A。对象A反过来说好的,这是我想写在流上的一些状态。如果该值是一个原始值,那么它可以通过 write 方法的重载来处理。如果没有,则可以在对象图中的下一个级别继续来回,直到所有有用的状态都已放置在流上。

我猜测描述可能会令人困惑,因为所描述的是幕后发生的事情,而不是呈现的代码,否则它似乎没有多大意义。以下是让我感到困惑的部分:

  • ObjectOutputStream首先查看该方法是否writeObject( ObjectOutputStream oos)存在”。为什么ObjectOutputStream需要检查这个方法是否存在,因为它是它自己的方法?
  • “如果是这样,那么它会以自身作为参数调用该方法”。在我看来,它writeObject使用实例A作为参数调用。回到上一项,如果它是用 的实例调用的,为什么还要寻找writeObject带有 arg 的签名?ObjectOutputStreamA
  • writeObject然后该方法将调用分派回ObjectOutputStream(从而使其成为双重分派)”。同样,该writeObject方法属于ObjectOutputStream该类,因此我看不到它是如何“派回的ObjectOutputStream”,因为那似乎是原始目的地。

我只是在这里遗漏了一些基本的东西,还是这是一个写得不好/描述得不好的例子?如果这是一个不好的例子,我想更改 Wikipedia 文章以指向更好的文章,因此请随时提供建议。

谢谢。

0 投票
1 回答
1131 浏览

python - 大多数 Pythonic 双重调度,用于从模型中提取视图信息

我正在使用 PySide 使用 Python 和 Qt 编写桌面应用程序。我需要显示一个树视图,其中顶级项目是与其子项不同类型的对象。具体来说,顶级项目是 Git 存储库,而其子项目是工作树中的目录。

对于存储库,我想显示其路径和当前签出的分支。对于一个目录,我只想显示它的名称。

现在,我通过让我的QAbstractItemModel后代使用isinstance底层模型对象(从internalPointer()方法中检索)并决定如何格式化结果字符串来做到这一点。

我想知道是否有一种更 Pythonic(或者不那么笨重)的方式来进行这种双重调度。

我不想做的是在我的 Git repo 和工作树文件的模型类中为此目的定义一个方法,因为我觉得这会违反 SRP。

任何想法或想法都是最受欢迎的。另外,如果有人能为这个问题想出一个不那么笨拙的标题,请告诉我;)

0 投票
2 回答
519 浏览

java - Java中的双重调度自动化

我有两个接口QueryFilterQuery在示例中是一个用于简化的类,我现在有 1 个查询),我现在想要Query.applyFilter()根据过滤器的真实情况编写函数,即不同的函数和NameFilter每个其他过滤器。DateFilter

我的解决方案如下:

好的,这里我需要modifyQuery()为每个 Filter 类重写实现。

然后,我有如何在 C++ 中避免它的解决方案:我们使用模板并强制转换modifyQuery()

演示

但是我不能在 Java 中使用这个解决方案,因为泛型与模板的操作不同。在 Java 中可以使用什么来避免复制粘贴?

0 投票
2 回答
233 浏览

java - Java中的双重调度

我不确定我是否对双重调度有错误的想法。但这就是我的想法:

由于Javas Single diapatch,我认为Java在运行时将objA正确解析为Achild,而在编译时将参数解析为B。请告诉我哪里弄错了?

0 投票
1 回答
179 浏览

c++ - C ++使用彼此不相关的对象调用双重调度方法

我有一系列形状对象,可以检查它们是否彼此相交(如果任一对象的任何部分与另一个对象重叠,则相交为真)。这对双重分派很有用,因为两个对象的交集可以相对于任何一个对象表示,并且仍然有效且真实。

我最近添加(读作:“尝试添加”)一个 Contains 方法,用于测试一个形状是否完全包含另一个形状。双重分派失败,因为两种不同大小的形状适用于 Intersect 但不适用于 Contains:shape_one是一个大圆圈,shape_two是一个完全由 包围的小圆圈shape_one。该调用shape_one.Contains(shape_two)将返回 true,但shape_two.Contains(shape_one)将返回 false。

有没有办法为这种类型的场景实现双重调度?

(鼓励编辑标题以增加对问题的理解......)

具有双重调度的 Intersects 方法示例:

具有双重分派的 Contains 方法示例:

0 投票
2 回答
725 浏览

c# - 在 C# 中实现双重分派,可扩展函数和对象以对其进行操作

我正在寻找一种方法来实现可以为方法和类扩展的双重调度。

到目前为止,我基本上使用了三种方法:

  • 传统的程序方法非常好switch(容易添加新功能,很难添加新类)
  • 访问者模式(非常相似:容易添加新访问者,很难添加新类)
  • 一个简单的接口方法(容易添加新类,很难添加新功能)

我正在寻找一种无需修改函数或现有类即可添加新函数和新类的方法。

在请求对象/函数的某种组合时,这不应该失败,至少在程序启动后我可以做一次检查之后不会失败。

以下是我目前使用的方法:

传统的程序方法:

传统的面向对象方法(Visitor-Pattern):

简单的界面方法: