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被初始化,它只是一個簡單的數組查找。 –
我確實認爲它通常被實現,所以對繼承的數量沒有懲罰。 –