繁体   English   中英

为什么不使用C ++调用Destructor?

[英]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明确销毁对象的程度。 使用newdelete的问题在于,忘记单个delete非常容易,并且您的程序已经泄漏了内存,这就是为什么建议您远离这种分配方式的原因。

如果出于某种原因您绝对需要动态生存期,请使用诸如std::unique_ptr类的智能指针,它将在超出范围时立即调用newdelete它。

您可以使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM