C 54 被遺棄的多重繼承 下

2021-09-12 21:45:38 字數 2117 閱讀 7879

輸出:

sizeof(d) = 8

using pa to call funca()...

basea::funca()

using pb to call funcb()...

baseb::funcb()

using pbc to call funcb()...

baseb::funcb()

using pbe to call funcb()...

basea::funca()

分析:1. sizeof(d) = 8 ==> d 中包含兩個虛函式表指標

2. dynamic_cast(pa); 編譯器做了什麼?

由於使用了 dynamic_cast 關鍵字,編譯器會檢查 pa 指標指向的物件d。

檢視 d 物件存在父類 basea, baseb, 於是判定dynamic_cast(pa);的強制型別轉換合法。

在強制型別轉換時,對指標做乙個修正,使得 pbe 指向 pb 所指的位置。

3. baseb* pbe = (baseb*)pa; pbe->funcb();

basea 型別指標 pa 指向 d 物件,將 pa 賦值給 baseb 型別,「等價於」將 d 物件位址賦值給 pbe 指標。

那麼使用 baseb 型別指標 pbe 呼叫 funcb(), 為什麼 basea 類中的 funca() 會被呼叫呢?

類 basea 與 類 baseb 定義的成員結構相同,那麼生成的虛函式表結構也將相同;

funca() 與 funcb() 是虛函式,那麼函式的呼叫將通過虛函式表指標完成;

baseb* pbe = (baseb*)pa; ==> c 方式的強制型別轉換將導致 pbe 指標指向 pa 指標指向的位址;

pbe->funcb(); ==> 實際將在 pa 指標指向處查詢虛函式表指標vptr, 因為條件1,於是在 vptr1 指標指向的虛函式表中查詢到 funca() 並成功呼叫。

單繼承某個類 + 實現( 多個 ) 介面

表象是多繼承,但在物件導向語義中已不再是多繼承(僅繼承自乙個類,其它類都是介面)

#include using namespace std;

class base

int geti()

bool equal(base* obj) // 注意這裡

};class inte***ce1

;class inte***ce2

;class derived : public base, public inte***ce1, public inte***ce2

void add(int i)

void minus(int i)

void multiply(int i)

void divide(int i)

}};int main()

輸出:

p->geti() = 100

p->geti() = 40

pint1 == p : 1

pint2 == p : 1

53 被遺棄的多重繼承

c 支援編寫多重繼承的 乙個子類可以擁有多個父類,子類擁有所有父類的成員變數,子類繼承所有父類的成員函式,子類物件可以當作任意父類物件使用。多重繼承的本質與單繼承相同。include include using namespace std class basea int geta class bas...

類的繼承 被遺棄的多重繼承

本文參照於狄泰軟體學院,唐佐林老師的 c 深度剖析教程 關聯知識 virtual虛函式,繼承 問題 c 中是否允許乙個類繼承自多個父類?如果可以,那麼會出現什麼問題呢?如果不可以,為什麼?我們在單繼承的語法基礎上,再繼承兩個父類,試試編譯是否能通過。class derived public base...

C 53 被遺棄的多重繼承 (上)

問題 c 中是否允許乙個類繼承自多個父類?class derived public base a,public base b,public base c include using namespace std class basea int geta class baseb int getb cla...