更新時(shí)間:2020-11-20 來(lái)源:黑馬程序員 瀏覽量:
C++的多態(tài)分為靜態(tài)多態(tài)(編譯時(shí)多態(tài))和動(dòng)態(tài)多態(tài)(運(yùn)行時(shí)多態(tài))兩大類(lèi)。靜態(tài)多態(tài)通過(guò)重載、模板來(lái)實(shí)現(xiàn);動(dòng)態(tài)多態(tài)就是通過(guò)本文的主角虛函數(shù)來(lái)體現(xiàn)的。
虛函數(shù)實(shí)現(xiàn)原理:包括虛函數(shù)表、虛函數(shù)指針等。
虛函數(shù)的作用說(shuō)白了就是:當(dāng)調(diào)用一個(gè)虛函數(shù)時(shí),被執(zhí)行的代碼必須和調(diào)用函數(shù)的對(duì)象的動(dòng)態(tài)類(lèi)型相一致。編譯器需要做的就是如何高效的實(shí)現(xiàn)提供這種特性。不同編譯器實(shí)現(xiàn)細(xì)節(jié)也不相同。大多數(shù)編譯器通過(guò)vtbl(virtual table)和vptr(virtual table pointer)來(lái)實(shí)現(xiàn)的。 當(dāng)一個(gè)類(lèi)聲明了虛函數(shù)或者繼承了虛函數(shù),這個(gè)類(lèi)就會(huì)有自己的vtbl。vtbl實(shí)際上就是一個(gè)函數(shù)指針數(shù)組,有的編譯器用的是鏈表,不過(guò)方法都是差不多。vtbl數(shù)組中的每一個(gè)元素對(duì)應(yīng)一個(gè)函數(shù)指針指向該類(lèi)的一個(gè)虛函數(shù),同時(shí)該類(lèi)的每一個(gè)對(duì)象都會(huì)包含一個(gè)vptr,vptr指向該vtbl的地址。
每個(gè)聲明了虛函數(shù)或者繼承了虛函數(shù)的類(lèi),都會(huì)有一個(gè)自己的vtbl。
同時(shí)該類(lèi)的每個(gè)對(duì)象都會(huì)包含一個(gè)vptr去指向該vtbl。
虛函數(shù)按照其聲明順序放于vtbl表中, vtbl數(shù)組中的每一個(gè)元素對(duì)應(yīng)一個(gè)函數(shù)指針指向該類(lèi)的虛函數(shù)。
如果子類(lèi)覆蓋了父類(lèi)的虛函數(shù),將被放到了虛表中原來(lái)父類(lèi)虛函數(shù)的位置。
在多繼承的情況下,每個(gè)父類(lèi)都有自己的虛表。子類(lèi)的成員函數(shù)被放到了第一個(gè)父類(lèi)的表中。
猜你喜歡: