gpt4 book ai didi

c++ - 派生类调用时的虚函数性能?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:21:17 26 4
gpt4 key购买 nike

如果在编译时从已知为派生类的类调用虚拟方法,是否会导致性能下降?下面我使用派生类显式调用 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;
}

最佳答案

Is there a performance penalty when a virtual method is called from a class that's known to be the derived class at compile time? See code below.

这取决于。大多数编译器会像这样“去虚拟化”代码:

Derived1 d;
d.speak();

对象的动态类型在调用点是已知的,因此编译器可以避免通过 vtable 进行调用,而可以直接调用 Derived1::speak()

在您的示例中,编译器需要更智能,因为在 force_speak 中您只有 Derived1* 个指针(存储在 unique_ptr 对象中),并且在该上下文中不清楚指向对象的动态类型是 Derived1 还是更多-派生类型。编译器要么需要将对 force_speak 的调用内联到 main(其中动态类型已知),要么使用一些关于该类型的额外知识来允许去虚拟化发生。 (作为附加知识的一个示例,整个程序优化可以确定在程序中的任何地方没有没有声明其他派生类型,因此 Derived1* 必须 指向 Derived1。)

使用 C++11 final 关键字可以帮助编译器去虚拟化某些情况,例如如果 Derived1 被标记为 final 那么编译器知道 Derived1* 只能指向 Derived1 而不是从它派生的其他类型可能会覆盖 speak()

关于c++ - 派生类调用时的虚函数性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27534970/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com