样品
void func(void* data)
{
CResource* resource = (CResource*)data;
delete resource; // ~CResource never called.
resource = NULL;
}
请帮我弄明白。
答案 0 :(得分:11)
总结可能无法调用CResource析构函数的原因,从其他答案中提取:
一个可能的原因是您只声明了CResource类型,未定义:
class CResource;
void func(void* data)
{
CResource* resource = (CResource*)data;
delete resource; // ~CResource never called.
resource = NULL;
}
这是一种未定义的行为(删除不完整的类型)。在这样的情况下,编译器应该发出关于未调用析构函数的警告(Visual C ++肯定会发出它)。如果是这种情况,请确保在您要销毁它的地方定义了类型(包括所需的标题)。
如果data为NULL,则delete不执行任何操作,也不会调用任何析构函数。
如果CResource析构函数是虚拟的,并且 data 指向的内存中存储的对象实际上是不同的类型,则会得到未定义的行为。通常会调用不同的析构函数(如果对象具有另一个虚拟析构函数),在其他情况下程序可能会崩溃(如果对象没有虚拟析构函数)。
答案 1 :(得分:6)
为什么不调用析构函数的唯一原因是数据指针是0(或NULL)。这就是删除的工作原理 - 它检查指针是否为0,如果不是,则调用必要的析构函数并释放内存。
正如评论中指出的那样。还有另一个原因就是它不会被调用。如果数据指向其他类(而不是CResource)对象,并且两个类都有虚拟析构函数,那么将调用该另一个类的析构函数。
答案 2 :(得分:3)
析构函数是虚拟的吗?也许数据根本不指向CResource对象,并且正在调用其他类的虚析构函数。
答案 3 :(得分:2)
class Aardvark
{
public:
virtual ~Aardvark()
{
printf("Aardvark::~Aardvark\n");
}
};
class CResource
{
public:
virtual ~CResource()
{
printf("CResource::~CResource\n");
}
};
void func(void* data)
{
CResource* resource = (CResource*)data;
delete resource; // ~CResource never called.
resource = NULL;
}
int _tmain()
{
void *data = new Aardvark();
func( data );
return 0;
}
答案 4 :(得分:0)
调用析构函数。给我们完整的代码。
答案 5 :(得分:0)
为什么你说dtor没有被叫? 可能是因为你在你的dtor中添加了printf,而你没有看到任何消息?
可能还会调用另一个dotr? CResource继承了吗?您是否定义了基类析构函数虚拟?
正如rajKumar指出的那样,给我们完整的代码,我们会尽力帮助你。
答案 6 :(得分:0)
我假设CResource是某种类的超类,允许您通过通用指针轻松传输对象。
那么你的问题对于C ++新手来说是正常的,你应该阅读
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7
此外,请获取Scott Meyer的“Effective C ++”副本,因为它会向您介绍您将在接下来的几个月内犯下的许多错误。