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

Xeo*_*Xeo 5 language-agnostic virtual

最流行的方式(或者我听说过)似乎是一个虚拟的桌子,但还有其他的选择吗?

这个问题的答案提供了一些例子,比如在运行时遍历层次结构或将对象的地址映射到更大的信息表,但问题是C++特定的,尽管答案大多不是.

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

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

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

dth*_*rpe 8

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

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

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

动态方法表实际上是传统vtable和消息传递的混合.纯消息传递通常很少或不期望参数对于调用是什么.Windows WndProc是消息传递的一个示例,替换窗口句柄的wndproc指针是挂钩或覆盖默认行为的方法.WndProc具有固定的参数结构,所有消息必须在其中找到附加其特定参数数据的方法.

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

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