从 base 转换的派生对象是否需要使用 vtable

Do derived objects cast from base need to use a vtable

本文关键字:vtable 是否 对象 base 转换 派生      更新时间:2023-10-16

如果我在派生类实例上调用继承的方法,代码是否需要使用 vtable?或者方法调用可以是"静态的"(不确定这是否是单词的正确用法)

例如:

Derived derived_instance;
derived_instance.virtual_method_from_base_class();

我正在使用 msvc,但我想大多数主要编译器的实现方式大致相同。

我(现在)意识到该行为是特定于实现的,我对实现感到好奇。

编辑:

应该补充一点,我们感兴趣的原因是该函数被调用了很多次,而且非常简单,并且我不允许以任何方式编辑函数本身,我只是想知道是否有可能,以及消除动态差异是否有任何好处无论如何。

在你们都支持我优化之前,我已经分析和计算了功能等。

您的两个示例都要求Derived有一个接受Base的构造函数并创建一个新的Derived实例。假设您有这样的构造函数并且这是您想要的,那么编译器将"可能"能够静态地确定动态对象类型并避免虚拟调用(如果它决定进行此类优化)。

请注意,该行为不是未定义的,它只是特定于实现的。两者之间存在巨大差异。

如果你想避免创建一个新实例(或者,更有可能的是,这不是你想要的),那么你可以使用引用强制转换static_cast<Derived&>(base_instance).virtual_method_from_base_class();但是虽然这避免了创建新对象,但它不允许你避免虚拟调用。

如果你真的想在编译时强制转换,你正在寻找的很可能是CRTP http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern 它允许你在编译时键入所有内容,避免虚拟调用。

编辑更新的问题:在您现在显示的情况下,我怀疑许多编译器能够静态确定动态类型并避免虚拟调用。

Vtable只有在使用指针或引用时才起作用。对于对象,始终是调用的特定类方法。

您可以简单地限定调用,然后没有虚函数调度:

Derived derived_instance;
derived_instance.Derived::virtual_method_from_base_class();

但是,我怀疑这将是过早的优化

测量