C++: why it doesn't call a destructor?

与世无争的帅哥 提交于 2019-11-28 09:47:13

问题


I use extra brackets in my code. I thought when the destructor should be called after the local variable scope is ended but it doesn't work like this:

class TestClass {
public:
    TestClass() {
        printf( "TestClass()\n" );
    }
    ~TestClass() {
        printf( "~TestClass()\n" );
    }
};

int main() {
    int a, b, c;
    {
         TestClass *test = new TestClass();
    }
}

It outputs:

TestClass()

So it doesn't call the destructor of the TestClass but why? If I call it manually (delete test) it calls the destructor, right. But why it doesn't call the destructor in the first case?


回答1:


TestClass *test = new TestClass();

You using new which creates a dynamically allocated object (most likely placed on the heap). This type of resource needs to be manually managed by you. By managing, you should use delete on it after you have done using it.

{
     TestClass *test = new TestClass();
     // do something
     delete test;
}

But for the most of your purposes and intents, you just have to use automatic-storage objects, which frees you the hassle of having to manually manage the object. It would also most likely to have better performance especially in short-lived objects. You should always prefer to use them unless you have a really good reason not to do so.

{
     TestClass test;
     // do something
}

However, if you need the semantics of dynamically allocated objects or that of pointers, it will always be better to use some mechanism to encapsulate the deletion/freeing of the object/resource for you, which also provides you additional safety especially when you are using exceptions and conditional branches. In your case, it would be better if you use std::unique_ptr.

{
     std::unique_ptr<TestClass> test(new TestClass());
     // auto test = std::make_unique<TestClass>();  in C++14

     // do something (maybe you want to pass ownership of the pointer)
}


The following is a relevant link to help you decide whether to use automatic storage objects or dynamically allocated objects: Why should C++ programmers minimize use of 'new'?


回答2:


Because you have a pointer to a dynamically allocated object. Only the pointer goes out of scope, not the object it points to. You have to call delete on the pointer in order for the pointee's destructor to get called.

Try with an automatic storage object instead:

{
  TestClass test;
}

Here, the destructor will be called on exiting the scope.

The use of raw pointers to dynamically allocated objects in C++ is discouraged because it can easily lead to resource leaks like the one shown in your code example. If pointers to dynamically allocated objects are really needed, it is wise to handle them with a smart pointer, rather than to attempt to manually deal with their destruction.




回答3:


This answer is good enough but just to add some more.

I see you have been coded with Java. In C++ to create variable/object in stack keyword new is not needed. Actually when you use keyword new your object is creating in heap and it doesn't destroys after leaving scope. To destroy it you need to call delete in your case delete test;

In such a structure as yours, after leaving scope you just lose pointer what points into object, so after leaving scope you cannot free memory and call destructor, but eventually OS call destructor just after exit() instruction is executed.

To sum up C++ != Java



来源:https://stackoverflow.com/questions/18097478/c-why-it-doesnt-call-a-destructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!