具體分為三種情況:1.只繼承介面,派生類必須自己編寫實現**(利用純虛函式)2.繼承介面和實現,但允許派生類自己編寫**替換基類實現**(利用虛函式)3.繼承介面和實現,不允許派生類修改函式**(非虛函式)
public:基類public成員與protect成員在派生類中保持原有屬性,private成員仍為基類private成員,派生類不可訪問
protect:基類public成員與protect成員均成為派生類的protect成員,private成員仍為基類private成員,派生類不可訪問
private:基類中public成員與protect成員均成為派生類的private成員,private成員仍為基類private成員,派生類不可訪問
public
protected
private
共有繼承
public
protected
不可見私有繼承
private
private
不可見保護繼承
protected
protected
不可見多台實現方式有兩種:過載和覆蓋(虛函式)。基類和派生類有各自的虛函式表和虛函式指標,虛函式指標指向自己的虛函式表。
class a
;class b : public a
;//a,b的實現省略
因為a有virtual void f(),和g(),所以編譯器為a類準備了乙個虛表vtablea,內容如下:
a::f 的位址
a::g 的位址
b因為繼承了a,所以編譯器也為b準備了乙個虛表vtableb,內容如下:
a::f 的位址
b::g 的位址
注意:因為b::g是重寫了的,所以b的虛表的g放的是b::g的入口位址,但是f是從上面的a繼承下來的,所以f的位址是a::f的入口位址。然後某處有語句 b bb;的時候,編譯器分配空間時,除了a的int a,b的成員int b;以外,還分配了乙個虛指標vptr,指向b的虛表vtableb,bb的布局如下:
vptr : 指向b的虛表vtableb
int a: 繼承a的成員
int b: b成員
當如下語句的時候:
a *pa = &bb;
pa的結構就是a的布局(就是說用pa只能訪問的到bb物件的前兩項,訪問不到第三項int b)
那麼pa->g()中,編譯器知道的是,g是乙個宣告為virtual的成員函式,而且其入口位址放在**(無論是vtalbea表還是vtalbeb表)的第2項,那麼編譯器編譯這條語句的時候就如是轉換:call *(pa->vptr)[1](c語言的陣列索引從0開始)。
參考:
繼承與多型
繼承 繼承是c 語言支援 重用及多型的重要機制。通過繼承,可以繼承可以在現有類的基礎上派生出新類,新類將共享現有類的成員,並且還可以新增新的成員。c 語言中,重用主要表現為可以使用現成的類 如.net框架類庫中的類 來定義新類,主要方法有組合和繼承兩種 繼承是物件導向程式設計支援 重用的另乙個重要機...
繼承與多型
虛函式只要在基類裡定義,所以繼承類都不用重新定義為虛函式,自動成為虛函式。虛函式必須有實現,普通成員函式在沒有呼叫時可以沒有實現 定義 class animal 只需要在基類定義函式為虛,子類中不需要新增virtual.smile函式在沒有呼叫時可以不實現。當有函式為虛函式時,析構函式應定義為vir...
繼承與多型
繼承需要符合的關係 is a,父類更通用 子類更具體 子類繼承父類的所有屬性和方法 不包括父類構造方法 super可以呼叫父類的方法和構造方法 子類可以重寫父類的方法 使用多型之後,當需要增加新的子類型別時,無需更改總部類,程式的可擴充套件性及可維護性增強 簡單來說,多型是具有表現多種形態的能力的特...