如果已知类类型,是否使用虚拟调度?

时间:2015-09-08 15:56:45

标签: c++ gcc clang vtable

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

最后,假设您使用本地范围创建了类B的对象,并调用此虚方法。

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

在这种情况下是否会使用虚拟调度,否则会被绕过?这适用于普通(非内联)方法吗?

我对gcc / clang感兴趣。

1 个答案:

答案 0 :(得分:4)

由于堆栈和vtable都是实现细节,因此最好用它来表达:

  

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

答案是:是的。编译器知道将在何处使用虚拟方法的版本,它只能发出一个定期的静态调度函数调用。

请注意,有些地方您可能期望编译器知道对象的运行时类型并且被误认为 - 特别是在构造函数内部。

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