C 多型(二)虛表剖析以及菱形繼承

2021-07-28 21:48:14 字數 3338 閱讀 2177

我們在類的成員函式的時候就已經接觸到了函式過載,但是並不知道它是多型的一種表現,

函式過載的特徵:

1、同一作用域(基類和派生類不是同一作用域)

2、函式名字相同

3、引數不同(引數型別不同,引數個數不同,排布順序不同)

4、返回值型別可以不同;

1、不在同一作用域(分別在基類和派生類)

2、函式名相同/引數相同/返回值相同(協變除外)

3、基類函式必須有virtual關鍵字

4、訪問修飾符可以不同

協變:基類/派生類返回值型別是基類/派生類的指標或引用

在函式重寫(覆蓋)中,一般分為基類中有虛函式,在派生類中進行重寫和沒有進行重寫;

1、用物件呼叫函式

class base

virtual

void funtset2()

virtual

void funtset3()

};class derived:public base

virtual

void funtset2()

};int main()

結果如下:

先對基類進行分析:

從圖中可以看到,記憶體1的視窗中還是只有乙個虛表的位址,在記憶體3的視窗中可以看到有3個位址分別對應到彙編**中funtest1(),funtest2(),funtest3()的函式的位址。

derived d;

d.funtset1();

d.funtset2();

d.funtset3();

對派生類進行分析:

圖中的內容和基類中差不了多少,我們把兩張不放在一起比較一下,就發現只有乙個地方是一樣的就是funtest3()中的函式對應位址和基類中的函式對應位址是完全一樣的,所以就能發現funtest1()和funtest2()函式發生了覆蓋;

2、用指標/引用呼叫函式

結果很簡單,但是在多重繼承的記憶體分配中得讓我們慢慢的來看一下記憶體:

對於上面這幅圖,我解釋一下 :

1、在記憶體1中是檢視了d;的位址可以分為4塊,第一部分為繼承base1,第二部分為繼承base2,第三部分為繼承base3的,在最後一部分是derived自己的成員;

2、在記憶體2中可以看到,是對base1的位址進行了檢視顯示出了兩個位址,其中第乙個為base1::funtest()函式的位址,第二個是derived中成員函式的位址,

3、是在彙編中截出funtest4()的位址進行驗證;

所以,總結一下:

1、通過基類的指標/引用呼叫虛函式時,呼叫基類還是派生類的虛函式,要根據執行時引用/指標實際引用的型別確定

2、呼叫非虛函式時,無論基類指向的是何種型別,都呼叫基類的函式;

3、派生類的虛函式表生成:①:先拷貝基類的虛函式表,②:如果派生類函式重寫了基類的某個虛函式,就替換同位置的基類虛函式,③:跟上派生類自己新定義的虛函式;

4、在多重繼承中派生類自己的虛函式是放在了第乙個繼承基類的虛表後面;

c++繼承(三)通過菱形繼承看virtual繼承在這篇博文中我已經簡單介紹了虛擬繼承,在虛擬繼承中,我們能看到解決了資料的冗餘與二義性,下來我們來看看菱形虛擬繼承:

class b

int b = 1;

};class c1:virtual

public b

int c1 = 2;

};class c2:virtual

public b

int c2 = 3;

};class d :virtual

public c1, virtual

public c2

int d = 4;

};int main()

程式的結果:

結果還是很簡單,但是在執行中的記憶體呼叫還是比較難的:

通過上圖的**,可以看到記憶體中,d的記憶體分配:

在d中虛擬繼承的是c1和c2的成員函式,而c1和c2繼承的是b中的成員函式,在帶有虛函式的虛擬繼承中,我們可以從上圖看都有4個虛表,每個函式都有乙個自己的虛表結構指向自己的虛表位址;

C 虛表(探索多型的原理)和菱形繼承

菱形繼承 多繼承 兩個子類繼承同乙個父類,而又有子類 同時繼承這兩個子類。菱形繼承關係模型如下圖 菱形繼承的 如下 dd的物件中有兩個aa成員 include includeusing namespace std class aa class bb public aa class cc public...

C 菱形繼承與虛繼承

12 29 study.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std 菱形繼承 多繼承 兩個類共同繼承於同乙個類 class animal class sheep1 public animal class tuo1 pu...

c 中菱形繼承 虛繼承

關於菱形繼承 相當於在c 中,分別建立四個類,動物類,羊類,駝類,羊駝類,繼承關係如圖所示。在類中只建立乙個屬性,年齡。動物類 class animal 羊類 class sheep virtualpublic animal 駝類 class tuo virtualpublic animal 羊駝類...