如果 class 类型已知,是否使用虚拟分派?

Is virtual dispatch used if class type is known?

假设我们的基 class A 至少有一个虚拟方法。假设我们有另一个 class B 派生自 A 并且可能会或可能不会覆盖此虚拟方法。

最后,假设您创建了一个 class B 的具有本地作用域的对象,并调用了这个虚方法。

从 C++ 文档我们知道,如果这个虚方法是内联的,将使用内联版本,因为 class 类型是已知的,这不是指针或引用,而是 class本身。

在这种情况下会使用虚拟调度还是会被绕过?这对普通(非内联)方法有效吗?

我对 gcc / clang 感兴趣。

由于堆栈和 vtable 都是实现细节,所以措辞可能更好:

Can the compiler use static - rather than virtual - dispatch if the object's (real, runtime) type is statically known?

答案是:是的。只要编译器确定将使用哪个版本的虚方法,它就可以发出常规的静态调度函数调用。

请注意,有些地方您可能 期望 编译器知道对象的运行时类型,但可能会弄错 - 特别是在构造函数内部。

如果您想知道特定编译器是否针对某些特定代码(在特定优化级别发出此特定优化) ,只需检查程序集输出。即使您不确定调用的两个版本应该是什么样子,您也可以将输出与简单且完全限定的调用 (b.B::foo() vs b.foo()) 进行比较。我希望 gcc 和 clang 在这种情况下能做一个合理的工作,但它很容易检查。