c++學習筆記之繼承和多態


1、public 繼承

class A : public B
(1)友元函數不能被繼承
(2)protected成員可以被派生類和友元訪問

2、派生類

(1)派生類構造函數如果未顯式調用基類構造函數,則會隱式調用基類默認構造函數,沒有則報錯
(2)派生類頭文件中#include包含基類頭文件
(3)派生類調用基類函數(已在派生類中重新定義過)
     基類名::基類函數          如 B::b(...)
     重新定義函數時一般會調用其基類函數,如果不加“基類名::”則會調用自己,形成無限遞歸
(4)派生類有一個與基類中同名但簽名不同的成員函數,那麼會隱藏基類的那個成員函數。如:
     基類A有一個成員函數  void go(int i)
     派生類B有                  void go(int i, int j)
     b.go(1)會編譯報錯參數太少。(如果派生類沒有go函數,則會直接調用基類的)
(5)多層派生關係:構造函數會從基類->派生類的順序調用,析構函數則相反。
(6)派生類不會繼承基類的構造函數、析構函數和重載的運算符

3、public/private/protected 繼承

繼承public基類:基類的public成員成爲派生類public成員,protected成員成爲派生類的protected成員,派生類不能直接訪問基類private成員。
繼承protected基類:基類的public、protected成員成爲派生類的protected成員,派生類不能直接訪問基類private成員。
繼承private基類:基類的public、protected成員成爲派生類的private成員,派生類不能直接訪問基類private成員。

4、基類、派生類指針

(1)基類指針指向派生類對象,可以調用基類成員,調用派生類成員則報錯,但可以將基類指針顯式強轉成派生類指針就可以調用了。所以句柄類型決定哪個類函數被調用。
(2)派生類指針指向基類對象,編譯錯誤。

5、virtual

virtual void a(...)
當通過指針調用virtual函數,則不再根據句柄來決定,而是根據指針所指的對象的類型選擇合適的函數調用。
(1)一個函數聲明爲virtual,那麼從整個繼承層次的那一點向下所有類中都保持virtual,即使派生類重載此函數時並沒有顯式的聲明virtual。
所以重載最好也顯式聲明virtual。
(2)當virtual函數通過按名引用被調用,如a.b(),調用哪個函數在編譯時已經決定,即靜態綁定,並不是多態性行爲
因此動態綁定只能通過指針句柄來完成

6、抽象類

通過聲明類的一個或多個virtual函數爲純virtual函數,可以使一個類成爲抽象類。
純virtual函數  virtual void a(...) const = 0;
“=0”稱爲純指示符。
派生類必須重載純virtual函數,否則實例化時編譯報錯。

7、運行時類型信息RTTI(dynamic_cast\typeid\type_info)

dynamic_cast<class>(...)  向下強制類型轉換
typeid(...)返回一個type_info對象的引用,其成員函數name()返回typeid實參的類型名稱字符串(如“Class A”)。注意這個字符串與編譯器有關,不同編譯器可能不同。

8、virtual析構函數

刪除一個派生類對象卻使用基類指針,這樣就無法調用派生類析構函數,會報行爲未定義錯誤。
解決方法是聲明基類析構函數爲virtual,即使派生類析構函數與基類的不同名,也可以使這些析構函數爲virtual函數,這時刪除就能正常銷燬。
(1)如果一個類會有virtual函數,就要提供一個virtual析構函數
(2)構造函數不能聲明爲virtual
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章