c++: 繼承的詳解(理解)
目錄
繼承的相關概念:
複用:重複性的程式碼肯定是越少越好,隨著組織越來越複雜,單純在main()中寫程式碼會變的越來越難以維護。而函式則更像是一個小的程式。
可以從主函式中脫離出來,使我們可以將任務劃分的跟更小,大大降低了我們的程式整體複雜性,函式讓我們實現了一定程度的程式碼複用。
繼承:繼承的機制是面向物件程式設計使程式碼可以複用的一種手段,它允許程式設計師在保持原有類特性的基礎上繼承擴充套件,增加功能。這樣產生的類
成為派生類!
繼承的格式:
繼承許可權&訪問限定符
三種類成員訪問限定符:
- public公有
- protected保護
- private私有
三種繼承關係
- public公有繼承
- protected保護繼承
- private私有繼承
繼承方式及繼承許可權對應表:
總結:
- 基類private成員在派生類中不可訪問(如果基類成員不想在類外被直接訪問,但需要在派生類中訪問就定義為protected,保護成員限定符因繼承才出現)
- public繼承是一個介面繼承,保持is-a的原則,每個父類可用成員對子類也可用,因為每個子類物件也都是一個父類物件
- protected/private是一個實現繼承,基類的部分成員並非完全成為子類介面的一部分,是has-a原則
- 不管是那種繼承方式,派生類內部都可以訪問基類的公有和保護成員,私有成員則不可見(編譯器語法檢測無法通過,所以不能訪問)
- class預設private,struct預設public
- 一般使用public,極少場景才會使用其他
賦值相容規則(public繼承)
- 子類物件可以賦值給父類物件(切割或切片:僅把父類含有的物件進行賦值)
- 父類物件不能賦值給子類物件
- 父類的指標或引用可以指向子類物件
- 子類的指標或引用不能指向父類物件(可以通過強制型別轉換完成,但是不能呼叫成員函式,會崩潰)
繼承中的作用域:
- 在繼承體系中基類和派生類都有獨立的作用域
- 子類和父類中有同名成員,子類將遮蔽對同名成員的直接訪問(在子類成員中:可以使用基類::基類成員 訪問)--(隱藏或重定義)
- 在實際體系中最好不要定義同名成員
派生類的預設成員函式:
派生類如果沒有顯示定義這六個預設成員函式,編譯器則會合成
合成:必須依賴與基類,根據基類的相應成員的行為來合成派生類的預設成員函式
生成:不依賴於任何東西,只是編譯器根據類的定義簡單生成基於基礎型別的成員函式
- 基類沒有預設建構函式,派生類必須要在初始化類表中顯式給出基類名和引數列表
- 基類沒有定義建構函式,則派生類也可以不用定義,全部使用預設建構函式
- 基類定義了帶有形參表建構函式,派生類就一定定義建構函式
【面試題】
系統自動呼叫析構原因:保證先析構子類在析構父類(子類隱藏了父類的解構函式)棧結構規則
同理:子類初始化時呼叫父類的預設成員函式初始化父類,呼叫自己的預設成員函式初始化自己
棧結構:先初始化父類在子類,先析構子類在析構父類
實現一個不能被繼承的類:將父類的建構函式定義成私有!
子類合成時先呼叫父類建構函式,因為私有所有失敗!
繼承與友元:
友元關係不能繼承,也就是說基類友元不能訪問子類私有和保護成員(父親的朋友,不一定是孩子的朋友)
繼承與static靜態成員:
基類定義了static靜態成員,則整個繼承體系中只有一個這樣的成員,無論派生出多少子類都只有static
繼承體系下派生類的物件模型:
物件模型為物件中非靜態成員變數在記憶體中的佈局形式,與成員函式無關
- 單繼承:一個子類只有一個直接父類
- 多繼承:一個子類有兩個或以上直接父類
- 菱形繼承 我們發現Assistant類中存在兩份Person物件,因此在訪問繼承於基類的成
員變數時,會存在資料冗餘及二義性的問題 二義性:兩邊都有(選擇困難) 解決方式:1》指定訪問那個父類2》虛繼承 - 虛擬繼承—— 解決菱形繼承的二義性和資料冗餘的問題
虛擬繼承在程序許可權前面加上virtual關鍵字即可構成虛擬繼承
特點:在任何派生類中的virtual基類總共用同一個(共享)物件表示
【注意】:儘量不要設計菱形繼承的類
虛繼承和直接繼承有什麼區別
1.時間:在通過繼承類物件訪問虛基類物件中的成員(包括資料成員和函式成員)時,都必須通過某種間接引用來
完成,這樣會增加引用定址時間(就和虛擬函式一樣),其實就是調整this指標以指向虛基類物件,只不過這個調整
是執行時間接完成的。
2.空間:由於共享所以不必要在物件記憶體中儲存多份虛基類子物件的拷貝,這樣較之 多繼承節省空間。虛擬繼承與
普通繼承不同的是,虛擬繼承可以防止出現菱形繼承時,一個派生類中同時出現了兩個基類的子物件。也就是說,
為了保證 這一點,在虛擬繼承情況下,基類子物件的佈局是不同於普通繼承的。因此,它需要多出一個指向基類子
物件的指標