简体   繁体   中英

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

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?

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'?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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