如果 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 在这种情况下能做一个合理的工作,但它很容易检查。
假设我们的基 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 在这种情况下能做一个合理的工作,但它很容易检查。