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

时间:2012-08-08 16:02:23

标签: c++ visual-c++ inheritance compilation

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

例如:

Derived derived_instance;
derived_instance.virtual_method_from_base_class();

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

我(现在)知道这种行为是特定于实现的,我对实现感到好奇。

编辑:

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

在你们全神贯注地讨论光学化之前,我已经分析并计算了函数等等。

3 个答案:

答案 0 :(得分:3)

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

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

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

如果您真的想在编译时进行转换,那么您最需要的是CRTP http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern,它允许您在编译时键入所有内容,从而避免虚拟调用。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

您可以简单地限定呼叫,然后没有虚拟功能调度:

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

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

衡量