[英]Why not call Destructor in C++?
我学习C++
概念。 我对构造函数和Destractor概念感到困惑。 退出程序时,编译器将隐式调用析构函数。 但是在我的程序中,只有构造函数被调用。
#include <iostream>
using namespace std;
class A
{
int i;
public:
A()
{
cout<<"Constructor call"<<endl;
}
~A()
{
cout<<"Destructtor call"<<endl;
}
};
int main()
{
A *a = new A();
}
输出:
Constructor call
因此,我有一个问题: 为什么析构函数在退出程序时不由编译器隐式调用?
为什么析构函数在退出程序时不由编译器隐式调用?
因为动态分配的对象不会自动销毁。 这就是指定语言的方式。 跟踪动态对象的破坏将需要运行时/内存开销。
解决方案:不要泄漏动态分配的对象。
在C ++中,变量生存期有2种“类型”。 动态和自动的。
自动是这样的:
void foo()
{
int i; // automatic storage
} // destroys i
在这里, i
离开作用域的那一刻(在foo
返回之后)将被破坏。 您可以通过使对象具有自动生存期来自己检查此问题:
int main()
{
A a; // calls A's constructor and allocates memory.
} //calls A's destructor and frees the memory used.
您将看到构造函数和析构函数都将被调用。
第二种形式是动态分配的内存。 您可以使用new
来动态分配内存(就像您一样),并使用delete
释放该内存。 编译器不会为您执行此操作。 这意味着,要破坏对象,您必须自己调用显式delete
:
int main()
{
A* a = new A();
delete a; // calls A's destructor and frees the memory used.
}
如果您不调用delete
(如您的代码),那么在程序离开main
指针的那一刻,指针a
被破坏了,现在我们有一块内存,什么也无法到达,因此没有人可以清理(使用delete
),这意味着您内存泄漏 。
但是,现代操作系统会在程序结束时自动回收该程序使用的所有内存,因此此时并没有太大关系。 这确实意味着您的析构函数将不会像您刚刚看到的那样被调用。
动态分配的内存使您可以执行一些巧妙的技巧,例如将对象的生存期控制到要使用delete
明确销毁对象的程度。 使用new
和delete
的问题在于,忘记单个delete
非常容易,并且您的程序已经泄漏了内存,这就是为什么建议您远离这种分配方式的原因。
如果出于某种原因您绝对需要动态生存期,请使用诸如std::unique_ptr
类的智能指针,它将在超出范围时立即调用new
并delete
它。
您可以使用new
动态创建对象。 仅当使用delete
时,才会调用析构函数。
为了防止内存泄漏,您可以/应该使用诸如unique_ptr
类的智能指针。
无论如何,进程结束时,内存本身当然会被释放。
在您的代码中永远不会调用析构函数,因为该对象永远不会被破坏。
您动态分配A
对象,并且永远不会取消分配它。 添加delete a;
进入main()
,您将看到析构函数在起作用:
int main()
{
A *a = new A();
delete a;
return 0;
}
在主函数中,创建一个指针变量,必须通过在主函数末尾delete a
来删除它。
因为您有内存泄漏。 您动态地使用new
对象创建了一个对象,并承诺将管理该对象的生存期,并在以后使用delete
。 然后,您违反了诺言。
如果以通常的方式创建对象:
A a;
它将自动为您销毁。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.