2013-07-01 32 views
2
class A{ 
    void virtual a(){} 
}; 
int main() { 
    std::cout<<sizeof(A); 
} 

在上述情況下,爲什麼編譯器沒有使函數變爲非虛擬並保存分配給它的空間。有沒有特定的理由不這樣做?爲什麼編譯器在可能的情況下不能編譯虛擬函數?

我使用gcc 4.7編譯器,如果它是編譯器特定的。

+0

因爲編譯器無法準確確定您是否使用動態分派機制。它不能認爲你只是通過檢查當前的TU。 –

+0

對於一個相關的問題,值得注意的是,現在大多數編譯器可以在編譯時確定虛擬函數的哪個超載被調用時可以內聯虛函數。 – zindorsky

回答

8

因爲您可以在單獨的翻譯模塊中創建派生類。

從理論上講,這可以在鏈接時解決,但這會涉及很多工作,所以在實踐中不會發生(AFAIK)。

+0

對於動態庫,即使LTO也不能排除子類可能會輸入圖片。至少直到LTO被應用到動態連接器上也是如此;-) – delnan

2

編譯器本身可能不會這樣做,因爲它不知道其他文件中的內容。

鏈接器可能能夠做到這一點,但不能保證A的後代版本不存在於某處,並且將被加載到單獨的模塊中。

0

你確定你寫的是真的嗎?您在優化版本中有什麼證明?

我的觀察是,如果程序確實包含創建A的單個實例的代碼,那麼VMT不會與程序鏈接,並且函數(包括虛擬)也不會被使用。

+0

是的,我運行該程序和輸出是8 – banarun

+0

是的,但8是什麼?或者你是否確實意味着爲什麼指向VMT的指針被包含在實例中?如果是這樣,請編輯該問題。 –

+0

不,我的意思是我發佈的內容。無論如何奧利查爾斯沃思已經給出了答案。 – banarun