理解C++ dynamic_cast

來源:互聯網
上載者:User

在物件導向程式設計中,有時我們需要在運行時查詢一個對象是否能作為某種多態類型使用。與Java的instanceof,以及C#的as、is運算子類似,C++提供了dynamic_cast函數用於動態轉型。相比C風格的強制類型轉換和C++ reinterpret_cast,dynamic_cast提供了型別安全檢查,是一種基於能力查詢(Capability Query)的轉換,所以在多態類型間進行轉換更提倡採用dynamic_cast。本文主要介紹dynamic_cast的意義,用法和注意事項。

 

基本用法

dynamic_cast可以擷取目標對象的引用或指標:

T1 obj;

T2* pObj = dynamic_cast<T2*>(&obj);//轉換為T2指標,失敗返回NULL

T2& refObj = dynamic_cast<T2&>(obj);//轉換為T2引用,失敗拋出bad_cast異常

 

多態類型

在使用時需要注意:被轉換對象obj的類型T1必須是多態類型,即T1必須公有繼承自其它類,或者T1擁有虛函數(繼承或自訂)。若T1為非多態類型,使用dynamic_cast會報編譯錯誤。下面的例子說明了哪些類屬於多態類型,哪些類不是:

//A為非多態類型

class A{

};

//B為多態類型

class B{

    public: virtual ~B(){}

};

//D為多態類型

class D: public A{

};

//E為非多態類型

class E : private A{

};

//F為多態類型

class F : private B{

}

 

橫向轉型

在多態類型間轉換,分為3種類型:

1.子類向基類的向上轉型(Up Cast)

2.基類向子類的向下轉型(Down Cast)

3.橫向轉型(Cross Cast)

向上轉型是多態的基礎,需不要藉助任何特殊的方法,只需用將子類的指標或引用賦給基類的指標或引用即可,當然dynamic_cast也支援向上轉型,而其總是肯定成功的。而對於向下轉型和橫向轉型來講,其實對於dynamic_cast並沒有任何區別,它們都屬於能力查詢。為了理解方便,我們不妨把dynamic_cast視為cross cast:

class Shape {

    public: virtual ~Shape();

    virtual void draw() const = 0;

};

class Rollable {

    public: virtual ~Rollable();

    virtual void roll() = 0;

};

class Circle : public Shape, public Rollable {

    void draw() const;

    void roll();

};

class Square : public Shape {

    void draw() const;

};

 

//橫向轉型失敗

Shape *pShape1 = new Square();

Rollable *pRollable1 = dynamic_cast<Rollable*>(pShape2);//pRollable為NULL

//橫向轉型成功

Shape *pShape2 = new Circle();

Rollable *pRollable2 = dynamic_cast<Rollable*>(pShape2);//pRollable不為NULL

 

指標比較

接上面的例子,在我的機器上pShape2和pRollable2的值(所指向的地址)分別為:

pShape2: 0x0039A294, pRollable2:0x0039A290

說明dynamic_cast在進行轉型的時候對不同多態類型設定了不同的位移量。接下來的問題是

pRollable2 == pShape2

這個運算式應該返回什麼呢?答案是:1,即指標比較相等。也許從C語言轉到C++的朋友可能會感到困惑,因為在C語言中指標的比較只是值比較而已。顯然,對於多態類型,C++編譯器為==運算子做了更多的幕後工作來保證指標比較注重對象的同一性而非指標的值。至於實現細節涉及到C++物件模型,這是我還不甚熟悉的內容,故本文不再深入。

 

參考

C++ Common Knowledge Item27,28

C++ Typecasting

 

文中若有錯誤和不足,歡迎各位批評指正!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.