Understanding Dynamic_cast in C++

在面向對象程序設計中,有時咱們須要在運行時查詢一個對象是否能做爲某種多態類型使用。與Java的instanceof,以及C#的as、is運算符相似,C++提供了dynamic_cast函數用於動態轉型。相比C風格的強制類型轉換和C++ reinterpret_castdynamic_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會報編譯錯誤。下面的例子說明了哪些類屬於多態類型,哪些類不是:code

//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:it

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

指針比較編譯

接上面的例子,在個人機器上pShape2pRollable2的值(所指向的地址)分別爲: pShape2: 0x0039A294, pRollable2:0x0039A290ast

說明dynamic_cast在進行轉型的時候對不一樣多態類型設置了不一樣的偏移量。接下來的問題是 pRollable2 == pShape2

相關文章
相關標籤/搜索