2013-08-23 14 views
0

就像标题所说,例如具有虚函数的8个派生类是否比2个派生类更影响性能?如果是这样,差异可以忽略不计?虚拟函数的代价是否随着继承树中类的数量而增加?

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

在此先感谢。

+2

“成本”是每个对象的vtable的大小,但就性能而言,它应该没有什么区别,因为一旦vtable被初始化,它只是一个简单的数组查找。 –

+0

我确实认为它通常被实现,所以对继承的数量没有惩罚。 –

回答

1

C++中动态分派的常见实现是通过一个虚拟表,它基本上是一个指向函数的指针数组,对于这个类型中的每个虚函数都是一个指针。继承链的长度并不重要,因为vtable仅保存一个指针,而在完整对象中则是该特定函数的最终覆盖。无论最终的覆盖是在底层还是在一百层以上,它将是一种单一的间接方式。

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

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

您明确提到您对虚拟继承没有兴趣,我将跳过复杂的进一步解释。以上所有内容都已经有所简化,但希望您能明白这一点。继承链的高度并不重要,宽度可以有一个非常小的影响(额外的跳跃和一个额外的,或一些类似的成本,具体取决于实施方式)

如果您有兴趣,我建议您选择高达C++的由李普曼对象模型,即使这本书是15岁以上,并含有错别字等等,它描述了许多的问题,在实施上的一些解决方案的对象模型和评论。

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