2013-01-13 105 views
1

我在使用虛擬方法時遇到問題。當我打電話f它不起作用。爲什麼?爲什麼我的虛函數沒有被調用?

#include <iostream> 

struct A { 
    virtual void f() const { std::cout << "In A"; } 
    virtual ~A() {}; 
}; 

struct B : A { 
    void f() const { std::cout << "In B"; } 
}; 

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

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

    (*b).f(); 


    delete a; 
} 

它根本不打印任何東西,我也沒有得到任何錯誤。我做錯了什麼?

+1

總是檢查'dynamic_cast'的結果。 – chris

+1

B是A,但A不是B. – Bart

回答

10

什麼是錯誤的是你沒有檢查是否重新調整指針是NULL

dynamic_cast告訴你a指出的實際物體是b的類型,這顯然不是。在這種情況下,它會返回給您NULL

基本上,您正在取消引用NULL指針,導致未定義行爲不幸的是您不會崩潰。

當您使用語言提供的功能時,應按照標準規定的方式使用它。使用dynamic_cast保證返回指針的NULL檢查。

您的指針a實際上應該指向派生類對象b。您需要:

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

而且,你的代碼必須檢查返回指針:

if(b != NULL) 
     (*b).f(); 
+0

如果你不想檢查'NULL'(但你爲什麼不這樣做?),你可以'dynamic_cast'改爲引用類型;那麼失敗的轉換會拋出異常而不是返回NULL。 –

7

這條線:

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

給你一個空指針,因爲a不以事實上指向B

下面一行是未定義的行爲。 (你很幸運,沒有任何事情發生。)

+0

我該如何解決? –

+0

@大衛,有一個有效的'B'對象。 – chris

+0

完全取決於你要做什麼。你可以做'A * a =新B;'...... – aschepler

相關問題