当虚拟函数立即标记为final时生成vtable吗?

时间:2015-04-02 13:03:34

标签: c++ vtable

在这篇文章中:Does final imply override?,其中一个答案显示您可以在同一声明中声明函数virtualfinal。给出了一个例子,它可以防止派生类错误地声明具有相同签名的函数,从而避免混淆实际调用哪个函数。

我的问题是,编译器是否仍会为这样的函数生成虚拟表?如果我知道我没有引起vtable运行时开销,我会更频繁地使用这种技术。

1 个答案:

答案 0 :(得分:3)

是!

说实话......

首先,不为函数生成虚拟表;为类型生成虚拟表(每个实例都有一个指向相关虚拟表的指针)。

仅仅因为没有一个函数成员可以被进一步覆盖而忽略整个虚拟表会导致大量问题;例如,当通过指向final的引用引用实例时,生成的二进制文件仍然需要能够查找 Base类型。

唯一可能有意义的是带有虚拟成员的类型,它们都是final且没有基础

/**
 * No members override (as there's no base)
 * and no members may be overridden (as they're
 * all `final`).
 */
struct Foo
{
   virtual void foo() final {}
};

编译器是否会忽略虚拟表?也许。可能不是;为什么要为极端角落场景实现替代的,特殊情况的语义集?

实际上,当你稍后在层次结构中进一步添加新的虚拟成员时,它可能会在一般情况下破坏:

/**
 * Well, this one needs a virtual table...
 * ...and it's probably going to want to
 * point out where Foo::foo() is...?
 */
struct Bar : Foo
{
   virtual void bar() {}
};

合法说话......

除此之外,我无法看到任何证据表明虚拟表格符合ABI标准,至少不在Itanium下:

  

具有虚拟成员函数或虚拟基础的每个类都有一组关联的虚拟表。

final说明符是一个C ++构造,没有ABI支持,禁止这种魔法。

可以证实......

但最终,确定的唯一方法是实际检查编译器生成的代码。