确定性时的虚函数开销(c ++)

bis*_*bis 5 c++ polymorphism

我知道虚函数本质上是包含在vtable上的函数指针,这使得多态调用由于间接等而变慢.但是当调用是确定性的时候我想知道编译器优化.确定性,我指的是以下情况:

  1. 对象是值而不是引用,因此不存在多态:
struct Foo
{
    virtual void DoSomething(){....}
};

int main()
{
    Foo myfoo;
    myfoo.DoSemthing();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
  1. 参考是一个没有孩子的类:
struct Foo
{
    virtual void DoSomething();
};
struct Bar : public Foo
{
   virtual void DoSomething();
};

int main()
{
    Foo* a = new Foo();
    a->DoSomething(); //Overhead ? a doesn't seem to be able to change nature.

    Foo* b = new Bar();
    b->DoSomething(); //Overhead ? It's a polymorphic call, but b's nature is deterministic.

    Bar* c = new Bar();
    c->DoSomething(); //Overhead ? It is NOT possible to have an other version of the method than Bar::DoSomething
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Yam*_*vic 9

在第一种情况下,这不是虚拟呼叫.编译器将直接发出呼叫Foo::DoSomething().

在第二种情况下,它更复杂.首先,它是最佳的链接时间优化,因为对于特定的转换单元,编译器不知道还有谁可能从该类继承.您遇到的另一个问题是共享库,如果没有您的可执行文件知道任何相关内容,它们也可能继承.

但总的来说,这种编译器优化称为虚函数调用消除虚拟化,并且在某种程度上是一个活跃的研究领域.有些编译器在某种程度上做到了,有些编译器根本没做.

参见GCC(g ++)-fdevirtualize-fdevirtualize-speculatively.这些名字暗示着保证的质量水平.