C++虛函數(shù)的實現(xiàn)機制分析
本文針對C++的虛函數(shù)的實現(xiàn)機制進行較為深入的分析,具體如下:
1、簡單地說,虛函數(shù)是通過虛函數(shù)表實現(xiàn)的。那么,什么是虛函數(shù)表呢?
事實上,如果一個類中含有虛函數(shù),則系統(tǒng)會為這個類分配一個指針成員指向一張?zhí)摵瘮?shù)表(vtbl),表中每一項指向一個虛函數(shù)的地址,實現(xiàn)上就是一個函數(shù)指針的數(shù)組。
例如下面這個例子:
class Parent { public: virtual void foo1() { } virtual void foo1() { } void foo1(); }; class Child1 { public: void foo1() { } void foo3(); }; class Child2 { public: void foo1() {} void foo2() {} void foo3(); };
下面列出了各個類的虛函數(shù)表(vtbl)的內(nèi)容。
Parent類的vtbl:Parent::foo1( )的地址、Parent::foo1( )。
Child1類的vtbl:Child1::foo1( )的地址、Parent::foo1( )。
Child2類的vtbl:Child1::foo1( )的地址、Child2::foo1( )。
2、可以看出,虛函數(shù)表既有繼承性,又有多態(tài)性。每個派生類的vtbl繼承了它各個基類的vtbl,如果基類vtbl中包含某一項,則派生類的vtbl中也將包含同樣的一項,但是兩項的值可能不同。如果派生類覆蓋了該項對應(yīng)的虛函數(shù),則派生類vtbl的該指針先指向重載后的虛函數(shù),沒有重載的話,則沿用基類的值。
3、在類對象的內(nèi)存布局中,首先是該類的vtbl指針,然后才是對象數(shù)據(jù)。在通過對象指針調(diào)用一個虛函數(shù)時,編譯器生成的代碼將先獲取對象類的vtbl指針,然后調(diào)用vtbl中對應(yīng)的項。對于通過對象指針調(diào)用的情況,在編譯期間無法確定指針指向的是基類對象還是派生類對象,或者是哪個派生類的對象。但是在運行期間執(zhí)行到調(diào)用語句時,這一點已經(jīng)確定,編譯后的調(diào)用代碼能夠根據(jù)具體對象獲取正確的vtbl,調(diào)用正確地虛函數(shù),從而實現(xiàn)多態(tài)性。
4、分析一下這里的思想所在:
問題的實質(zhì)是這樣,對于發(fā)出虛函數(shù)調(diào)用的這個對象指針,在編譯期間缺乏更多的信息,而在運行期間具備足夠的信息,但那時已不再進行綁定了,怎么在二者之間做一個過渡呢?
把綁定所需的信息用一種通用的數(shù)據(jù)結(jié)構(gòu)記錄下來,該數(shù)據(jù)結(jié)構(gòu)可以同對象指針相聯(lián)系,在編譯時只需要使用這個數(shù)據(jù)結(jié)構(gòu)進行抽象的綁定,而在運行期間將會得到真正的綁定。這個數(shù)據(jù)結(jié)構(gòu)就是vtbl??梢钥吹?,實現(xiàn)用戶所需的抽象和多態(tài)需要進行后綁定,而編譯器又是通過抽象和多態(tài)實現(xiàn)后綁定的。
相關(guān)文章
c語言求出給定范圍內(nèi)的所有質(zhì)數(shù)
本文主要介紹了c語言求出給定范圍內(nèi)的所有質(zhì)數(shù)的小程序。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04淺談C結(jié)構(gòu)和C++結(jié)構(gòu)之間的區(qū)別
這篇文章主要介紹了淺談C結(jié)構(gòu)和C++結(jié)構(gòu)之間的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2021-04-04c++基礎(chǔ)語法:構(gòu)造函數(shù)與析構(gòu)函數(shù)
構(gòu)造函數(shù)用來構(gòu)造一個對象,主要完成一些初始化工作,如果類中不提供構(gòu)造函數(shù),編譯器會默認的提供一個默認構(gòu)造函數(shù)(參數(shù)為空的構(gòu)造函數(shù)就是默認構(gòu)造函數(shù)) ;析構(gòu)函數(shù)是隱式調(diào)用的,delete對象時候會自動調(diào)用完成對象的清理工作2013-09-09C語言數(shù)據(jù)結(jié)構(gòu)之單鏈表操作詳解
鏈表是一種物理存儲結(jié)構(gòu)上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。本文將和大家一起聊聊C語言中單鏈表的常用操作,感興趣的可以學(xué)習一下2022-07-07