c++中的虛函式的作用主要是實現了多型的機制。關於多型,簡而言之就是用父型別別的指標指向其子類的例項,然後通過父類的指標呼叫實際子類的成員函式。這種技術可以讓父類的指標有「多種形態」,這是一種泛型技術。
虛函式的作用是實現動態聯編,也就是在程式的執行階段動態地選擇合適的成員函式。當程式發現虛函式名前的關鍵字virtual後,會自動將其作為動態聯編處理,即在程式執行時動態地選擇合適的成員。
c++的虛函式(virtual function)是通過一張虛函式表(virtual table)來實現的。簡稱為v-table。 在這個表中,主是要乙個類的虛函式的位址表,這張表解決了繼承、覆蓋的問題,保證其真實反應實際的函式。這樣,在有虛函式的類的例項中這個表被分配在了這個例項的記憶體中,所以,當我們用父類的指標來操作乙個子類的時候,這張虛函式表就顯得由為重要了,它就像乙個地圖一樣,指明了實際所應該呼叫的函式。
如果乙個類中含有虛函式,則系統會為這個類分配乙個指標成員指向一張虛函式表(vtbl),表中每一項指向乙個虛函式的位址,實現上就是乙個函式指標的陣列。
虛函式表既有繼承性,又有多型性。每個派生類的vtbl繼承了它各個基類的vtbl,如果基類vtbl中包含某一項,則派生類的vtbl中也將包含同樣的一項,但是兩項的值可能不同。如果派生類覆蓋了該項對應的虛函式,則派生類vtbl的該指標先指向過載後的虛函式,沒有過載的話,則沿用基類的值。
在類物件的記憶體布局中,首先是該類的vtbl指標,然後才是物件資料。在通過物件指標呼叫乙個虛函式時,編譯器生成的**將先獲取物件類的vtbl指標,然後呼叫vtbl中對應的項。對於通過物件指標呼叫的情況,在編譯期間無法確定指標指向的是基類物件還是派生類物件,或者是哪個派生類的物件。但是在執行期間執行到呼叫語句時,這一點已經確定,編譯後的呼叫**能夠根據具體物件獲取正確的vtbl,呼叫正確地虛函式,從而實現多型性。
c++在基類中宣告乙個帶關鍵字virtual的函式,這個函式叫虛函式;它可以在該基類的派生類中被重新定義並被賦予另外一種處理功能。通過指向指向派生類的基類指標或引用呼叫虛函式,編譯器可以根據指向物件的型別在執行時決定呼叫的目標函式。這就實現了多型。
虛函式實現機制
說到虛函式的實現方法,我們就不得不說到動態聯編 dynamic binding 和靜態聯編 static binding 靜態聯編意味著編譯器能夠直接將識別符號和儲存的實體地址聯絡在一起。每乙個函式都有乙個唯一的實體地址,當編譯器遇到乙個函式呼叫時,它將用乙個機械語言說明來替代函式呼叫,用來告訴cp...
虛函式的實現機制
將函式宣告為virtual時,在背後發生了什麼呢?編譯器在編譯的時候,發現animal類中有虛函式,此時編譯器會為每個包含虛函式的類建立乙個虛表 即vtable 該表是乙個一維陣列,在這個陣列中存放每個虛函式的位址。對於例1 2的程式,animal和fish類都包含了乙個虛函式breathe 因此編...
C 虛函式實現機制
看完之後,對c 中的虛函式實現機制算的上是恍然大悟,但是個人感覺博文中有幾點不足之處,現在一一枚舉,以下語言僅僅代表個人看法 1.定位虛表的方式 大家都知道含有虛函式的類的例項裡面前4個位元組是虛函式指標占用的記憶體,裡面填充的是虛函式表的位址號。原博文中通過乙個long型別的物件取得前四個位元組的...