我无法帮助阅读关于析构函数的大量论坛帖子并完全混淆.
有人说调用析构函数(带delete)一次为每个调用到new.有人说析构函数会在各种情况下自动调用,即 当指针被重新分配时,当对象超出范围时.有人建议指针超出范围,同时作为返回值,其中对象作为其前自身的副本存在,(这是否需要显式销毁,因为它最初是用new?创建的?
似乎有一些建议是不止一次地调用相同的析构函数会破坏内存,因此所有delete调用都应该与之合作*pointer = NULL;以避免损坏.如果没有,那么一些更高级的对象管理系统将需要实施,或铁腕严格的所有权.
我似乎无法对调用析构函数序列进行任何讨论,即调用1)是否源自基类超类并级联到特定类,在路上调用所有虚拟化析构函数,2)源于实例化class并向上移动到超类,或3)发起类在超出范围时所具有的特定强制转换,然后遍历实例化和基类.做级联析构
最终,我根本不知道如何或何时删除对象,无论对象是否负责删除它们引用的所有对象,如何干净地处理适当的面向对象的删除例程,其中多次引用对象,它只是一个我脑子里一团糟.正如你所看到的那样,我无法真正提出一个可靠的问题,我真的希望有人可以提供一个简洁而简洁的讨论,如果不是单一的"正确"方法,至少是行业最佳实践来反对删除.
有三种类型的分配,以不同的方式调用析构函数:
这些对象驻留在自动内存中(通常是堆栈):
int main()
{
A a;
//...
}
Run Code Online (Sandbox Code Playgroud)
超出范围(关闭)a时a会自动调用析构函数}.
对象驻留在动态内存(堆)中.它们被分配,new并且为了调用dstructor,你需要调用delete:
int main()
{
A* a = new A;
delete a; //destructor called
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,可能建议你应该NULL在a之后分配delete.关于这个有两种思想流派(我个人不会建议).如果你没有设置它,你可能会delete再次调用a并崩溃程序NULL.哪个是对的.但是,如果你delete再次打电话,这已经是一个错误或逻辑上的错误,不应该通过使代码看起来正确运行来掩盖.
对象驻留在static内存中.无论它们在何处分配,程序结束时都会自动调用析构函数:
A a; //namespace scope
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
这里,A在程序终止后,在main完成后调用析构函数.