標籤:虛繼承 版本 物件導向 enter 也會 ios 形參 過程 尋找
18.3 多重繼承與虛繼承
規則基本與“單繼承”是一樣的,在次記錄幾點需要關注的點!
衍生類別建構函式初始化所有基類
構造一個衍生類別的對象將同時初始化它的所有基類子物件。多重繼承的衍生類別的建構函式初始值也只能初始化它的直接基類:
1 class ZooAnimal { }; 2 class Bear:public ZooAnimal { }; 3 class Endangered { }; 4 class Panda:public Bear,public Endangered {/*......*/}; 5 6 //顯式地初始化所有基類 7 Panda::Panda(string name,bool onExhibit) 8 :Bear(name,onExhibit,"Panda"), 9 Endangered(Endangered::critical) { }10 //隱式使用Bear的預設建構函式初始化Bear子物件(前提是:Bear類含有預設建構函式)11 Panda::Panda()12 :Endangered(Endagered::critical) { }
基類的構造順序與衍生的資料行表中基類的出現順序保持一致,而與衍生類別建構函式初始值列表中基類的順序無關。
繼承的建構函式與多重繼承
多重繼承問題1:如果從多個基類中繼承了相同的建構函式(即形參列表完全相同),則程式將產生錯誤:
解決辦法:這個類必須為該建構函式定義它自己的版本!
類型轉換與多個基類
編譯器不會在衍生類別向基類的幾種轉換中進行比較和選擇,因為它認為轉換到任意一種基類都一樣好。
問題2:這時要注意二義性錯誤。
例如,存在以下所示的print重載版本:
void print(const Bear&);void print(const Endangered&);Panda ying_yang("ying_yang");print(ying_yang); //二義性錯誤 注意二者缺一不可:
1.衍生類別向基類的類型轉換存在;
2.轉換可訪問。
多重繼承下的類範圍
衍生類別的範圍嵌套在直接基類和間接基類的範圍中。尋找過程沿著體系自底向上進行。
問題3:當一個類擁有多個基類時,有可能出現衍生類別從兩個或多個基類中繼承了同名成員的情況。此時,不加首碼限定符直接使用該名字將引發二義性。
解決辦法:1.不調用;2.限定符指定版本;3.定義一個新版本。
虛繼承
在預設情況下,派生了中含有繼承鏈上每個類對應的子部分。如果某個類在派生過程中出現了多次,則衍生類別中將包含該類的多個子物件。
問題4:這種預設情況對某些形如iostream的類是行不通的。一個iostream對象肯定希望在同一個緩衝區中進行讀寫操作,也會要求條件狀態能同時反映輸入輸出操作的情況。假如在iostream對象中真的包含了base_ios的兩份拷貝,則上述的共用行為就無法實現了。
解決辦法:虛繼承
c++ -- 物件導向程式設計2