2016-05-12 42 views
3

我試圖將基類對象轉換爲派生類對象dynamic_cast,但dynamic_cast返回null。是否有可能使用dynamic_cast倒置?使用dynamic_cast向下轉換返回null

struct A { 
    virtual ~A() {} 
}; 

struct B : A {}; 


int main() 
{ 
    A* a = new A(); 

    B* b = dynamic_cast<B*>(a); 
    if(b){ 
     std::cout << "b has value" << std::endl; 
    }else{ 
     std::cout << "no value" << std::endl; 
    } 
} 

此代碼打印出「沒有值」。

+0

FYI鑄造*向下*繼承鏈被稱爲向下鑄造。 – NathanOliver

+2

你不能從A那裏得到一個B,這個語言會怎麼做,例如, B實例擁有比A實例更多的數據成員? –

+3

你不能將'a'降爲'B *',因爲它不指向'B',它指向'A':'A'不是'B'。然而,你可以將'B *'轉換爲'A *',因爲'B *'會指向一個B,這個「是一個」A(繼承的定義) – KABoissonneault

回答

14

因爲a實際上指向的是A,而不是B,那麼dynamic_cast將會失敗。

是否可以使用dynamic_cast向下傾倒?

是的,你可以,例如,如果a指向B準確地說,

A* a = new B; 
B* b = dynamic_cast<B*>(a); 

參見http://en.cppreference.com/w/cpp/language/dynamic_cast

5)如表達式是一個指針或引用一個多態型Base和NEW_TYPE是一個指針或引用派生一個運行的類型執行時間檢查:

a)檢查由表達式指出/識別的派生最多的對象。如果在該對象中,表達式點/指的是派生的公共基礎,並且如果只有一個派生類型的子對象從由該表達式指向/標識的子對象派生,那麼拋出的結果指向/指向該派生子對象。 (這被稱爲 「垂頭喪氣」。)

...

c)否則,運行時檢查失敗。如果在指針上使用dynamic_cast,則返回類型爲new_type的空指針值。如果在引用上使用它,則拋出異常std::bad_cast

+0

如果基礎對象能夠使用'dynamic_cast'已經刪除了默認的ctor,只能用靜態函數'create'創建? – Herrgott

+0

@Herrgott是的。 'dynamic_cast'與指針和引用一起工作,它不涉及基類的默認構造函數。 – songyuanyao

4

即每個設計。當您想要測試指向基類對象的指針是否實際指向子類時,將使用dynamic_cast。如果它是一個子類對象,那麼dynamic_cast會給你一個有效的指針,如果它不是,你只會得到一個nullptr

當您創建A類對象,並且A不是B的子類時,dynamic_cast通常返回空指針。