2011-04-29 112 views
14

我有兩個類:類有虛函數和可訪問的非虛擬析構函數

class A { 
public: 
    virtual void somefunction() = 0; 
}; 

class B : public A { 
public: 
    B(); 
    ~B(); 
    void somefunction(); 
}; 

B::B() {} 

void B::somefunction() { 
    // some code 
} 

但隨着G ++我得到的錯誤:

class A has virtual functions and accessible non-virtual destructor 
class B has virtual functions and accessible non-virtual destructor 

我沒有任何想法,這個錯誤是什麼...在博客上的某處,我讀到它是一個編譯器警告。我該如何解決這個問題?

回答

16

發生這種情況是因爲您的基類A沒有虛擬析構函數。舉例來說,如果你有這樣的代碼:

int main() 
{ 
    A* a = new B; 
    delete a; 
} 

然後delete a通話將無法調用B的析構函數,因爲A的不是虛擬的。 (它會泄漏B的所有資源。)您可以read more about virtual destructors here

添加一個虛擬析構函數到你的基類,你應該沒問題。

class A 
{ 
public: 
    virtual void somefunction() = 0; 
    virtual ~A() = 0; 
} 
+1

我試過這個,但它給出了A ::〜A() – SPB 2011-04-29 04:29:17

+2

@SPB的未定義的引用它意味着它找不到你的析構函數的實現。寫一個微不足道的,如果你沒有什麼可以實際銷燬的話。 'A ::〜A(){}'應該這樣做。 – zneak 2011-04-29 04:31:18

+0

雅它幫助..感謝..解釋是好的。 – SPB 2011-04-29 04:39:44

6

給予A級:

virtual ~A() { } 

這樣,派生類如B仍將有人稱他們的自定義析構函數,如果你delete他們通過A*

3

如果一個類具有虛函數,那麼它的析構函數也應該是虛擬的。你有一個可訪問的析構函數,但它不是虛擬的。

2

作爲一個經驗法則(恕我直言)或短的析構函數在基類必須是公共的和虛擬或受保護的非虛擬防止記憶leaks.by這樣的析構函數的派生類得到並且這可以防止每當基址指針/引用持有派生的地址/引用被刪除。