2012-01-07 67 views
0

我的問題是建立在這個問題上:Correct way to inherit from a virtual class with non-virtual parent正確的方式從具有非虛擬父項的虛擬課堂繼承

我的理解是正確的,在問題描述的情況下,新分配對象的三部分和二部分泄漏是因爲它們沒有被破壞?

來源:

#include <iostream> 

struct One 
{ 
    ~One() { 
     std::cout << "~One()\n"; 
    } 
}; 

struct Two : One 
{ 
    virtual ~Two() { 
     std::cout << "~Two()\n"; 
    } 

    virtual void test() = 0; 
}; 

struct Three : Two 
{ 
    virtual ~Three() { 
     std::cout << "~Three()\n"; 
    } 

    virtual void test() { 
     std::cout << "Three::test()\n"; 
    } 
}; 

int main() 
{ 
    Two* two = new Three; 
    two->test(); 

    One* one = two; 
    delete one; 
} 
+2

是的,這是正確的。我只是[回答了類似問題](http://stackoverflow.com/questions/8764353/what-does-has-virtual-method-but-non-virtual-destructor-warning-mean-durin/8764393#8764393)昨天。 – 2012-01-07 11:55:13

+0

請您可以編輯您的問題以包含上下文,以便我們不需要按照鏈接瞭解「兩個」和「三個」是什麼。 – 2012-01-07 11:59:53

+0

@OliCharlesworth完成 – inf 2012-01-07 12:09:26

回答

1

是的,這是正確的。內存泄漏的定義是您無法刪除您創建的某些內容(以及您因此負責管理的生命週期)的情況。

由於answers對這個問題表示,delete one調用未定義的行爲(在大多數情況下,可能會轉化爲一個普通的舊內存泄漏,但事情可能是一樣糟糕nasal demons),因爲指定對象的運行時類型不匹配它的靜態(聲明)類型,而靜態類型沒有虛擬析構函數。

從C++標準適用的部分是這樣的一種:

§5.3.5/ 3:在第一種方式(刪除對象),如果靜態類型的操作數是從它的動態類型不同,靜態類型應該是操作數動態類型的基類,並且靜態類型應該具有虛擬析構函數或行爲未定義。

解決方案是要麼聲明所有析構函數virtual的,或不通過指針刪除對象One