- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最流行的方式(或者我听说的)似乎是虚拟表,但还有哪些其他选择?
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/
我有一个曾经是 TreeView 控件的菜单,但现在我想让每个项目更加直观,并向树中的每个对象添加更多信息。 我的第一个意图是制作一个代表项目的用户控件,并在运行时将它们添加到面板中。这是一个好方法吗
我是 Docker 新手,想知道是否有可能(并且是一个好主意)在 Docker 容器中进行开发。我的意思是创建一个容器,执行 bash,安装和配置我需要的一切,然后开始在容器内进行开发。 容器将成为我
在 Java 中: Parent obj = new Child(); 我创建了一个 Parent 类型的对象。我假设我只能调用父类中定义的方法。因此,我无法调用 Child 中定义的“附加”方法或访
注意:我省略了其他两个阶段(V 和 W)的代码,示例中不需要。 我很确定,我这样处理“开”和“关”时间的方式并不是一种有效的方式。 我想使用查找表实现“开”和“关”脉动。计时器应与表的当前选定值进行比
当代码中包含 Java instanceof 运算符时,许多人会扬起眉毛并说这是禁忌。例如,在这个 other SO Q&A ,答案说: Note that if you have to use th
我是一名优秀的程序员,十分优秀!