小古銀的官方**(完整教程):
使用 dynamic_cast 轉換引用
基類和派生類的智慧型指標轉換
#include // std::cout std::endl
class base
;class derived : public base
;int main(void)
從輸出結果可以看出,都是同乙個記憶體位址。
派生類的位址或者指標賦值給基類指標時,可以隱式轉換,也可以使用static_cast
顯示轉換,不過一般都用隱式轉換。
倒過來,基類指標賦值給派生類指標的時候,必須要顯示轉換。這個轉換,使用dynamic_cast
或者static_cast
都不會報錯。
dynamic_cast
和static_cast
的區別。
#include // std::boolalpha std::cout std::endl
class base
;class derived : public base
;class test : public base
;int main(void)
輸出結果:
derived指標儲存derivedobj的位址(dynamic_cast)
是否成功:true
是否成功:false
是否成功:true
是否成功:true
derived
類和test
類並不是乙個同乙個類,它們不應該可以互相轉換。
上面**中,static_cast
將derivedobj
的位址轉換成了test *
型別,這樣明顯是不正確的。因為static_cast
是在編譯期進行轉換,而分配堆記憶體是在程式執行的時候,記憶體位址每次也都不一樣,編譯器是無法安全檢測的。
而dynamic_cast
可以在執行的時候,對位址的實際型別進行檢測,當不能轉換的時候,將會返回乙個nullptr
值。上面**中,使用dynamic_cast
嘗試將derivedobj
的位址轉換成了test *
型別,由於不能轉換,所以轉換的結果就是nullptr
。
所以,基類指標(或引用)轉換成派生類指標(或引用)應該使用dynamic_cast
,這樣會更安全。
由於dynamic_cast
是在執行的時候進行檢測和轉換的,所以會影響到執行時的效能。
不過,在良好的程式設計中,不會也不應該頻繁地將基類指標(或引用)轉換成派生類指標(或引用),也就是說,不應該頻繁地使用dynamic_cast
。如果你的**頻繁地使用了dynamic_cast
,應該要考慮,繼承是否設計好。
因此,在良好的程式設計中,合理使用dynamic_cast
是沒有問題的。
#include // std::cout std::endl
#include // std::bad_cast
class base
;class derived : public base
;class test : public base
;int main(void)
trycatch (const std::bad_cast &)
輸出結果:
成功轉換成derived引用
轉換失敗
dynamic_cast
轉換指標時,轉換失敗可以通過nullptr
來表達,而引用就不能。所以dynamic_cast
轉換引用使用的是丟擲異常std::bad_cast
。std::bad_cast
在標準庫typeinfo
中。
基類和派生類的智慧型指標轉換要使用std::dynamic_pointer_cast
和std::static_pointer_cast
。由於std::dynamic_pointer_cast
和dynamic_cast
原理一樣,std::static_pointer_cast
和static_cast
原理一樣,所以下面就直接講解這兩個使用。
#include // std::cout std::endl
#include // std::shared_ptr std::dynamic_pointer_cast std::static_pointer_cast
class base
;class derived : public base
;class test : public base
;int main(void)
輸出結果:
false
true
C 基類和派生類
本講討論基類和派生類的基本概念。通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。在c 語言中,乙個派生類可以從乙個基類派生,也可...
C 基類和派生類
本講討論基類和派生類的基本概念。通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。在 c 語言中,乙個派生類可以從乙個基類派生,也...
C 基類和派生類
通過繼承機制,可以利用已有的資料型別來定義新的資料型別。所定義的新的資料型別不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱已存在的用來派生新類的類為基類,又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。在c 語言中,乙個派生類可以從乙個基類派生,也可以從多個基類派生。從乙個基類派生...