我知道虚函数本质上是包含在vtable上的函数指针,这使得多态调用由于间接等而变慢.但是当调用是确定性的时候我想知道编译器优化.确定性,我指的是以下情况:
struct Foo
{
virtual void DoSomething(){....}
};
int main()
{
Foo myfoo;
myfoo.DoSemthing();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
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)
在第一种情况下,这不是虚拟呼叫.编译器将直接发出呼叫Foo::DoSomething().
在第二种情况下,它更复杂.首先,它是最佳的链接时间优化,因为对于特定的转换单元,编译器不知道还有谁可能从该类继承.您遇到的另一个问题是共享库,如果没有您的可执行文件知道任何相关内容,它们也可能继承.
但总的来说,这种编译器优化称为虚函数调用消除或虚拟化,并且在某种程度上是一个活跃的研究领域.有些编译器在某种程度上做到了,有些编译器根本没做.
参见GCC(g ++)-fdevirtualize和-fdevirtualize-speculatively.这些名字暗示着保证的质量水平.