虚函数的成本是否随继承树中的类数量而增加?

时间:2013-08-23 00:07:13

标签: c++ performance inheritance virtual-functions

就像标题所说,例如8个具有虚函数的派生类是否会影响性能而不是2个派生类?如果是这样,差异可以忽略不计吗?

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

提前致谢。

1 个答案:

答案 0 :(得分:1)

C ++中动态分派的常见实现是通过一个虚拟表,它基本上是一个指向函数的指针数组,一个用于该类型中的每个虚函数。继承链的长度无关紧要,因为vtable只保存一个指针,即整个对象中该特定函数的最终覆盖指针。无论最终的覆盖是在底层还是在100级,它都将是一个单独的间接。

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

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

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

如果您有兴趣,我建议您选择Lippman的 C ++对象模型。即使这本书超过15年,并且包含拼写错误等,它描述了实现对象模型的许多问题以及对某些解决方案的评论。

[*]使用空基优化,这将成为所有空基的第一个非空基。