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

C++ 如果类类型已知,是否使用虚拟分派?,c++,gcc,clang,vtable,C++,Gcc,Clang,Vtable,假设我们有至少一个虚方法的基类A。假设我们有另一个类B,它派生自A,可以重写也可以不重写这个虚拟方法 最后,假设您创建了一个具有本地作用域的类B的对象,并调用这个虚拟方法 从C++文档中我们知道,如果这个虚拟方法被内联,则使用内联版本,因为类类型是已知的,这不是指针或引用,而是类本身。 在这种情况下,是使用虚拟分派还是绕过虚拟分派?这对普通(非内联)方法有效吗 我对gcc/clang感兴趣。因为堆栈和vtable都是实现细节,所以最好将其表述为: 如果对象的(真实的、运行时的)类型是静态已知的,

假设我们有至少一个虚方法的基类
A
。假设我们有另一个类
B
,它派生自
A
,可以重写也可以不重写这个虚拟方法

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

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

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


我对gcc/clang感兴趣。

因为堆栈和vtable都是实现细节,所以最好将其表述为:

如果对象的(真实的、运行时的)类型是静态已知的,编译器是否可以使用静态分派而不是虚拟分派

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

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


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

C++没有vtable的概念,这是编译器实现特有的。谢谢。问题用gcc标记更新如果在堆栈上创建了B,那么编译器确切地知道它是什么类型,所以不需要遍历vtable。如果要传递对象,请注意切片问题。检查时,请同时在-O0和-O2处进行。从技术上讲,虚拟化是一种优化。