2017-09-15 55 views
1
#include<iostream> 
using namespace std; 

class Mahesh 
{ 

    public: 
     Mahesh(){ 
     cout<<"Base Constructor is called at here"<<endl<<endl; 
     } 
     virtual ~ Mahesh() 
     { 
     cout<<"Base Destructor is called"<<endl<<endl; 
     } 
}; 

class Purnima:public Mahesh 
{ 

    public: 

     Purnima() 
     { 
     cout<<"Derived class constructor"<<endl<<endl; 
     } 
     ~Purnima(){ 
     cout<<"Derived class Destructor"<<endl<<endl; 
     } 
}; 

int main() 
{ 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 

    return 0; 
} 

我的問題是,如果我不析構函數的前面,然後上面的代碼寫關鍵字virtual工作正常,那麼爲什麼虛析構函數?省略關鍵字析構函數之前虛擬仍然工作幾乎

+1

更好的重複:https://stackoverflow.com/q/461203/501250 – cdhowie

+4

重複都不合適。答案是'virtual'是繼承的,無論你是否在派生析構函數中重新指定它。 – EJP

+3

你甚至從不會以多態的方式調用析構函數。你基本上正在測試銷燬派生類調用父類和派生類的析構函數。 – chris

回答

0

當你寫這樣

int main() 
{ 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 

    return 0; 
} 

代碼你得到Purnima p1自動銷燬當你超出範圍..這就是爲什麼你會得到適當的析構函數序列調用。

無論如何,你不能刪除m1,否則它的崩潰。

嘗試在範圍內封閉以更好地理解它。

int main() 
{ 
    { 
    Mahesh *m1; 
    Purnima p1; 
    m1=&p1; 
    } 
    cout<<"After Scope.."<<endl; 

    return 0; 
} 

「應用範圍」應在析構函數調用後打印。

所以,總之,你的動態類型打交道時需要virtual

+0

當我想知道如果將unique_ptr指定爲指向局部變量時會發生什麼,我對此有類似的想法。原來他們不是完全白癡的證明。 – Zebrafish

1

在這段代碼沒有什麼需要一個虛析構函數,它確實是這樣,事實上,做工精細。如果通過指向基本類型的指針刪除派生類型的對象,則需要虛擬析構函數。就像這樣:

Mahesh *m1 = new Purnima; 
delete m1; 

如果Mahesh的析構函數不是虛擬的,這個代碼未定義的行爲。注意:未定義行爲最隱祕的表現之一是代碼「正常工作」,直到您在其他地方稍作改動,準備向最重要的客戶展示演示,此時它將會慘敗。

+0

您忘記提及,一旦問題變得明顯,找到原因所需的時間與可用於解決問題的時間量呈負相關。你擁有的時間越少,你需要的就越多。 :-) – Peter