C++聯編

聯編
函數的聯編:在編譯或運行將函數調用與相應的函數體連接在一起的過程。
1 先期聯編或靜態聯編:在編譯時就能進行函數聯編稱爲先期聯編或靜態聯編。
2 遲後聯編或動態聯編:在運行時才能進行的聯編稱爲遲後聯編或動態聯編。
那麼聯編與虛函數有什麼關係呢,當然,造成上面例子中的矛盾的原因就是代碼的聯編過程採用了先期聯編,使得編譯時系統無法確定究竟應該調用基類中的函數還是應該調用派生類中的函數,要是能夠採用上面說的遲後聯編就好了,可以在運行時再判斷到底是哪個對象,所以,virtual關鍵字的作用就是提示編譯器進行遲後聯編,告訴連接過程:“我是個虛的,先不要連接我,等運行時再說吧”。
那麼爲什麼連接的時候就知道到底是哪個對象了呢,這就引出虛函數的原理了:當編譯器遇到virtual後,會爲所在的類構造一個表和一個指針,那個表叫做vtbl,每個類都有自己的vtbl,vtbl的作用就是保存自己類中虛函數的地址,我們可以把vtbl形象地看成一個數組,這個數組的每個元素存放的就是虛函數的地址.指針叫做vptr,指向那個表。而這個指針保存在相應的對象當中,也就是說只有創建了對象以後才能找到相應虛函數的地址。
【注意】
1爲確保運行時的多態定義的基類與派生類的虛函數不僅函數名要相同,其返回值及參數都必須相同,否則即使加上了virtual,系統也不進行遲後聯編。
2 虛函數關係通過繼承關係自動傳遞給基類中同名的函數,也就是上例中如果A中print有virtual,那麼 B中的print即使不加virtual,也被自動認爲是虛函數。
*3 沒有繼承關係,多態機制沒有意義,繼承必須是公有繼承。
*4現實中,遠不只我舉的這兩個例子,但是大的原則都是我前面說到的“如果發現一個函數需要在派生類裏有不同的表現,那麼它就應該是虛的”。這句話也可以反過來說:“如果你發現基類提供了虛函數,那麼你最好override它”。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章