0
A
回答
1
C++中动态分派的常见实现是通过一个虚拟表,它基本上是一个指向函数的指针数组,对于这个类型中的每个虚函数都是一个指针。继承链的长度并不重要,因为vtable仅保存一个指针,而在完整对象中则是该特定函数的最终覆盖。无论最终的覆盖是在底层还是在一百层以上,它将是一种单一的间接方式。
多继承对性能影响很小,其数量取决于实际实现,但与基数无关。在单继承的情况下,基和派生对象在内存中对齐,指向派生类型的指针的值将具有与转换为指向基类型的指针的相同指针相同的地址。在多重继承的情况下(假设基数不为空),情况并非如此。只有第一个基础[*]可以与整个对象对齐。
缺少对齐的含义是this
指针需要调整指向适当的位置,具体取决于哪个是完整对象中虚拟函数的最终覆盖。一个简单的实现可以在vtable中存储偏移量和函数指针,使用偏移量来调整指针,然后跳转到函数。这意味着每次调用虚拟函数时都会增加(可能为0)this
指针。在现实生活中,编译器通常会存储一个指向函数的指针,该指针指向不需要调整指针的最终覆盖或指向将偏移this
指针并转发到该覆盖的小蹦床函数。
您明确提到您对虚拟继承没有兴趣,我将跳过复杂的进一步解释。以上所有内容都已经有所简化,但希望您能明白这一点。继承链的高度并不重要,宽度可以有一个非常小的影响(额外的跳跃和一个额外的,或一些类似的成本,具体取决于实施方式)
如果您有兴趣,我建议您选择高达C++的由李普曼对象模型,即使这本书是15岁以上,并含有错别字等等,它描述了许多的问题,在实施上的一些解决方案的对象模型和评论。
[*]使用空基优化,这将成为所有空的基地和第一个非空基地。
相关问题
- 1. 虚拟继承和虚函数是否使用相同的vtable?
- 2. 虚拟函数继承
- 3. 虚拟函数,函数重载,继承
- 4. 派生类的成员函数是否继承了基类的虚拟性?
- 5. 继承类是否可以重载其他继承类的虚函数?
- 6. 继承类中的C++虚函数
- 7. 多继承类中的虚函数
- 8. 虚拟继承和在基类空的虚函数表
- 9. 虚拟析构函数是否被继承?
- 10. C++继承虚拟纯函数
- 11. 继承和虚拟成员函数
- 12. 使用非虚拟析构函数从类中私下继承是否安全?
- 13. 平方和中的Kmeans总数是否随群集数量增加而增加?
- 14. 继承虚基类的构造函数
- 15. 继承:子代使用父虚函数而不是自己
- 16. 虚基在虚拟函数表中的偏移为虚拟继承
- 17. 继承虚拟派生类的构造函数。
- 18. 为什么boost :: optional失败继承虚拟函数的类
- 19. 从没有虚拟析构函数的类继承
- 20. 多态性/继承问题与虚拟类的成员函数
- 21. 继承基类成员函数的虚拟说明符
- 22. 非虚拟地使用虚拟继承函数?
- 23. 常量和虚拟继承
- 24. 从基类虚拟继承
- 25. 虚拟类和继承
- 26. 继承虚拟类和非虚类
- 27. 如何从析构函数不是虚拟的基类中正确继承?
- 28. 虚拟继承
- 29. 虚拟继承
- 30. 虚拟继承
“成本”是每个对象的vtable的大小,但就性能而言,它应该没有什么区别,因为一旦vtable被初始化,它只是一个简单的数组查找。 –
我确实认为它通常被实现,所以对继承的数量没有惩罚。 –