简体   繁体   English

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

[英]Why not call Destructor in C++?

I studding C++ concept. 我学习C++概念。 I'm confused in constructor and Destractor concept. 我对构造函数和Destractor概念感到困惑。 Destructor will be invoked implicitly by the compiler upon exit from the program. 退出程序时,编译器将隐式调用析构函数。 But in my program, only constructor called. 但是在我的程序中,只有构造函数被调用。

#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();
}

Output: 输出:

Constructor call

So, I have question : Why destructor not call implicit by the compiler upon exit program? 因此,我有一个问题: 为什么析构函数在退出程序时不由编译器隐式调用?

Why destructor not call implicit by the compiler upon exit program? 为什么析构函数在退出程序时不由编译器隐式调用?

Because dynamically allocated objects are not destroyed automatically. 因为动态分配的对象不会自动销毁。 That is how the language has been specified. 这就是指定语言的方式。 Tracking the destruction of dynamic objects would require runtime / memory overhead. 跟踪动态对象的破坏将需要运行时/内存开销。

Solution: Do not leak dynamically allocated objects. 解决方案:不要泄漏动态分配的对象。

There are 2 "types" of variable lifetime in C++. 在C ++中,变量生存期有2种“类型”。 Dynamic and automatic. 动态和自动的。

Automatic is something like : 自动是这样的:

void foo()
{
  int i; // automatic storage
} // destroys i

Here, i will be destructed the moment it leaves scope (after foo returns). 在这里, i离开作用域的那一刻(在foo返回之后)将被破坏。 You can check this for yourself by making your object have an automatic lifetime: 您可以通过使对象具有自动生存期来自己检查此问题:

int main()
{
    A a; // calls A's constructor and allocates memory.
} //calls A's destructor and frees the memory used.

You'll see that both the constructor and the destructor will get called. 您将看到构造函数和析构函数都将被调用。


The second form is dynamically allocated memory. 第二种形式是动态分配的内存。 You can dynamically allocate memory by using new (like you did) and free that memory by using delete . 您可以使用new来动态分配内存(就像您一样),并使用delete释放该内存。 The compiler won't do this for you. 编译器不会为您执行此操作。 This means that, to destruct your object you have to call delete explicitly yourself: 这意味着,要破坏对象,您必须自己调用显式delete

int main()
{
        A* a = new A();
        delete a; // calls A's destructor and frees the memory used.
}

If you do not call delete (like your code) then the moment the program leaves main the pointer a is destroyed and now we have a piece of memory that nothing can reach and thus nobody can clean up (with delete ) which means you're leaking memory . 如果您不调用delete (如您的代码),那么在程序离开main指针的那一刻,指针a被破坏了,现在我们有一块内存,什么也无法到达,因此没有人可以清理(使用delete ),这意味着您内存泄漏

However, modern operating systems reclaim all memory used by the program automatically the moment the program ends so at this point it won't matter too much. 但是,现代操作系统会在程序结束时自动回收该程序使用的所有内存,因此此时并没有太大关系。 This does mean your destructor won't be called as you've just witnessed. 这确实意味着您的析构函数将不会像您刚刚看到的那样被调用。


Dynamically allocated memory allows you to do some nifty tricks like controlling the lifetime of your objects to the point where you want to destroy them explicitly yourself with delete . 动态分配的内存使您可以执行一些巧妙的技巧,例如将对象的生存期控制到要使用delete明确销毁对象的程度。 The problem with using new and delete is that it's so easy to forget a single delete and your program will already leak memory, which is why it's advised to stay away from this way of allocation. 使用newdelete的问题在于,忘记单个delete非常容易,并且您的程序已经泄漏了内存,这就是为什么建议您远离这种分配方式的原因。

If for some reason you absolutely need dynamic lifetime then use a smart pointer like std::unique_ptr that will call new and delete for you the moment it goes out of scope. 如果出于某种原因您绝对需要动态生存期,请使用诸如std::unique_ptr类的智能指针,它将在超出范围时立即调用newdelete它。

You create the object dynamically with new . 您可以使用new动态创建对象。 The destructor will only be called when the objected is deleted with delete . 仅当使用delete时,才会调用析构函数。

To prevent memory leaks, you could/should use smart pointers like unique_ptr . 为了防止内存泄漏,您可以/应该使用诸如unique_ptr类的智能指针。

In any case, the memory itself will of course be released when the process ends. 无论如何,进程结束时,内存本身当然会被释放。

The destructor is never called in your code because the object is never destroyed. 在您的代码中永远不会调用析构函数,因为该对象永远不会被破坏。

You dynamically allocate the A object and you never deallocate it. 您动态分配A对象,并且永远不会取消分配它。 Add delete a; 添加delete a; into main() and you'll see the destructor in action: 进入main() ,您将看到析构函数在起作用:

int main()
{
    A *a = new A();
    delete a;

    return 0;
}

在主函数中,创建一个指针变量,必须通过在主函数末尾delete a来删除它。

Because you have a memory leak. 因为您有内存泄漏。 You dynamically created an object with new , promising that you would manage the lifetime of the object and clean it up later with delete . 动态地使用new对象创建了一个对象,并承诺将管理该对象的生存期,并在以后使用delete Then you broke that promise. 然后,您违反了诺言。

If you create an object in the usual fashion: 如果以通常的方式创建对象:

A a;

then it will be destroyed automatically for you. 它将自动为您销毁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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