首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 繼承與多態核心知識體系(一):從基礎概念到虛繼承機制

     編輯:關於C++

繼承的核心價值

繼承將具有共同特徵、相互關聯的類別組織成層次結構:共同部分提煉為基類(父類),其他類別直接或間接繼承成為派生類(子類)。這實現了程式碼復用——子類自動擁有父類的所有非私有成員。

存取控制與繼承關係

繼承存取控制表

  • public 繼承:基類 public 成員保持 public,protected 保持 protected。
  • protected 繼承:基類 public/protected 成員均變為派生類 protected。
  • private 繼承:基類所有非私有成員均變為派生類 private。

protected 成員用於「想與派生類分享,但不想被外部存取」的場景。

賦值相容規則(public 繼承前提下)

  1. 物件賦值:子類物件可賦值給父類物件(切片問題),反之不可。學生是人,但人不一定是學生。
  2. 指標/引用賦值:父類指標/引用可指向/綁定子類物件,反之不可。子類擁有父類所有成員再加上自己的成員,父類指標指向父類物件時,解引用可能存取非法記憶體。

成員函數重定義/隱藏

子類與父類成員(含變數與函數)同名時,子類成員會隱藏父類同名成員,與參數列表、返回型別無關。需透過作用域解析運算子(Base::member)存取被隱藏成員。

單繼承、多重繼承與鑽石繼承問題

多重繼承示意圖

鑽石繼承 導致兩大問題:

  1. 資料冗餘:基類成員在最底層派生類中存在多份拷貝。
  2. 存取二義性:無法確定使用哪份基類成員。

虛繼承解決鑽石問題

在繼承關係前加 virtual 關鍵字:

class A { protected: int _a; };
class B : virtual public A { ... };
class C : virtual public A { ... };
class D : public B, public C { ... }; // D 中只有一份 _a

虛繼承記憶體佈局

虛繼承透過虛基類指標/虛基類表實現共享,解決冗餘與二義性,但會增加存取開銷,降低效能。

虛函數與動態多態

  • 虛函數:成員函數前加 virtual。
  • 覆寫:派生類虛函數與基類虛函數完全相同(函數名、參數、返回型別),除協變返回型別與虛解構函數外。
  • 動態多態條件:① 子類覆寫父類虛函數 ② 使用父類指標/引用調用虛函數。
class Book { public: virtual void ShowPrice() { cout << "全價"; } };
class BarginBook : public Book { public: void ShowPrice() override { cout << "半價"; } };

Book* p = new BarginBook();
p->ShowPrice(); // 輸出「半價」—— 動態綁定

虛解構函數的必要性

透過基類指標刪除派生類物件時,若基類解構函數非虛函數,僅呼叫基類解構函數,導致派生類資源洩漏。基類解構函數應宣告為 virtual,確保完整的解構鏈呼叫。

友元、靜態成員與繼承

  • 友元不可繼承:父類友元非子類友元,需在子類重新宣告。
  • 靜態成員共享:整個繼承體系僅有一份靜態成員,屬於整個體系,無存取限定時皆可訪問。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved