0

所以我已经用 C++ 编程了一段时间,有人告诉我,使用动态转换将抽象类指针的指针转换为不同的具体类指针是不好的做法。

Shape* GeneralShape = new Triangle(...);
Triangle* triPtr = dynamic_cast<Triangle*>(GeneralShape);

其中 Shape 是一个抽象类,而 Triangle 继承自它。

当您继承的一个类与抽象类所包含的通用函数有点不同并且需要更多的东西时,使用动态转换似乎是一种访问成员函数的便捷方式。我只是想知道什么是坏的或运行时多态性的开销是什么?

4

1 回答 1

4

虚拟分派的“运行时开销”相当低,除非在紧密循环中,否则可能无关紧要:

  • 查找正确的函数
  • 使用地址间接调用函数
  • 如果 CPU 分支预测器错误预测了调用,则管道停止

dynamic_cast增加了一些额外的开销:

  • 遍历类型继承的运行时表示以获得对象指针的正确调整因子(或失败)。如果继承图不深,这仍然相当快。

更大的成本是在编译时错过了优化机会。特别是在 C++ 中,使用编译时多态性(模板)通常会导致大量内联、循环消除、预计算等。当运行时多态性发挥作用时,这些优化通常是不可能的。

有趣dynamic_cast的是,编译时优化的障碍较小,因为编译器只需要考虑两种情况——转换成功和转换失败,程序员将其编写为两个单独的代码路径,都需要优化。相比之下,使用虚拟调用的“推荐”运行时多态方法更难优化,因为可能的类型集是开放式的。

dynamic_cast为了便于维护(如@user4581301 评论),虚拟呼叫通常优于(或标记和切换),其次是性能考虑。

于 2021-05-03T22:43:20.813 回答