C 多重繼承與虛基類

2021-09-19 03:59:33 字數 2302 閱讀 9327

多重繼承就是乙個派生類繼承了多個基類。

i>通過成員初始化列表指定建構函式

class d : public b, public c 

};

ii>構造函式呼叫順序

class b 

void f()

};class c

void f()

};class d : public b, public c

void f()

};int main()

輸出:

b::b()

c::c()

d::d()

b::f() ------ a = 1

c::f() ------ a = 2

d::f() ------ a = 3

呼叫建構函式的順序與繼承順序一致i>方法衝突派生類中重定義方法(用上例的方法)

void d::f()
或者在外部呼叫的時候加上域解析運算子

objd.b::f();//派生類物件呼叫基類b的方法f

objd.c::f();//派生類物件呼叫基類c的方法f

ii>成員衝突(經典的菱形繼承)

class a ;

class b : public a;

class c : public a;

class d : public b, public c ;

可以看到,對於類a的成員,繼承了兩次,也就是說,d中,有兩個重複成員a的來自類a,這是不必要的,所以,有了新的繼承方法,虛繼承在繼承時,加上virtual關鍵字,表示虛繼承

class a ;

class b : virtual public a ;

int main()

輸出:

1

4

可以發現,類b中有了隱藏的成員(如果是普通的繼承,只佔1個位元組),其實,這個隱藏的成員儲存了類b物件到類a物件的乙個間接引用(存了乙個整數,是乙個偏移量)

虛繼承中的基類被稱為虛基類

class a ;

class b : virtual public a;

class c : virtual public a;

class d : public b, public c ;

通過虛繼承,當d建立例項時,只會繼承「乙份a」(b,c中存了間接引用)。

d::d(int a) : a(a)
注意,a是d的間接基類,如果a是非虛基類,這裡是非法的,一般情況下,只能指定自己的直接基類怎樣呼叫構造;如果是虛基類,想要呼叫有參的構造,就要在間接基類中的成員初始化列表中指定虛基類呼叫哪個構造。不能通過b和c的建構函式進行傳遞,因為只有乙份a,兩條初始化路徑可能會造成二義性,所以,採用這樣的方式初始化虛基類。

先來看普通的繼承:

class a 

};class b : public a

};class c : public a ;

class d : public b, public c;

int main()

這裡會出現二義性呼叫,d中有b::f()和a::f()對於虛繼承:

class a 

};class b : virtual public a

};class c : virtual public a ;

class d : public b, public c;

int main()

輸出:

b::f()
同樣,d中有b::f()和a::f(),但b是a的子類,則,b::f更優先。 個人覺得在使用時還是加上域解析運算子,這樣不容易出錯

多重繼承 虛繼承與虛基類

一 多重繼承 單重繼承 乙個派生類最多只能有乙個基類 多重繼承 乙個派生類可以有多個基類 class 類名 繼承方式 基類1,繼承方式 基類2,派生類同時繼承多個基類的成員,更好的軟體重用 可能會有大量的二義性,多個基類中可能包含同名變數或函式 多重繼承中解決訪問歧義的方法 基類名 資料成員名 或成...

多重繼承與虛基類

多重繼承 multiple inheritance,mi 虛基類虛基類使得從多個類 它們的基類相同 派生出的物件只繼承乙個基類物件。通過使用關鍵字virtual。例如,可以使worker被用作singer和waiter的虛基類 virtual和public的次序無關緊要 class singer v...

多重繼承與虛基類

多重繼承 前面我們介紹的派生類只有乙個基類,稱為單基派生或單一繼承。在實際運用中,我們經常需要派生類同時具有多個基類,這種方法稱為多基派生或多重繼承。2.1 多重繼承的宣告 在 c 中,宣告具有兩個以上基類的派生類與宣告單基派生類的形式類似,只需將要繼承的多個基類用逗號分開即可。在多重繼承中,公有派...