2012-11-21 130 views
0

我一直被轉換爲基類對象的指針轉換爲派生類的指針時感到困惑。 請檢查下面的代碼:將指針轉換爲基礎對象轉換爲派生類的指針

derivate_class *d1 = (derivate_class*)cb; 
d1->print(); 
d1->print1(); 

結果是:

  • 我在基地的虛函數。
  • 我是派生類中的函數。
  • 任何人都可以幫我解釋爲什麼d1->print()打印「我是基地的虛擬功能」?

    #include <iostream> 
    using namespace std; 
    
    class base 
    { 
    public: 
        virtual void print() 
        { 
         cout << "I'm a virtual function in base." << endl; 
        } 
    }; 
    
    class derivate_class : public base 
    { 
    public: 
        void print() 
        { 
         cout << "I rewrite the virtual function in base." << endl; 
        } 
    
        void print1() 
        { 
         cout << "I'm a function in derivate class." << endl; 
        } 
    }; 
    
    int main() 
    { 
        base* b = new base(); 
        derivate_class *d = new derivate_class(); 
        b->print(); 
        d->print1(); 
        base* cb = b; 
        b = d; 
        b->print(); 
        cout << "*********************" << endl; 
    
        derivate_class *d1 = (derivate_class*)cb; 
        d1->print(); 
        d1->print1(); 
    
        system("pause"); 
        return 0; 
    } 
    
    +0

    您正在調用[UB](http://en.wikipedia.org/wiki/Undefined_behavior) - 任何事情都可能發生。切換到'dynamic_cast <>'而不是C風格強制轉換並檢查nullptr。 – ildjarn

    +0

    @ildjarn,非常感謝您的回覆。我正在閱讀STL的源代碼。在鏈接列表的STL中,它有一些代碼可將指針轉換爲基礎對象,並將其轉換爲派生類的指針。所以我在這個問題中編寫代碼來測試如果將指針轉換爲基礎對象到派生類的指針會發生什麼。我真正的問題是,我們什麼時候需要將指針轉換爲基礎對象到派生類的指針?我將在下面發佈STL代碼。 – Fihop

    +0

    @ildjarn,我開始一個新的問題:http://stackoverflow.com/questions/13486010/why-c-allow-converting-pointer-to-base-object-into-pointer-of-derivate-class – Fihop

    回答

    2

    這是UB,所以任何事情都可能發生。

    但是這裏有一個解釋:d1實際上並不指向derivate_class,而是指base

    base* b = new base(); 
    //... 
    base* cb = b; 
    derivate_class *d1 = (derivate_class*)cb; 
    d1->print(); 
    d1->print1(); 
    

    該調用是動態解析的,因爲它是通過指針和方法爲virtual

    print1不是virtual所以這個調用是靜態解析的。 print然而是virtual,所以調用派生類型最多的實現。但在這種情況下,派生最多的類型實際上是base

    在引擎蓋下,在cb中的vfptr指向的虛函數表中查找方法print。由於cvbase,該表將是base的表,其包含功能printbase::print實現。這就是爲什麼這是被調用的功能。

    +0

    謝謝所以很多爲您的答覆。我正在閱讀STL的源代碼。在鏈接列表的STL中,它有一些代碼可將指針轉換爲基礎對象,並將其轉換爲派生類的指針。所以我在這個問題中編寫代碼來測試如果將指針轉換爲基礎對象到派生類的指針會發生什麼。我真正的問題是,我們什麼時候需要將指針轉換爲基礎對象到派生類的指針?我將在下面發佈STL代碼。 – Fihop

    +0

    我開始一個新的問題:http://stackoverflow.com/questions/13486010/why-c-allow-converting-pointer-to-base-object-into-pointer-of-derivate-class – Fihop

    0

    d1是一個derivate_class指針,但它實際指向的數據(cb)是base類型的。由於print()是虛擬的,因此調用會動態解析,因此它將在虛函數表中找到基的實現,而不是derivate_class's。

    相關問題