例如,为什么没有语言支持来检查vtable?为什么不能用新成员函数代替成员函数?我有种直觉,认为有很多方法可以很好地利用这些功能。

还有其他允许我做这种事情的语言吗?

最佳答案

主要原因是,将vtable保留为实现细节可以允许任何具体实现对其进行适当的优化。这意味着它可以例如如果可以证明给定方法(或所有方法)没有虚拟调用,则完全修剪甚至消除vtable。或者它可以用if-else类型检查代替vtable调度,例如它看到只有几种选择(这可能是有利的,因为分支预测在这种情况下将起作用,但不适用于vtables,并且因为随后可以内联if-else分支)。它可以对vtable中的方法进行重新排序,以使最常用的方法先出现,或者使那些通常一个接一个地调用的方法填充vtable中的相邻插槽以利用缓存。等等等等。当然,所有这些实现都会使vtable布局完全不可预测,因此,如果要(通过语言规范)将vtable布局暴露给实现,则毫无用处。

同样,vtable并不像听起来那么简单。例如,编译器通常必须生成thunk来修复this指针,以解决诸如虚拟继承或与协变返回类型结合在一起的多重继承的问题。这再次是没有“唯一的最佳方法”来做到这一点的(这就是为什么不同的编译器以不同的方式来做到这一点),而对其进行标准化将实际上需要以一种特定的方式来解决。

就是说,“vtable切换”如果作为高级构造公开(因此仍然可以进行优化),则是一种潜在有用的技术。有关示例,请参见UnrealScript,该脚本允许一个人为一个类定义几个states(一个默认值,另一个名为),并覆盖命名状态下的某些方法。派生类可以覆盖现有状态中的更多方法,或者添加自己的状态并在其中覆盖。此外,状态可以扩展其他状态(因此,如果未为特定状态覆盖方法,则该方法将退回到“父”状态,依此类推,直到链达到默认状态为止)。对于 Actor 建模(本质上是游戏),这一切都非常有意义,这就是UnrealScript拥有它的原因。而所有这些显而易见的有效实现机制是vtable切换,每个状态都有一个单独的vtable。

关于c++ - 为什么C++继承机制不透明?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1415779/

10-13 00:01