2012-01-23 111 views
8
/*Child is inherited from Parent*/ 
class Parent { 
    public: 
    Parent() //Constructor 
    { 
     cout << "\n Parent constructor called\n" << endl; 
    } 
    protected: 
    ~Parent() //Dtor 
    { 
     cout << "\n Parent destructor called\n" << endl; 
    } 
}; 

class Child : public Parent 
{ 
    public: 
    Child() //Ctor 
    { 
     cout << "\nChild constructor called\n" << endl; 
    } 
    ~Child() //dtor 
    { 
     cout << "\nChild destructor called\n" << endl; 
    } 
}; 

int main() 
{ 
    Parent * p2 = new Child;   
    delete p2; 
    return 0; 
} 

如果我使Parent的析構函數爲虛擬的,那麼我得到一個錯誤,那麼使受保護的析構函數成爲虛擬的目的是什麼?有沒有用於使受保護的析構函數虛擬?

+1

也許我們應該從「爲什麼要讓dtor保護?」開始。 –

+4

你爲什麼想要使析構函數爲虛擬?不應該*你*知道目的?受保護的析構函數意味着對象不應該通過基本指針被破壞,所以'main'中的代碼是錯誤的。 – thiton

+0

請參閱http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors – user998692

回答

17

舉一個例子:假設你有一個實現引用計數的基類。如果(只有,如果)內部計數器通過調用release達到零,則您有一個addRefrelease方法,並且希望將對象銷燬。

所以,首先你要保護你的析構函數(因爲你只想破壞relase中的對象)。

如果你打算從你的類派生,你也希望你的析構函數是虛擬的,因爲當你想通過指向基類的指針銷燬一個子對象時,你需要一個虛擬析構函數(謝謝@sharptooth提示...)

+2

不,你需要一個虛擬析構函數,而不管派生類是否需要額外的銷燬,否則行爲只是未定義的。 – sharptooth

+0

@sharptooth對,我沒有想到這一點。修好了,謝謝指出! – MartinStettner

+0

我看到一些使用這個技巧的代碼強制所有銷燬都通過朋友C風格的包裝函數(根據派生類定義)。我想這個意圖是相似的,但是在維護中失去了意義。 – Muxecoid

4

protected: Base::~Base();應該虛擬至少如果你(上圖)或刪除派生類的BaseBaseBase衍生的任何對象。

+0

刪除此;對於任何未知的孩子對象 得到它的感謝 – tusharfloyd

+0

@ user1085822:所以,你感謝我,而不接受我的答案。你想告訴我什麼? – bitmask

+0

不應該只是 – ksb

5

是的,如果你打算在class Parent中執行delete this成員函數,這在COM對象中實現IUnknown::Release()時非常常見。

+0

不錯。對於這個問題,如果有'depete pBase;'attampted的話,其他派生類。 – iammilind

相關問題