2011-04-11 104 views
1

夥計。我已經閱讀了關於內聯和虛函數之間的交互的幾個線程。在大多數情況下,編譯器不會將其視爲內聯。但是,當非虛擬內聯成員函數調用虛函數時,該原則是否適用於該場景?說:內聯和虛擬

class ABC{ 
public: 
    void callVirtual(){IAmVitrual();} 
protected: 
    virtual void IAmVirtual(); 
}; 

回答

2

什麼原理?我期望編譯器生成對虛函數的調用。該調用(實際上是跳轉到函數指針)可以內聯,但函數不是。

虛擬函數本身不是inline,並且不調用內聯所需的限定條件,即使它是內聯的,也不能內聯。

0

你的情況callVirtual()將被內聯。任何非虛函數都可以作爲inline的一個很好的候選(顯然最後的決定是編譯器)。

0

虛擬函數必須在虛擬方法表中查找,因此編譯器不能簡單地將它們移動到內聯。這通常是運行時查找。然而,內聯函數可能會調用虛函數,編譯器可以將該調用(代碼在VMT中查找調用)內聯。

2

虛擬函數的重點在於編譯器通常不知道運行時需要哪個派生類實現,或者即使額外派生類將從共享庫動態加載。所以,一般來說,內聯是不可能的。編譯器可以內聯的一種情況是,它恰好知道它處理的是哪種類型,因爲它可以在代碼中看到具體類型,並且不久之後 - 類型沒有改變的機會 - 看到調用虛擬功能。即使如此,它不是要求試圖優化或內聯,它只是唯一的情況下,甚至有可能。

除非事件探查器證明虛擬通話正在扼殺你,否則你不應該試圖與之對抗。然後,首先嚐試對一堆操作進行分組,以便一個虛擬呼叫可以爲您做更多工作。如果虛擬調度仍然太慢,考慮維護某種區分的聯合:它的靈活性和可擴展性要低得多,但可以避免虛函數調用開銷並允許內聯。

假設你真的需要動態分派:一些程序員和系統過度使用虛擬功能,僅僅是因爲OO是20年前的事情,或者他們已經使用了像Java這樣的OO語言。 C++有編譯時多態機制的豐富選擇,包括template