虚函数的成本是否随着继承树中类的数量增加而增加? [英] Does the cost of virtual functions increase with the number of classes in the inheritance tree?

查看:24
本文介绍了虚函数的成本是否随着继承树中类的数量增加而增加?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所说,例如有 8 个带虚函数的派生类是否比有 2 个派生类对性能的影响更大?如果是这样,差异可以忽略不计吗?

Like the title says, e.g. does having 8 derived classes with virtual functions affect performances more than having 2 derived classes? And if so, is the difference negligible?

那么多重继承(非虚拟继承)呢?

And what about multiple inheritance (non virtual inheritance)?

提前致谢.

推荐答案

C++ 中动态调度的常见实现是通过一个虚表,它基本上是一个指向函数的指针数组,每个虚函数对应一个指针.类型.继承链的长度无关紧要,因为 vtable 只保存一个指针,即完整对象中该特定函数的最终覆盖的指针.无论最终的覆盖是在基础还是在它的一百层,这将是一个单一的间接.

The common implementation of dynamic dispatch in C++ is by means of a virtual table, which is basically an array of pointers to functions, one for each virtual function in the type. The length of the inheritance chain does not matter, since the vtable holds only one pointer, that of the final overrider for that particular function in the complete object. It will be a single indirection whether the final overrider is in the base or a hundred levels from it.

多重继承对性能的影响很小,影响的程度取决于实际实现,但与基数无关.在单继承的情况下,基类和派生对象在内存中对齐,即指向派生类型的指针的值与转换为指向基类型的指针的同一指针的地址相同.在多重继承的情况下(假设基数不为空),情况并非如此.只有第一个 base[*] 可以与整个对象对齐.

Multiple inheritance can have a small impact in performance, the amount of which will depend on the actual implementation, but will be independent of the number of bases. In the case of single inheritance the base and the derived object are aligned in memory, that the value of a pointer to the derived type, will have the same address as the same pointer converted to pointer to the base type. In the case of multiple inheritance (assuming that bases are not empty), that is not the case. Only the first base[*] can be aligned with the full object.

缺少对齐的含义是this指针将需要调整以指向适当的位置,具体取决于哪个是完整对象中虚函数的最终覆盖.一个简单的实现可以将偏移量和指向函数的指针都存储在 vtable 中,使用偏移量来调整指针,然后跳转到函数.这意味着每次调用虚函数时都会向 this 指针添加(可能为 0).在现实生活中,编译器通常存储一个指向函数的指针,如果 this 指针不需要调整,则该函数将引用最终覆盖程序或将偏移 的小蹦床函数this 指针并转发到该覆盖程序.

The implication of the lack of alignment is that the this pointer will need to be adjusted to point to the appropriate location, depending on which is the final overrider of the virtual function in the complete object. A naïve implementation could store both the offset and the pointer to the function in the vtable, use the offset to adjust the pointer, then jump to the function. This would imply an addition (of possibly 0) to the this pointer for every call to the virtual function. In real life, compilers usually store a single pointer to function that will refer to either the final overrider if the this pointer does not need to be adjusted or to a small trampoline function that will offset the this pointer and forward to that overrider.

您明确提到您对虚拟继承并不真正感兴趣,我将跳过复杂的进一步解释.以上所有内容已经有点简化,但希望您能理解.继承链的高度无关紧要,宽度可以产生非常小的影响(额外的跳跃和添加,或一些类似的成本,取决于实现.

You explicitly mentioned that you are not really interested in virtual inheritance, and I will skip the complex further explanations. All of the above is already a bit of a simplification, but hopefully you get the idea. The height of the inheritance chain does not matter, the width can have a very small impact (an extra jump and an addition, or some similar costs, depending on the implementation.

如果您有兴趣,我建议您阅读 Lippman 的 The C++ Object Model.即使这本书已经超过 15 年了,并且包含错​​别字等等,它也描述了实现对象模型的许多问题,并对一些解决方案进行了评论.

If you are interested, I recommend that you pick up The C++ Object Model by Lippman. Even if the book is over 15 years old, and contains typos and so forth, it describes many of the issues in implementing the object model and comments on some of the solutions.

[*] 通过空基优化,这成为所有空基第一个非空基.

[*] With the Empty Base Optimization, this becomes all of the empty bases and the first non-empty base.

这篇关于虚函数的成本是否随着继承树中类的数量增加而增加?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆