在OO编程中,继承的一些负面运行时影响是什么?

时间:2011-10-20 14:38:37

标签: c++ oop inheritance

我知道继承有一些积极的方面,但我不知道继承对运行时的负面影响?谁能告诉我这件事,谢谢!

8 个答案:

答案 0 :(得分:4)

  • 基于大型继承的系统通常使用更多内存并且比基于组合的系统具有更差的数据布局,由于缓存行为的方式,这在速度方面具有运行时成本(您希望所有相关的内容尽可能紧密)。
  • 虚函数调用需要访问虚函数表才能检索正确的函数来调用,由于缓存行为,这可能代价很高,vtable可能远离调用函数。
  • 多重继承会进一步增加虚函数调用的成本,因为首先可能需要计算偏移量才能获得正确的vtable。
  • 如果您正在使用RTTI,那么您通常会在与vtable相关的固定位置看到其他数据。这会影响vtable局部性,再次禁止缓存。

答案 1 :(得分:3)

如果基类包含虚函数,则它的实例及其后代将各自具有指向虚函数表的指针,以一个指针的大小增加其内存占用。与非虚拟功能相比,对虚拟功能的调用将具有额外的间接级别,因此那里的通话时间成本很低。

否则,没有负面影响。从另一个类派生但不使用多态(因此,没有虚函数,总是通过指向派生类的指针调用方法)对没有父类的类没有成本。

更新:我已经解决了继承对性能的影响。其他答案还有更多关于OO正确性的说法。

答案 2 :(得分:1)

唯一的运行时影响可能是内存和速度方面的性能。考虑到功能方面的一切都可以在没有继承的情况下完成,唯一的问题是它的执行效果与替代方案相比。这取决于您要比较的具体方案,以及编译器生成的代码。

答案 3 :(得分:1)

继承可能会对数据位置产生负面影响,当您需要处理大量数据时,这是一个很大的问题。与使用合成时相比,您对数据布局的控制也更少,因此您的对象可能会占用更多内存。

如果你也使用多态,那么你在间接函数调用上会花费额外的周期,并且在引用虚函数表时会得到更糟糕的数据局部性。

通常,面向对象编程的开销很小,而且在处理大量数据时只需要考虑它。查看索尼的Pitfalls of Object Oriented Programming演示文稿 - 从游戏开发者的角度来看它的OOP性能。

答案 4 :(得分:1)

使用继承的好处大大超过了垮台。

第一个缺点是内存中的对象大小,当使用虚函数时,它有一个指向虚函数表的额外指针。

与普通电话相比,虚拟函数调用在程序集中还需要一些额外的步骤。

非虚拟函数调用在性能方面的成本相同。

对象大小也可以作为类A的对象增加,如果A派生自B,则包含来自B的所有信息。当然,使用经过深思熟虑的设计,这不会发生,因为即使没有继承,A也会包含B中的所有信息。

另一个问题是使用dynamic_caststatic_cast,在无继承环境中不会遇到这种问题,但即使使用继承也可以避免这些问题。

答案 5 :(得分:1)

由于您使用C++标记了帖子,我想补充一点,当您在C++中使用虚拟函数时,最重要的运行时影响之一与内联扩展它们的不可能性有关。

事实上,最重的性能影响不是由于虚函数表查找,而是因为即使您将虚拟函数声明为inline,编译器也无法扩展虚函数。这可以防止重要的优化,使您的代码更快。

答案 6 :(得分:1)

在阅读其他(内容丰富的!)回复后,我认为尚未提及一个潜在的负面影响:

继承通常用于实现多态。在C ++中,这意味着您将引用(C ++引用或指针)传递给基类型,而不是按值传递它,以避免slicing problem。实际上,传递引用通常意味着对象的范围不应再定义其生命周期 - 因此人们开始使用动态内存管理(例如,newdelete)。而这个本身可以打开一整套蠕虫。

总而言之:通常,继承与动态内存分配密切相关,这会带来一系列全新的问题。

答案 7 :(得分:0)

我认为继承只会改善运行时。如果你在几个地方重写代码,那么代码必须编译多次。