In your code test T
is a local variable and local variables are deleted when they go out of scope.
If you call T.~test()
explicitly then it deletes the variable before it goes out of scope. But when the variable really goes out of scope, the destructor is called again.
Consider the example (taken from your code):
#include <string>
#include <iostream>
class test
{
private:
std::string member;
public:
test(const std::string & arg) { member = arg; };
~test()
{
std::cout << " calling destructor "<<std::endl;
}
};
int main()
{
test T = test("test test test test");
//take the call away and you will still have the destructor call
//T.~test();
return 0;
}
If now, you call the destructor explicitly, then you get the destructor called twice (once explicitly and once when the variable goes out of scope)
#include <string>
#include <iostream>
class test
{
private:
std::string member;
public:
test(const std::string & arg) { member = arg; };
~test()
{
std::cout << " calling destructor "<<std::endl;
}
};
int main()
{
test T = test("test test test test");
//causing a double call to the destructor
T.~test();
return 0;
}
The execution would be
calling destructor
calling destructor
free(): double free detected in tcache 2
Abandon
If instead, you have allocated a pointer on test
with new
, you then need to explicitly call the destructor otherwise, you will have memory leaks.
When excuting the code below, you see that the destructor does not get called even if your pointer goes out of scope.
int main()
{
test* T = new test("test test test test");
// in this case you will have no more destructor automatically
//T.~test();
return 0;
}
You need to deallocate the allocated memory explicitly by calling the destructor but not by using T.~test()
because now T
is not of type test
but test*
. You only need to call delete T
like this:
int main()
{
test* T = new test("test test test test");
//You need to deallocate the allocated memory explicitly
//T.~test();
delete T;
return 0;
}
And the destructor is called on the allocated memory