2013-07-28 29 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调用。

如果你把这个功能放在课后,它会正常工作。