需要更好的閱讀的體驗請移步 👉 小牛肉的個人博客 👈
文章目錄
一、三種繼承方式
1. public
2. private
同名隱藏
如果派生類聲明一個和某基類成員同名的新成員(如果是成員函數,則參數表也要相同,參數不同的情況屬於重載),派生的新成員就隱藏了外層(基類)同名成員,稱爲同名隱藏
3. protected
二、 類型兼容規則(類型轉換)
公有派生類對象可以被當作基類的對象使用,反之則不可。
- 派生類的對象可以隱含轉換爲基類對象;
class A;
class B:public A
A a1; B b1;
a1 = b1;
- 派生類的對象可以初始化基類的引用;
A &a = b1;
- 派生類對象的地址可以隱含轉換爲基類的指 針。
A *ra ;
ra = &b1;
在替代之後,派生類對象就可以作爲基類的對象使用,但只能使用從基類繼承的成員。
例如:
雖然根據類型兼容規則,可以將派生類對象的地址賦值給基類Base1的指針,
但是通過這個基類的指針(或者對象名)只能訪問從基類繼承的成員。
所以運行結果是:
Base1 :: display( )
Base1 :: display( )
Base1 :: display( )
可以使用 虛函數 解決這個問題(詳細解析見後續博客)
三、派生類的構造函數
按照 Base2,Base1,Base3的順序調用基類的構造函數進行初始化,
按照 Base1,Base2,Base3的順序初始化成員對象
析構函數的調用順序和構造函數的調用順序正好相反
四、訪問從基類繼承的成員
1. 二義性問題
如果某個派生類的部分或全部基類都是從另一個共同的基類派生而來,
在這些直接基類中,從上一級繼承而來的成員就擁有相同的名稱,因此派生類中就會出現同名現象。
多繼承時的二義性和冗餘性問題:
使用作用域限定符,派生類的對象在內存中就同時擁有成員var0的多份同名副本,可賦不同的值,若只需要一個這樣的數據副本,使用虛基類
2. 作用域限定
當派生類與基類中有相同成員時:
- 若未特別限定,則通過派生對象使用的是派生類中的同名成員(同名隱藏)
- 如果要通過派生類對象訪問基類中被隱藏的同名成員,應使用基類名和作用域操作符
::
來限定
使用作用域限定符,通過直接基類名來確定要訪問的成員,這種情況下,
派生類的對象在內存中就同時擁有成員var0的兩份同名副本(Base1和Base2的)可賦不同的值
可以使用類名限定解決多繼承時的二義性問題
3. 虛基類
解決多繼承(派生類繼承多個小基類,這些小基類又都繼承同一個大基類)時的二義性和冗餘性問題
舉例:
4. 虛基類和作用域分辨符比較
前者只維護一份成員副本,後者在派生類中擁有同名成員的多個副本,可以存放不同的數據。
相比之下,前者使用更爲簡潔,空間更爲節省,後者可以容納更多的數據