動態類型轉換dynamic_cast


  

  C++Primer第十九章的動態類型轉換部分講的不是很清楚,於是自己查cpp的官方手冊總結一下。

dynamic_cast < new-type > ( expression )        

  動態類型轉換是可以安全的在繼承體系將指針和引用進行向上、向下和橫向的轉換。其表達式的類型為運行時的動態類型。具體功能如下:

 

  一、和隱式轉換,靜態轉換static_cast一樣的功能

 

  1、增加const屬性:在expression和new-type類型相同或new-type為void*時,轉換結果為expression的指針或引用。並且可以在dynamic_cast前加上const限定符實現增加const屬性。

const dynamic_cast < new-type > ( expression ) 

  2、向上轉換upcast:和static_cast和隱式轉換一樣,dynamic_cast可以將派生類轉換為基類。

 

  二、dynamic_cast的特殊功能

  如果expression是一個指向具有多態特性的基類Base的指針或引用(靜態類型),new-type是一個指向派生類Derived對象的指針或引用,具體進行哪種轉換根據expression的動態類型判斷。

 

  1、向下轉換downcast:expression的動態類型為指向派生類Derived的指針或引用,並且Derived僅包含一份繼承自Base的對象,則轉換結果為指向Derived對象的指針或引用。(相當於從expressionh的父類轉換為子類

  2、橫向轉換sidecast:expression的動態類型為指向一個類的對象的指針或引用,該類公有繼承自Base和Derivied(Derived不一定繼承自Base)並且繼承自Derived的子成員是明確的(必須是虛繼承,不能有二義性)。則轉換結果為指向Derived的指針或引用。(相當於expression動態類型對象的一個父類轉換為另一個父類)

 

  三、轉換失敗時如果轉換目標是指針類型則返回空指針,引用類型拋出一個bad_cast異常。

  四、所謂安全是指編譯器會對dynamic_cast的對象進行類型檢查,而static_cast則不會。dynamic_cast相當於根據情況進行轉換,static_cast相當於不管情況如何強制進行轉換。

 

  這里直接使用官方例子

 1 #include <iostream>
 2  
 3 struct V {
 4     virtual void f() {}  // must be polymorphic to use runtime-checked dynamic_cast
 5 };
 6 struct A : virtual V {};
 7 struct B : virtual V {
 8   B(V* v, A* a) {
 9     // casts during construction (see the call in the constructor of D below)
10     dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
11     dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
12   }
13 };
14 struct D : A, B {
15     D() : B(static_cast<A*>(this), this) { }
16 };
17  
18 struct Base {
19     virtual ~Base() {}
20 };
21  
22 struct Derived: Base {
23     virtual void name() {}
24 };
25  
26 int main()
27 {
28     D d; // the most derived object
29     A& a = d; // upcast, dynamic_cast may be used, but unnecessary
30     [[maybe_unused]]
31     D& new_d = dynamic_cast<D&>(a); // downcast
32     [[maybe_unused]]
33     B& new_b = dynamic_cast<B&>(a); // sidecast
34  
35  
36     Base* b1 = new Base;
37     if(Derived* d = dynamic_cast<Derived*>(b1))
38     {
39         std::cout << "downcast from b1 to d successful\n";
40         d->name(); // safe to call
41     }
42  
43     Base* b2 = new Derived;
44     if(Derived* d = dynamic_cast<Derived*>(b2))
45     {
46         std::cout << "downcast from b2 to d successful\n";
47         d->name(); // safe to call
48     }
49  
50     delete b1;
51     delete b2;
52 }

  輸出結果

downcast from b2 to d successful

 

注意:所有C++標准的轉換均產生局部變量,不實際對原變量修改。

參考文獻:dynamic_cast conversion - cppreference.com


免責聲明!

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



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