2013-08-23 40 views
0

就像標題所說,例如具有虛函數的8個派生類是否比2個派生類更影響性能?如果是這樣,差異可以忽略不計?虛擬函數的代價是否隨着繼承樹中類的數量而增加?

那麼多重繼承(非虛擬繼承)呢?

在此先感謝。

+2

「成本」是每個對象的vtable的大小,但就性能而言,它應該沒有什麼區別,因爲一旦vtable被初始化,它只是一個簡單的數組查找。 –

+0

我確實認爲它通常被實現,所以對繼承的數量沒有懲罰。 –

回答

1

C++中動態分派的常見實現是通過一個虛擬表,它基本上是一個指向函數的指針數組,對於這個類型中的每個虛函數都是一個指針。繼承鏈的長度並不重要,因爲vtable僅保存一個指針,而在完整對象中則是該特定函數的最終覆蓋。無論最終的覆蓋是在底層還是在一百層以上,它將是一種單一的間接方式。

多繼承對性能影響很小,其數量取決於實際實現,但與基數無關。在單繼承的情況下,基和派生對象在內存中對齊,指向派生類型的指針的值將具有與轉換爲指向基類型的指針的相同指針相同的地址。在多重繼承的情況下(假設基數不爲空),情況並非如此。只有第一個基礎[*]可以與整個對象對齊。

缺少對齊的含義是this指針需要調整指向適當的位置,具體取決於哪個是完整對象中虛擬函數的最終覆蓋。一個簡單的實現可以在vtable中存儲偏移量和函數指針,使用偏移量來調整指針,然後跳轉到函數。這意味着每次調用虛擬函數時都會增加(可能爲0)this指針。在現實生活中,編譯器通常會存儲一個指向函數的指針,該指針指向不需要調整指針的最終覆蓋或指向將偏移this指針並轉發到該覆蓋的小蹦牀函數。

您明確提到您對虛擬繼承沒有興趣,我將跳過複雜的進一步解釋。以上所有內容都已經有所簡化,但希望您能明白這一點。繼承鏈的高度並不重要,寬度可以有一個非常小的影響(額外的跳躍和一個額外的,或一些類似的成本,具體取決於實施方式)

如果您有興趣,我建議您選擇高達C++的由李普曼對象模型,即使這本書是15歲以上,並含有錯別字等等,它描述了許多的問題,在實施上的一些解決方案的對象模型和評論。

[*]使用空基優化,這將成爲所有空的基地第一個非空基地。