2013-07-28 73 views
13

之間的關係,我有以下代碼:向前聲明和析構函數

#include <iostream> 
using namespace std; 

class CForward; 

void func(CForward* frw) { delete frw; } 

class CForward 
{ 
public: 
    ~CForward() { cout << "Forward" << endl; } 
}; 

int main() 
{ 
    func(new CForward); 
    cin.get(); 
} 

我跑的程序,它印什麼。

爲什麼?

in main,我創建new CFoward,並在func我刪除它,並將其稱爲析構函數。

看來,析構函數還沒有被調用。爲什麼?無論如何,這與前瞻性的減損有關嗎?

+0

'g ++'實際上告訴你當你編譯這段代碼時發生了什麼。 – fuenfundachtzig

+2

至少提高編譯器的警告級別。這應該總是發出「刪除指向不完整類型的指針」診斷。 –

+0

GCC非常有用:'警告:在調用刪除操作符時檢測到可能的問題:[默認情況下啓用]'frw'具有不完整類型[默認情況下啓用]'CForward類的前向聲明'[缺省情況下啓用]析構函數,也不會調用特定於類的操作符delete,即使它們是在定義類時聲明的。 – juanchopanza

回答

12

事實上,您的向前聲明引入稍後與非平凡的析構函數定義的一個不完整的類型,和不能在一個刪除表達式中使用:

從n3337,段落5.3.5/5:

5如果對象被刪除在刪除的點具有不完整的類型和完整的類具有 非平凡的析構函數或解除分配功能,行爲理解過程音響定義。

+3

@ user1798362:如果你定義了你的類的析構函數(而不是僅僅使用編譯器生成的),它是非平凡的。遞歸地,如果你的類有非平凡析構函數的成員,你的類有一個非平凡的析構函數。所有其他的析構函數都是微不足道的(他們實際上並沒有做任何事情)。 –

1

是的。事實上,在函數func中,編譯器不知道cForward的完整類型。所以desctructor是neved調用。

如果你把這個功能放在課後,它會正常工作。