C++ 中 dynamic_cast 淺析


簡述:
dynamic_cast 操作符,將基類的指針或引用安全的轉換為派生類的指針或引用。主要講解,dynamic_cast操作符的原理、使用方式、編譯器設置、返回值等相關知識。
dynamic_cast 操作符,將基類的指針或引用安全的轉換為派生類的指針或引用。
1. 原理
  將一個基類對象指針(或引用)cast (拋)到繼承類指針,dynamic_cast 會根據基類指針是否真正指向繼承類指針來做相應處理。

2. 返回值
  對指針進行dynamic_cast,失敗返回null,成功返回正常cast后的對象指針;
  對引用進行dynamic_cast,失敗拋出一個異常,成功返回正常cast后的對象引用。 
3. 注意
  dynamic_cast在將父類cast到子類時,父類必須要有虛函數。
4. 對編譯器的要求
  dynamic_cast<> 會用到RTTI技術,因此需要啟動“運行時類型信息”這一選項,而在VC.net 2003中默認是關閉的。所以,需要人為的啟動這一選項。否則編譯器會警告:   
warning C4541: “dynamic_cast”用在了帶 /GR- 的多態類型“CBasic”上;可能導致不可預知的行為從而導致程序在運行時發生異常。 
5. 編譯器設置方法
  在 Project->Setting中 C/C++ -> C++ Language中設置。 
首先,dynamic_cast依賴於RTTI信息,其次,在轉換時,dynamic_cast會檢查轉換的source對象是否真的可以轉換成target類型,這種檢查不是語法上的,而是真實情況的檢查。
先看RTTI相關部分,通常,許多編譯器都是通過vtable找到對象的RTTI信息的,這也就意味着,如果基類沒有虛方法,也就無法判斷一個基類指針變量所指對象的真實類型, 這時候,dynamic_cast只能用來做安全的轉換,例如從派生類指針轉換成基類指針。而這種轉換其實並不需要dynamic_cast參與。
也就是說,dynamic_cast是根據RTTI記載的信息來判斷類型轉換是否合法的。
下面看一個例子:
struct B1{
    virtual ~B1(){}
};
struct B2{
    virtual ~B2(){}
};
struct D1 : B1, B2{};
int main()
{
    D1 d;
    B1* pb1 = &d;
    B2* pb2 = dynamic_cast<B2*>(pb1);//L1
    B2* pb22 = static_cast<B2*>(pb1);  //L2
    return 0;
}
上述定義中可以看到,B1和B2是不相關的類,從L1可以看到,dynamic_cast允許這種轉換:只要B1存在多態方法。
L2將編譯失敗,static_cast並不允許兩個完全不相干的類互相轉換。

 
        
進一步分析可參見:http://www.cnblogs.com/weidagang2046/archive/2010/04/10/1709226.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM