假设我们的基类A
至少有一个虚方法。假设我们有另一个类B
,它派生自A
,可能会或可能不会覆盖此虚拟方法。
最后,假设您使用本地范围创建了类B
的对象,并调用此虚方法。
从C ++文档我们知道,如果内联这个虚方法,将使用内联版本,因为类类型是已知的,这不是指针或引用,而是类本身。
在这种情况下是否会使用虚拟调度,否则会被绕过?这适用于普通(非内联)方法吗?
我对gcc / clang感兴趣。
答案 0 :(得分:4)
由于堆栈和vtable都是实现细节,因此最好用它来表达:
如果对象的(真实的,运行时的)类型是静态已知的,编译器是否可以使用静态 - 而不是虚拟 - ?
答案是:是的。编译器知道将在何处使用虚拟方法的版本,它只能发出一个定期的静态调度函数调用。
请注意,有些地方您可能期望编译器知道对象的运行时类型并且被误认为 - 特别是在构造函数内部。
如果您想知道特定编译器是否为某些特定代码(在特定优化级别)发出此特定优化,请检查程序集输出。即使您不确定两个版本的调用应该是什么样的,您也可以将输出与简单和完全限定的调用(b.B::foo() vs b.foo()
)进行比较。在这种情况下,我希望gcc和clang做一个合理的工作,但这很容易检查。