條款39 避免 向下轉換 繼承層次

2022-03-17 19:21:41 字數 695 閱讀 8780

基類指標不能呼叫派生類的獨有的成員,即使基類指標指向派生類物件,因為編譯器是根據指標的靜態型別來確定呼叫物件在記憶體中佔據的空間的。此時可以使用static_cast來轉換,但不要這麼做,因為向下轉換難看、容易導致錯誤,而且使得**難於理解、公升級和維護,static_cast不會進行型別檢查,即使指標指向的物件的型別與轉換的目標型別不一樣,比如說指標指向基類物件,轉換為派生類物件,此時仍然會繼續轉換,當執行時若該指標嘗試呼叫派生類獨有成員會出錯。

"向下轉換" 可以通過幾種方法來消除。最好的方法是將這種轉換用虛函式呼叫來代替(程式執行時根據指標的動態型別來呼叫對應的函式),同時,它可能對有些類不適用(多個派生類,有的派生類需要該函式,有的派生類不需要,此時讓其繼承基類的虛函式而不覆蓋),所以要使這些類的每個虛函式成為乙個空操作。第二個方法是加強型別約束,使得指標的宣告型別(靜態型別)和你所知道的真的指標型別(動態型別)之間沒有出入。

但是,有的情況下不得不執行向下型別轉換:基類指標呼叫派生類成員,該成員是派生類獨有的,且不能修改類的定義,使得該函式成為基類的虛函式。

此時有比上面那種原始轉換更好的辦法。這種方法稱為 "安全的向下轉換",它通過c++的dynamic_cast運算子(參見條款m2)來實現。當對乙個指標使用dynamic_cast時,先嘗試轉換,如果成功(即,指標的動態型別(見條款38)和正被轉換的型別一致),就返回新型別的合法指標;如果dynamic_cast失敗,返回空指標,vs2013中會編譯出錯

條款39 明智的使用private繼承

首先看一下private繼承的法則 class之間的繼承關係如果是private的話,那麼編譯器不會將乙個derived物件自動當作為乙個base class物件。從base class繼承而來的所有方法以及屬性,在derived class都會變成是private的。private繼承的底層含義實...

條款 33 避免繼承而來的名稱

避免繼承而來的名稱 一朵玫瑰叫任何名字還是一樣芬芳 莎士比亞 子類中查詢乙個成員的的名字的方法 1子類作用域 2 基類作用域 3 內含基類的名字空間 4 全域性 includeclass base void mf3 double class derived public base void mf3 ...

條款33 避免遮掩繼承而來的名稱

問題 base class 中的所有名為 mf1 和 mf3 的函式被 derived class 中的名為 mf1 和 mf3 的函式覆蓋。從名字搜尋的觀點看,base mf1 和 base mf3 不再被 derived 繼承!就像你看到的,即使 base 和 derived classes 中...