当一个虚函数被立即标记为final时是否生成了一个vtable?

Is a vtable generated when a virtual function is immediately marked final?

在这个 post: 中,其中一个答案表明您可以在同一个声明中声明一个函数 virtualfinal。给出了一个示例,这可以防止 derived 类 错误地声明具有相同签名的函数,从而避免混淆实际调用的函数。

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

是的!

实际说话...

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

仅仅因为一个类型的 none 函数成员可以被进一步重写而删除整个虚拟 table 会导致很多问题;例如,当通过指向 Base.[=18 的指针引用实例时,生成的二进制文件仍然需要能够 find final 类型=]

唯一可能有意义的是具有虚拟成员的类型,它们都是 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 {}
};

那么编译器会省略虚拟 table 吗?可能是。可能不会;为什么要为极端角落场景实施一组替代的、特殊情况的语义?

实际上,在一般情况下,当您稍后在层次结构的更上方添加新的虚拟成员时,它可能无论如何都会中断:

/**
 * 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() {}
};

合法说话...

除此之外,我看不到任何证据表明省略虚拟 table 会符合 ABI,至少在 Itanium:

下不会

Each class that has virtual member functions or virtual bases has an associated set of virtual tables.

final 说明符是一个 C++ 结构只有,没有 ABI 支持,禁止这样的魔术。

说话可验证...

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