C 多型的原理

2021-10-04 16:43:02 字數 2441 閱讀 2634

//這裡常考一道筆試題:sizeof(base)是多少?

/* 這裡 sizeof(base) = 8。

int型別4個位元組 + virtual中含乙個指標:4個位元組 = 8個位元組

(無論有幾個虛函式,只有乙個指標,指標指向虛函式表)

*/class

base

private

:int _b =1;

};

通過觀察測試我們發現b物件是8bytes,除了_b成員,還多了乙個_vfptr放在物件的前面(注意有些平台可能會放到物件的最後面,這個跟平台有關),物件中的這個指標我們叫做虛函式表指標(v代表virtual,f代表function)。乙個含有虛函式的類中都至少都有乙個虛函式表指標,因為虛函式的位址要被放到虛函式表中,虛函式表也簡稱虛表。

下面我們來分析一下派生類中這個表放了什麼。

//針對上面的**我們做出以下改造

//1、我們增加乙個派生類drive去繼承base

//2、drive中重寫func1

//3、base再增加乙個虛函式func2和乙個普通函式func3

class

base

virtual

void

func2()

void

func3()

private

:int _b =1;

};class

derive

:public base

private

:int _d =2;

};intmain()

通過觀察和測試,我們發現了以下幾點問題:

派生類物件d中也有乙個虛表指標,d物件由兩部分構成,一部分是父類繼承下來的成員,虛表指標也就是存在部分的另一部分是自己的成員。

基類b物件和派生類d物件虛表是不一樣的,這裡我們發現func1完成了重寫,所以d的虛表中存的是寫的derive::func,所以虛函式的重寫也叫作覆蓋。覆蓋就是指虛表中虛函式的覆蓋。重寫是語法的叫法,覆蓋是原理層的叫法。

另外func2繼承下來後是虛函式,所以放進了虛表,func3也繼承下來了,但是不是虛函式,所以不會放進虛表。

虛函式表本質是乙個存虛函式指標的指標陣列,這個陣列最後麵放了乙個nullptr。

總結一下派生類的虛表生成:

(1)先將基類中的虛表內容拷貝乙份到派生類虛表中

(2)如果派生類重寫了基類 中某個虛函式,用派生類自己的虛函式覆蓋虛表中基類的虛函式

(3)派生類自己新增加的虛函式按其在派生類中的宣告次序增加到派生類虛表的最後。

這裡還有乙個小可愛們容易混淆的問題:虛函式存在**?虛表存在**?答:虛函式存在虛表,虛表存在物件中。注意上面的回答是錯的。但是很多小可愛們都是這樣深以為然的。注意虛表存的是虛函式指標,不是虛函式 ,虛函式和普通函式是一樣的,都是存在**段的,只是他的指標又存到了虛表中。另外物件中存的不是虛表,存的虛表指標。

注:虛表指標隨物件儲存;虛函式存在**段;虛表存在**段;this指標存在棧上。

觀察下圖的紅色箭頭我們看到,p是指向mike物件時,p->buyticket在mike的虛表中找到虛函式是person::buyticket。

觀察下圖的藍色箭頭我們看到,p是指向johnson物件時,p->buyticket在johnson的虛表中找到虛函式是student::buyticket。

這樣就實現出了不同物件去完成同一行為時,展現出不同的形態。

反過來思考,我們要達到多型,有兩個條件,乙個是虛函式覆蓋,乙個是物件的指標或引用呼叫的虛函式。滿足多型以後的函式呼叫,不是在編譯時確定的,是執行起來以後到物件的中取找的。不滿足多型的函式呼叫時編譯時確認好的。

靜態繫結又稱為前期繫結(早繫結),在程式編譯期間確定了程式的行為,也稱靜態多型,比如:函式過載。

動態繫結又稱後期繫結(晚繫結),是在程式執行期間,根據具體拿到的物件確定程式的具體行為,呼叫具體的函式,也稱動態多型。

C 多型原理

靜態多型性比較簡單,主要動態多型性比較難理解。動態多型性有兩個條件 1 在基類中必須使用虛函式 純虛函式 2 呼叫函式時要使用基類的指標或引用。只要在基類的成員函式前加上virtual,該成員函式就是虛函式,從基類派生出來的類的同名成員函式,不管前面是否有virtual,同樣是虛函式,在虛函式的實現...

c 多型原理

1 當類中宣告虛函式時,編譯器會在類中生成乙個虛函式表 2 虛函式表是乙個儲存類成員函式指標的資料結構 3 虛函式表是由編譯器自動生成與維護的 4 virtual成員函式會被編譯器放入虛函式表中 5 當存在虛函式時,每個物件中都有乙個指向虛函式表的指標 c 編譯器給父類物件 子類物件提前布局vptr...

C 多型的實現原理

1.用virtual關鍵字申明的函式叫做虛函式,虛函式肯定是類的成員函式。2.存在虛函式的類都有乙個一維的虛函式表叫做虛表。類的物件有乙個指向虛表開始的虛指標。虛表是和類對應的,虛表指標是和物件對應的。3.多型性是乙個介面多種實現,是物件導向的核心。分為類的多型性和函式的多型性。4.多型用虛函式來實...