gpt4 book ai didi

language-agnostic - 虚拟或动态调度的合理底层实现是什么?

转载 作者:行者123 更新时间:2023-12-04 17:56:25 27 4
gpt4 key购买 nike

最流行的方式(或者我听说的)似乎是虚拟表,但还有哪些其他选择?

This question的答案提供了一些示例,例如在运行时遍历层次结构或将对象的地址映射到一些更大的信息表,但该问题非常特定于 C++,尽管答案大多不是。

所以,这是一个与语言无关(或者我希望如此)的问题:

除了 vtables 之外,还有哪些其他实现虚拟/动态调度的方法?

请注意,这不是关于速度、易于实现、代码大小等之间的权衡,尽管这些在答案中会非常好。

最佳答案

方法一:扁平化VTable。
一个类类型的所有虚方法(包括继承的方法)都在一个方法指针表中表示,每个虚方法一个。调用需要通过表中固定偏移量处的方法指针进行间接调用。每个新类创建自己的虚表,复制其祖先的虚表,用指向新方法的指针覆盖在类中重写的虚方法的指针,并在表的末尾添加类中定义的新虚方法。

方法 2:链接的 VTable(又名动态方法表)
只有在类类型中声明或覆盖的虚方法才会占用链接虚表中的空间。每个方法都分配了一个id,id和方法指针一起存放在动态方法表中。调用需要扫描动态方法表以查找虚拟方法 id 的匹配项。如果未找到匹配项,则扫描将继续使用类的直接祖先的动态方法表,依此类推,直到找到匹配项或用完祖先。

方法三:消息传递。编译器不会生成正式的方法指针表。相反,每个虚拟方法都被分配了一个唯一的 id 并通过调度函数调用。 dispatch 函数可以是简单的方法 id 上的 case/switch 语句。 Case 块可以调用对象的各个方法,也可以直接实现行为。

动态方法表实际上是传统虚表和消息传递的混合体。纯消息传递通常很少或根本不期望调用的参数是什么。 Windows WndProc 是消息传递的一个示例,替换窗口句柄的 wndproc 指针是 Hook 或覆盖默认行为的方法。 WndProc 有一个固定的参数结构,所有消息都必须找到一种方法来附加它们的特定参数数据。

消息传递的优势在于灵活性,但通常以性能为代价。 VTable 虚拟方法的调度速度非常快(只是间接调用),但一旦建立就非常不灵活。由于每个类 VTable 都包含所有继承的虚方法的插槽,因此 VTable 需要比动态方法表更多的内存,尤其是在深层对象层次结构中。

在 Delphi 编程语言中,虚方法使用 VTables 实现,动态方法使用动态方法表实现,WndProcs 使用消息传递。

关于language-agnostic - 虚拟或动态调度的合理底层实现是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8252485/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com