首先,我們來認識一下類與類之間的關係有哪幾種:
1、has_a 組合 包含關係,類中包含另乙個類的物件
2、use_a 使用關係,類中使用了另乙個類的成員函式
3、is_a 繼承關係,b是特殊的a,b從a繼承過來,a中有的b中都有
繼承的語法:class 類名 :訪問控制許可權 要繼承的類的名字
class c_xy:public xy {};// c_xy是繼承自xy的子類(派生類),xy是c_xy的父類(基類)
1、訪問控制許可權:public 、protect 、private主要講一下protect屬性,是保護屬性,類的內部可用,外部不可用,其派生類的內部可用,外部不可用
1)公有繼承(public)下,父類→子類:公有→公有(內外可用),保護→保護(內可用),私有→私有(不可用)。
2)保護繼承(protect)下,父類→子類:公有→保護(內可用),保護→保護(內可用),私有→私有(不可用)。
3)私有繼承(private)下,父類→子類:公有→私有(內可用),保護→私有(內可用),私有→私有(不可用)。
判斷子類的訪問許可權可以依次判斷:類的內外→繼承方式→基類屬性
2、物件模型:子類的排列方式是基類成員在前,本身的成員在後
3、型別相容性原則:在需要基類物件的任何地方,都可以使用公有派生類的物件來替代,在替代之後,派生類物件就可以作為基類的物件使用,但是只能使用從基類繼承的成員。
1)子類物件可以當作父類物件使用
2)子類物件可以直接賦值給父類物件
3)子類物件可以直接初始化父類物件
4)父類指標可以直接指向子類物件
5)父類引用可以直接引用子類物件
4、繼承中的構造和析構:
1) 派生類在進行構造時要呼叫父類的建構函式對父類變數進行初始化;
派生類新增的變數要呼叫自己的建構函式進行初始化;
對父類的成員引數初始化,在初始化列表中呼叫父類的建構函式。
2) 繼承和組合混搭時的順序:先父類,再子類物件,最後之類的建構函式。
5、派生類中有和基類同名的成員變數會遮蔽基類的成員,當然真正需要使用時,可以使用域解析符::來進行區分,如
b.a::a = 10;
6、過載和重定義:
1) 類中的函式過載必須發生在同乙個類中;
派生類不能過載基類的函式,過載會遮蔽基類的所有同名函式,但同樣,還是可以使用域解析符的。
2) 派生類的函式和基類的函式 函式原型一樣,叫函式的重定義。重定義是發生在基類和派生類之間的。
7)static 關鍵字的繼承
基類的靜態變數是所有派生類共享的,因為它存在資料域中。 靜態變數也遵循繼承的訪問控制。
8)多繼承:乙個類有多個基類的繼承關係
class c : public a, public b{};
1) 派生類的基類的構造順序和在繼承列表中的宣告順序有關。
2) 多繼承中的指標偏移:
a *pa = &c;
b *pb = &c;
c *pc = &c;
此時,pa 和 pc 指向 繼承類中父類a成員的起始位址,但pb則指向的是繼承類中父類b成員的起始位址,與pa和pc相差乙個a的距離
3)但是,當乙個派生類從多個基類派生,而這些基類又有乙個共同的基類,則在對該基類宣告的名字進行訪問時會產生二義性問題。
公共基類的呼叫不明確(::可以解決);
雖說呼叫不明確問題可以解決,但在構造派生類的時候公共基類的建構函式卻還是會被呼叫2次,產生問題。
4)為了解決二義性問題,c++便引入了虛繼承的概念,使公共基類在派生類中只產生乙個子物件。
關鍵字: virtual
class b1: virtual public a{};
運用virtual 關鍵字之後,建構函式就只會被呼叫一次。但是當我們用sizeof 來測試類的大小時,發現類不僅沒有變小,反而變大了。
經過一系列的測試,發現,在基類的父類成員中多了乙個vbpter這樣的虛基類指標:
該指標包含2個內容:當前類指標距離虛基類指標的偏移量 、 基類指標和虛基類指標的偏移量。
class a
;class b1 : virtual public a
;class b2 : virtual public a
;class c :public b1,public b2
;int main()
執行結果為:
pa = 00cff90c, pb1 = 00cff8f8, pb2 = 00cff900, pc = 00cff8f8
這樣的乙個測試程式,從執行結果我們可以看出,pc和pb1 確實是指向b1首位址,而pb2與其相差8個位元組,pa與其相差20個位元組,所以vbptr確實是20和12。
派生與繼承 多重派生
1 理解下面的程式,並在 vc 6.0 下執行檢視結果,回答程式後面的問題。class cbase1 cbase1 void print protected int a class cbase2 cbase2 void print protected int b class cderive publ...
繼承與派生
實驗內容 建立乙個基類,兩個派生類,讓每乙個派生類都包含乙個函式area 分別用來返回矩形和三角形的面積。用建構函式對height和width進行初始化。要求通過基類指標訪問虛函式的方法。純虛函式 virtual double area 0 純虛函式的作用是在基類中為派生類保留乙個函式的名字,以便派...
繼承與派生
在c 中,所謂 繼承 就是在乙個已存在的類的基礎上建立乙個新的類。已存在的類成為 基類 新建立的類成為 派生類 乙個新類從已有的類那裡獲得其已有特性,這種現象成為累的繼承。從另一角度說,從已有的類產生乙個新的子類,稱謂累的派生。派生類的宣告方式 class 派生類名 繼承方式 基類名 派生類新增加的...