2011-12-12 17 views
32

是否有可能繼承沒有虛擬方法?編譯器說以下代碼不是多態的。不能縮減因爲類不是多態嗎?

實施例:

Class A(){ 
    int a; 
    int getA(){return a;}; 
} 


Class B(): A(){ 
    int b; 
    int getB(){return b;}; 
} 

在另一類我們試圖從A目的是向下轉換到一個B對象:

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

但這提供了以下錯誤:

cannot dynamic_cast ... (source type is polymorphic) 
+1

'a'不是指針。這是如何在你的代碼? – littleadv

+0

對不起,a其實是一個指針。 – wbarksdale

+0

並且是錯誤編譯時間或運行時間?如果運行時,恕我直言,其預期的行爲。其編譯時錯誤爲 – littleadv

回答

56

語法錯誤不能承受,您不能dynamic_cast非多態類型。 static_cast是在這種情況下您將使用的演員,如果您知道它實際上是目標類型的對象。

原因:static_cast基本上有編譯器在編譯時執行檢查「可以將輸入轉換爲輸出嗎?」這可以用於在指針(或引用)的繼承層次上向下或向下轉換的情況。但是檢查僅在編譯時,編譯器假定你知道你在做什麼。

dynamic_cast只能在指針或引用轉換的情況下使用,除編譯時檢查外,它還會執行額外的運行時檢查轉換是否合法。它要求所討論的類至少有一個虛擬方法,它允許編譯器(如果它支持RTTI)執行這個額外的檢查。但是,如果有問題的類型沒有任何虛擬方法,則不能使用它。

最簡單的情況,如果你像這樣傳遞指針,可能是值得的,那就是考慮讓基類的析構函數變爲虛擬。除了允許使用動態轉換之外,它還允許在刪除基類指針時調用正確的析構函數。

+0

非常感謝這些知識。這解決了。 – wbarksdale

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

這裏a是一個對象,b是一個指針。

實際上,C++中都允許向上轉換和向下轉換。但是在使用向下轉換時,需要注意兩點: 1超類應該至少有一個虛擬方法。 2由於超類比子類「小」,所以應該仔細使用內存對象。

4

是的,不允許針對非多態類型的dynamic_cast。基類應該至少有一個虛擬方法。只有那個類可以被稱爲多態。

本文介紹了一個類似的例子:http://www.cplusplus.com/doc/tutorial/typecasting/

+0

戴夫給出了一個很好的答案。我無權評論他的帖子。所以,我在這裏評論。 –

18

您需要run-time type information (RTTI)類中的至少一個虛擬方法成功地應用dynamic_cast運算符。

11

只是使一個析構函數虛擬(爲了安全起見,總是爲任何類而做)。

+7

不適用於任何類,但對於打算成爲基類的類 – ParokshaX

相關問題