在面向对象编程中,继承有哪些负面的运行时影响?

发布于 2024-12-11 07:18:12 字数 50 浏览 0 评论 0原文

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

I know there is some positive aspects of inheritance, but I don't know negative runtime impacts of inheritance? Can anybody tell me about that, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

岁月无声 2024-12-18 07:18:12
  • 基于大型继承的系统通常比基于组合的系统使用更多的内存并且数据布局更差,由于缓存的行为方式,这在速度方面会产生运行时成本(您希望所有相关的内容都尽可能紧密地打包)。
  • 虚拟函数调用需要访问虚拟函数表才能检索要调用的正确函数,由于缓存行为,这可能会导致成本高昂,虚函数表可能距离调用函数很远。
  • 多重继承进一步增加了虚拟函数调用的成本,因为首先可能需要计算偏移量才能获得正确的虚函数表。
  • 如果您使用 RTTI,那么您通常会在与 vtable 相关的固定位置看到其他数据。这会影响 vtable 局部性,从而再次禁止缓存。
  • Large inheritance based systems usually uses more memory and have worse data layout than composition based systems, this has a runtime cost in terms of speed due to how the cache behaves ( you want everything related to be as tightly packed as possible ).
  • Virtual function calls requires a trip to a virtual function table in order to retrieve the correct function to call, this can be costly due to cache behavior, the vtable might be far from the calling function.
  • Multiple inheritance increases the cost of virtual function calls further, as first an offset might need to be computed in order to get the correct vtable.
  • If you're using RTTI, then you'll usually see additional data at a fixed location in relation to the vtable. This affects the vtable locality, which once again prohibits the cache.
烛影斜 2024-12-18 07:18:12

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

否则不会有任何负面影响。从一个类派生另一个类但不使用多态性(因此,没有虚函数,始终通过指向派生类的指针调用方法)与没有父类的类相比没有任何成本。

更新:我已经在这里解决了继承对性能的影响。其他答案对面向对象的正确性有更多的阐述。

If a base class contains virtual functions then instances of it and its descendants will each have a pointer to a virtual function table, increasing their memory footprint by the size of one pointer. Calls to virtual functions will have an extra level of indirection compared to non-virtual functions, so there is a small call time cost there.

Otherwise, there is no negative impact. Deriving one class from another but not using polymorphism (so, no virtual functions, always calling methods through pointers to the derived class) has no cost over a class with no parent.

Update: I have addressed the performance impact of inheritance here. Other answers have more to say on OO-correctness.

宛菡 2024-12-18 07:18:12

使用继承的好处远远超过了缺点。

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

与常规调用相比,虚拟函数调用还需要在汇编中执行一些额外的步骤。

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

如果 A 派生自 B,并且包含来自 B 的所有信息,则对象大小也会随着 A 类的对象而增加代码>.当然,如果经过深思熟虑的设计,这种情况就不会发生,因为即使没有继承,A 也会包含 B 中的所有信息。

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

The benefits of using inheritance greatly outweigh the downfalls.

The first downfall is the object size in memory, which, when using virtual functions, has an extra pointer to the virtual function table.

Virtual function calls also require a few extra steps in the assembly compared to regular calls.

Non-virtual function calls cost the same in terms of performance.

Object size can also increase as an object of class A, if A is derived from B, contains all information from B. Of course, with a well-thought design, this doesn't happen, because even without inheritance, A would contain all information in B.

One more issue would be the use of dynamic_cast or static_cast, which you wouldn't encounter in an inheritance-free environment, but these can also be avoided even using inheritance.

念﹏祤嫣 2024-12-18 07:18:12

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

The only runtime impact could be performance in terms of memory and speed. Considering functionality-wise everything can be done without inheritance, the only question is how well it performs as opposed to the alternatives. That will depend on the specific scenarios you want to compare, and the complier's generated code.

dawn曙光 2024-12-18 07:18:12

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

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

一般来说,面向对象编程的开销成本相当小,只有在处理大量数据时才需要考虑它。查看 Sony 的 面向对象编程的陷阱 演示文稿 — 它着眼于 OOP 性能游戏开发者的视角。

Inheritance can negatively impact data locality, which is a big deal when you have a lot of numbers to crunch. You also get less control over data layout than when you use composition, so your objects might take up more memory.

If you also use polymorphism, then you spend additional cycles on indirect function calls and get even worse data locality, as you reference virtual function tables.

Generally, the overhead cost of object-oriented programming is fairly small and you only have to think about it when you are processing large amounts of data. Check Sony's Pitfalls of Object Oriented Programming presentation — it looks at OOP performance from a game developer's perspective.

骷髅 2024-12-18 07:18:12

在阅读了其他(信息丰富!)的回复后,我相信还没有提到一个潜在的负面影响:

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

长话短说:继承常常与动态内存分配齐头并进,这引发了一系列全新的问题。

After reading the other (informative!) responses, I believe one potential negative impact wasn't mentioned yet:

Inheritance is often used to achieve polymorphy. In C++, this means that you pass references (C++ references or pointers) to the base type around, instead of passing it by value, to avoid the slicing problem. In practice, passing references around often means that the scope of an object should no longer define its life time - so people start using dynamic memory management (say, new and delete). And this can open a whole can of worms itself.

To make a long story short: very often, inheritance goes hand in hand with dynamic memory allocation, which opens a whole new class of issues.

英雄似剑 2024-12-18 07:18:12

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

事实上,对性能影响最大的并不是虚函数表查找,而是因为即使将虚函数声明为内联,编译器也无法扩展它。这会阻止重要的优化,而优化可能会使您的代码更快。

Since you tagged your post with C++, I'd like to add that one of the most important runtime impact when you use virtual function in C++ is related to the impossibility to expand them inline.

In fact, the heaviest performance impact is not due to the virtual function table lookup, but to the fact that the compiler cannot expand a virtual function even if you declare it as inline. This prevents an important optimization that could make your code much faster.

同展鸳鸯锦 2024-12-18 07:18:12

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

I would think inheritance would only improve runtime. If you rewrite the code in several places that code has to be compiled that many times more.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文