2016-09-24 71 views
-2

我正在學習多態,這是我偶然發現的。我無法找到滿意的答案,並測試下面的代碼不會產生預期的結果。C++刪除類指針和多態性

#include <stdio.h> 
#include <iostream> 

class Base { 
    public: 
     Base(){ 
      std::cout<<"Constructing Base" << std::endl; 
     }; 
     virtual int get_a(){ 
      return p_a; 
     }; 
     virtual int check(){ 
      std::cout<<"check Base" << std::endl; return 2; 
     }; 
     virtual ~Base(){ 
      std::cout<<"Destroying Base" << std::endl; 
     }; 
     int p_a = 4; 
}; 

class Derive: public Base { 
    public: 
     Derive(){ 
      std::cout<<"Constructing Derive" << std::endl; 
     }; 
     int get_a(){ 
      return p_a; 
     }; 
     int check(){ 
      std::cout<<"check Derive" << std::endl; 
      return 3; 
     }; 
     ~Derive(){ std::cout<<"Destroying Derive" << std::endl; }; 
     int p_a = 2; 
}; 

int main() { 
     Base *basePtr = new Derive(); 
     delete basePtr; 
     basePtr->check(); 
     std::cout << "p_a: " << basePtr->get_a() << std::endl; 
     return 1; 
} 

控制檯輸出:

Constructing Base // line 1 
Constructing Derive // line 2 
Destroying Derive // line 3 
Destroying Base  // line 4 
check Base   // line 5 
p_a: 4    // line 6 

我明白爲什麼我得到線1-4中,basePtr是指針來導出,它從基地,它實現了虛擬函數繼承。

我的期望:在調用刪除之後,指針basePtr不應該能夠傳遞函數調用 - > check(),並且也不應該有值p_a。

我的期望:我期望Derive(p_a = 2)的值p_a出現在輸出中,因爲basePtr存儲了Derive的指針。

有人能糾正我的想法嗎?

+0

這就是爲什麼總是將您剛剛刪除的指針設置爲nullptr是個好主意。 –

+0

*指針basePtr不應該能夠傳遞函數調用 - > check(),* - 爲什麼不呢?你的代碼說要這麼做,那就是發生了什麼事。如果你告訴C++去做某件事,那麼它就是這樣做的,無論你要求做什麼都可能需要不希望的結果。 – PaulMcKenzie

+0

@BasinhetVeld:呃......這就是爲什麼你**不會在C++中使用指針。具有自動存儲持續時間的對象非常棒,包括諸如'std :: unique_ptr'之類的智能指針類型。 – IInspectable

回答

2

這是未定義的行爲。無論你得到什麼結果,都是無效的。

delete basePtr; 

這破壞了對象。

basePtr->check(); 

銷燬對象後,將示出代碼試圖取消引用一個指針的類的實例被破壞,並調用銷燬的對象的方法。調用被銷燬對象的方法是未定義的行爲。