C++多態性:虛函數的調用原理

來源:互聯網
上載者:User
多態性給我們帶來了好處:多態使得我們可以通過基類的引用或指標來指明一個對象(包含其衍生類別的對象),當調用函數時可以自動判斷調用的是哪個對象的函數。一個函數說明為虛函數,表明在繼承的類中重載這個函數時,當調用這個函數時應當查看以確定調用哪個對象的這個函數。 普通函數的處理:一個特定的函數都會映射到特定的代碼,無論時編譯階段還是串連階段,編譯器都能計算出這個函數的地址,調用即可。 虛函數的處理:被調用的函數不僅依據調用的特定函數,還依據調用的 對象的種類。通常是由虛函數表(vtable)來實現的。虛函數表的結構:它是一個函數指標表,每一個表項都指向一個函數。任何一個包含至少一個虛函數的類都會有這樣一張表。需要注意的是vtable只包含虛函數的指標,沒有函數體。實現上是一個函數指標的數組。虛函數表既有繼承性又有多態性。每個衍生類別的vtable繼承了它各個基類的vtable,如果基類vtable中包含某一項,則其衍生類別的vtable中也將包含同樣的一項,但是兩項的值可能不同。如果衍生類別重載(override)了該項對應的虛函數,則衍生類別vtable的該項指向重載後的虛函數,沒有重載的話,則沿用基類的值。每一個類只有唯一的一個vtable,不是每個對象都有一個vtable,恰恰是每個同一個類的對象都有一個指標,這個指標指向該類的vtable(當然,前提是這個類包含虛函數)。那麼,每個對象只額外增加了一個指標的大小,一般說來是4位元組。

在類對象的記憶體布局中,首先是該類的vtable指標,然後才是對象資料。

在通過對象指標調用一個虛函數時,編譯器產生的程式碼將先擷取對象類的vtable指標,然後調用vtable中對應的項。對於通過對象指標調用的情況,在編譯期間無法確定指標指向的是基類對象還是衍生類別對象,或者是哪個衍生類別的對象(見代碼中的函數f在編譯期間是無法判斷的)。但是在運行期間執行到調用語句時,這一點已經確定,編譯後的調用代碼能夠根據具體對象擷取正確的vtable,調用正確的虛函數,從而實現多態性。

給出執行個體代碼:class A {public :virtual void run (){......}}class B :public A{public: void run(){......}}int f (A *pA){pA->run();}分析一下這裡的思想所在,問題的實質是這樣,對於 發出虛函數調用的這個對象指標, 在編譯期間缺乏更多的資訊,而在運行期間具備足夠的資訊,但那時已不再進行綁定了而是直接執行好了,怎麼在二者之間作一個過渡呢?把綁定所需的資訊用一種 通用的資料結構記錄下來,該資料結構可以同對象指標相聯絡,在編譯時間只需要使用這個資料結構進行抽象的綁定,而在運行期間將會得到真正的綁定。這個資料結 構就是vtable, 也就是編譯期間建立 vtable 表,執行期間查表執行。可以看到,實現使用者所需的抽象和多態需要進行後綁定,而編譯器又是通過抽象和多態而實現後綁定的。下面是通過基類的指標來調用虛函數時,所發生的一切:step 1:開始執行調用 pA->run();(這裡能判斷到底是哪個對象)step 2:取得對象的vtable的指標step 3:從vtable那裡獲得函數入口的位移量,即得到要調用的函數的指標step 4:根據vtable的地址找到函數,並調用函數。step 1和step 4對於一般函數是一樣的,虛函數只是多了step 2和step 3。解惑:1基類和衍生類別是共用一表,還是各有各的表(物理上)
答:基類和衍生類別是各有各的表,也就是說他們的物理地址是分開的,基類和衍生類別的虛表的唯一關聯是:當衍生類別沒有實現基類虛函數的重載時,衍生類別會直接把自己表的該函數地址值寫為基類的該函數地址值.轉自:http://www.cppblog.com/ElliottZC/archive/2007/07/20/28416.aspx
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.