#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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With