0

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

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

提前致谢。

4

1 回答 1

2

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

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

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

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

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

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

于 2013-08-23T02:17:42.317 回答