问题标签 [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.
c++ - C++ 双重调度问题
这是我之前问过的一个问题的第 2 部分:是否可以在 C++ 中进行多态成员重载?
使用 Wiki 示例我创建了这个示例。 http://en.wikipedia.org/wiki/Double_dispatch
我的问题是编译后的代码从不查找 vtable,并且总是使用基类而不是继承类。这是我的代码:
但是,输出始终是:
非常感谢您对这个谜团的任何帮助。
java - Java中的多态调度
在下文中,我希望 EventHandler 以一种方式处理 EventA,以另一种方式处理 EventB,并以另一种方式处理任何其他事件(EventC、EventD)。EventReceiver 仅接收对 Event 的引用并调用 EventHandler.handle()。当然,总是被调用的版本是 EventHandler.handle(Event event)。
在不使用 instanceOf 的情况下,有没有办法多态地分派(可能通过 EventHandler 或泛型中的另一个方法)到适当的句柄方法?
c++ - 双重调度产生“隐藏虚拟功能”警告,为什么?
我想实现两个对象之间的交互,其类型派生自一个公共基类。存在默认交互,一旦相同类型的对象交互,可能会发生特定的事情。这是使用以下双重调度方案实现的:
不幸的是,关于这段代码,我有两个完全不同的问题:
- 你认为这是一个合理的方法吗?你会建议一些不同的东西吗?
- 如果我省略前两种
B
方法,我会收到编译器警告和最后两种B
方法隐藏A
方法的错误。这是为什么?指针不A*
应该转换为B*
指针,还是应该转换?
更新:我刚刚发现添加
使错误和警告消失,但为什么这是必要的?
更新 2:这在此处得到了巧妙的解释:http: //www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9,谢谢。我的第一个问题呢?对此方法有何评论?
c++ - 在不知道完整层次结构的情况下双重调度
我想在 C++ 中实现以下内容:
我希望有一堆单个类的子类,它们能够调用一个函数,该函数采用任何这些类型的一对对象。如果将相同派生类型的两个对象用作参数,则应该有一个为混合类型或基类型调用的通用实现和一个专门的实现。
据我所知,这是双分派的经典应用。但是,我有以下限制:
必须可以从现有类派生新类并为这些新类添加新的配对函数,而无需更改现有类,例如在外部库中。
我在上一个问题中提出的方法是错误的,那里提出的解决方案仅适用于编写基类时已知的类型。
关于如何实现这一点的任何建议?这甚至可能吗?
更新:代码说了一千多个字。以下方法有效:
但它需要了解B
何时实施A
。有没有更好的办法?
c++ - std::shared_ptr 和双重回调
我有一些逻辑,我将 std::shared_ptrs 用于继承层次结构中的对象。有一次我需要根据它们的真实类型来处理这些对象,所以我使用了双重调度(即我调用基类上的一个方法,然后它又调用另一个具有真实类型的对象上的方法,参见例如GoF 中的访问者模式)。
现在,我可以传递对具有正确类型或副本的对象的引用。出于多种原因,副本是不可能的。引用通常没问题,因为调用发生在 shared_ptr 所在的范围之下,因此在调用发生时它不会被破坏。但是对于某些子类型,我需要将对象存储在 STL 容器中,因此我需要绝对确定它不会被破坏。显然,裸指针或新的 shared_ptrs 在这里不起作用,所以我需要获取对调用 this 的 shared_ptr 的引用。
现在我正在做以下事情:我使用命名构造函数而不是真实的构造函数来创建对象。这会在对象内部设置一个 weak_ptr 并给出一个 shared_ptr 以供对象使用。当双重回调发生时,我从 weak_ptr 获得一个新的 shared_ptr 并将其存储在 Container 中,因此对象不会被破坏。然而,这使我的构造逻辑非常难看。
有没有更好的方法来做到这一点?
c++ - 尝试使用模板双重调度物理碰撞
我想让编译器为物理碰撞系统建立函数连接。我有测试碰撞功能:
然后我使用一个对撞机对象来保存碰撞对象。
我为效果函数添加了一个间接级别
我最终想要的是一种在具有正确函数签名但不需要不会命中的类型的任何对象中调用函数的方法。
请注意,我不希望有一个墙撞墙的功能。我只想为应该发生的交互编写或提供函数。我知道这不起作用,因为 VictimEffect 没有“看到”派生函数。
我想分派而不必在使用它们的任何地方指定模板参数。我想在可碰撞之外构建我的可碰撞效果,并将其一般地赋予可碰撞对象。我不想为每个可以碰撞的事物集合使用不同的可碰撞对象。基本上我想要
我在这里需要更多的间接层,但我看不到它。我知道这是可以做到的,因为所有信息在编译时都可用。不需要动态多态解决方案。
任何帮助是极大的赞赏!
更新 我想做的是建立我自己的现代(如安德烈的书)游戏库。到目前为止,我已经解决了大部分关系,但这一个让我难过。这不是时间关键问题,而是结果关键问题。我从事游戏工作很多年了,我不喜欢我从事过的任何游戏引擎。这意味着易于使用且易于扩展。既然控制台编译器变得不那么糟糕,它就可以在任何平台上运行。
这是我想要写的一个简单的例子。
所有的物理都是在制品,不是我希望它结束的地方,但它正在到达那里。System object 初始化 Windows 和平台特定的渲染器。在这种情况下,它是 openGL。尽管它被编译为控制台应用程序,但它会创建所有 Windows 组件。我不想让人们处理 main() 与 winmain()。除了物理,没有继承。在我将场景导入系统后,三个渲染调用将被替换为一个。我计划使用我不久前写的东西,结合 Gary Powell 和 Martin Weiser 的 View 模板库。
我知道我只是看不对。访客可以帮助改变我的方法。
所以这就是我想要做的。
更新 2 好的。到目前为止,我已经从评论和答案中获得了一些灵感,这就是我去的地方,但我还没有完成。
然后使用它我这样做
无所不在是对的。通过传入基础,我丢失了类型信息。现在基地在那里只是为了捕捉我不关心的东西。
对于我的容器,我认为我可以使用类型列表来收集添加到容器中的每种类型,并使用它来声明类型特定的容器,然后处理信息。一个问题是我不能取出普通的迭代器,传递函数对象会更容易。
也许 C++ 0X 可以帮助解决这个新的未知类型变量。(我忘记它叫什么了)。
c++ - 存储 std::shared_ptr 的向量其中 Foo 是一个模板类
我有一个基类,我制作了一个模板,因为我想改变几个函数所需的类型,但我想从这些模板化的基类派生。我想存储这些类的向量。我的想法是在层次结构中的所有内容之上创建一个非模板化基类,并使用双重调度来确定类型。我这样做是“正确的方式”吗?
这是该场景的代码片段:
// 以及许多来自 Foo、Foo 的派生类
然后在另一个班级
我只是不知道这是否是“最好的”方法。我可以使用 dynamic_casting,但感觉很脏。那么这是解决这种情况的可靠方法吗?请告知(我希望我没有在示例中留下任何明显的语法错误)
(删除编辑,是我的愚蠢错误)
c++ - 在 C++ 中使用两个类层次结构实现双重分派
我想创建一个具有事件(浅)层次结构的事件调度系统,可以通过 EventObservers 的(浅)层次结构观察。我认为双重调度将允许各种各样的事件和事件观察者,而不必为每个组合都提供一个函数。
我有这样的代码:
然后定义几个测试类:
(这一切都遵循C++ 中的 Double dispatch/multimethods和Wikipedia article on double dispatch)
现在当我调试双重调度时,调用beObservedBy
了派生Event类(EventA
比如说)的方法,并使用了派生EventObserver类,但是observe( BaseEvent* )
调用的是函数而不是observe( EventA* )
我做错了吗?我尝试使用引用而不是指针,但没有得到爱。
c++ - 给定抽象基类 X,如何创建另一个模板类 D其中 T 是从 X 派生的类的类型?
我希望能够接受一个Message&
引用 aMessage1
或Message2
class 的对象。我希望能够创建一个MessageWithData<Message1>
或MessageWithData<Message2>
基于Message&
对象的底层类型。例如,见下文:
messageWithData 类本质上包含从 Message 继承的方法,这些方法允许根据其类型动态地将其双重分派回处理程序。到目前为止,我最好的解决方案是将数据与消息类型分开,并一直通过动态调度链传递它,但我希望更接近动态双重调度的真正习惯,其中消息类型包含可变数据。
(我或多或少遵循的方法来自http://jogear.net/dynamic-double-dispatch-and-templates)