Agr*_*hak 6 c++ performance virtual function derived-class
从编译时已知为派生类的类调用虚方法时是否存在性能损失?下面我force_speak
用派生类显式调用.
码:
#include <iostream>
#include <array>
#include <memory>
class Base
{
public:
virtual void speak()
{
std::cout << "base" << std::endl;
}
};
class Derived1 : public Base
{
public:
void speak()
{
std::cout << "derived 1" << std::endl;
}
};
template<class B>
void force_speak(std::array<std::unique_ptr<B>, 3>& arr)
{
for (auto& b: arr)
{
b->speak();
}
}
int main()
{
std::array<std::unique_ptr<Derived1>, 3> arr =
{
std::unique_ptr<Derived1>(new Derived1),
std::unique_ptr<Derived1>(new Derived1),
std::unique_ptr<Derived1>(new Derived1)
};
force_speak(arr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
从编译时已知为派生类的类调用虚方法时是否存在性能损失?见下面的代码.
这取决于.大多数编译器会像这样"去虚拟化"代码:
Derived1 d;
d.speak();
Run Code Online (Sandbox Code Playgroud)
对象的动态类型在调用站点是已知的,因此编译器可以避免通过vtable进行调用,并且可以直接调用Derived1::speak()
.
在您的示例中,编译器需要更智能,因为在force_speak
您只有 Derived1*
指针(存储在unique_ptr
对象中)并且在该上下文中,不清楚指向对象的动态类型是否是Derived1
更多派生类型.编译器需要内联调用force_speak
into main
(动态类型已知的地方)或使用有关类型的一些其他知识来允许进行虚拟化.(作为附加知识的一个示例,整个程序优化可以确定在程序中的任何地方都没有声明其他派生类型,因此Derived1*
必须指向a Derived1
.)
使用C++ 11 final
关键字可以帮助编译器对某些情况进行虚拟化,例如,如果Derived1
标记了,final
则编译器知道a Derived1*
只能指向a Derived1
而不是指向可能覆盖的某个其他类型speak()
归档时间: |
|
查看次数: |
404 次 |
最近记录: |