Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manual call of destructor

Tags:

c++

destructor

#include <iostream> 
using namespace std; 
namespace GB
{
    class Test 
    { 
    public: 
        Test()  { cout << "Constructor is executed\n"; } 
        ~Test() { 
            cout << i << " " << "Destructor is executed\n";  
            this->i = 7;
        } 
        int i = -1;
    }; 
}
  
int main() 
{ 
    // Test();  // Explicit call to constructor 
    GB::Test t;    // local object 
    t.i = 6;
    t.~Test(); // Explicit call to destructor 
    return 0; 
}

Output

Constructor is executed
6 Destructor is executed
6 Destructor is executed

My questions are:
1)Why destructor is called twice.
2)In first call of destructor member value is changed from 6 to 7 , still in second call it comes as 6.
3)Can we stop second call of destructor (I want to keep only manually call of destructor).

like image 653
gaurav bharadwaj Avatar asked Oct 19 '25 03:10

gaurav bharadwaj


1 Answers

Why destructor is called twice.

The first call is from the line i.~Test();.
The second call is the automatic call to the destructor when the variable i gets out of scope (before returning from main).

In first call of destructor memeber value is changed from 6 to 7 , still in second call it comes as 6.

That's caused by undefined behavior. When an object's destructor gets called twice, you should expect undefined behavior. Don't try to make logical sense when a program enters undefined behavior territory.

Can we stop second call of destructor (I want to keep only manually call of destructor).

You can't disable the call to the destructor of an automatic variable when variable goes out of scope.

If you want to control when the destructor is called, create an object using dynamic memory (by calling new Test) and destroy the object by calling delete.

GB::Test* t = new GB::Test(); // Calls the constructor
t->i = 6;
delete t;                     // Calls the destructor

Even in this case, calling the destructor explicitly is almost always wrong.

t->~Test();  // Almost always wrong. Don't do it.

Please note that if you want to create objects using dynamic memory, it will be better to use smart pointers. E.g.

auto t = std::make_unique<GB::Test>();  // Calls the constructor
t->i = 6;
t.reset();                              // Calls the destructor

If t.reset(); is left out, the dynamically allocated object's destructor will be called and the memory will be deallocated when t gets out of scope. t.reset(); allows you to control when the underlying object gets deleted.

like image 198
R Sahu Avatar answered Oct 20 '25 18:10

R Sahu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!