Question

Not to use in any implementation but just for the sake of understanding I am trying to explicitly call a destructor using an object and another * to object.

CODE

#include<iostream>
using namespace std; 

class A{
public :
A(){
    cout<<"\nConstructor called ";
}

~A()
{
    cout<<"\nDestructor called ";
}
};

int main()
{
    A obj,*obj1;
    obj1->~A();
    obj.~A();
    return 0;
}


OUTPUT

output1


Now the problem is that I can't understand why destructor is called three times.
Even if the obj1 is not yet pointing to any object.
Note that I understand that the last two destructor calls are:

  1. because I am calling obj.~A();
  2. because we go out of the scope of object obj.

I am using DevC++ 5.5.1

Was it helpful?

Solution

Your code only works by a fluke.

int main()
{   
    A obj,*obj1;
    obj1->~A(); // (1) Bad reference that works
    obj.~A();   // (2) Explicit call to destructor
    return 0;
} // (3) obj's destructor is called when obj goes out of scope

OTHER TIPS

obj1->~A();

You dereference the pointer obj1 which has not been initialized. That is undefined behaviour.

In this situation, anything can happen and nothing is guaranteed.

It's called three times, twice explicitly, and once when it goes out of scope.

The first explicit call is invalid, because the pointer is not initialized (this is undefined behaviour). In your case, it seems to have called the destructor function anyway, and since that doesn't use this, nothing bad appeared to happen. There's nothing in the C++ standard that says method calls on uninitialized pointers are elided!

In general, you shouldn't call the destructor of an object more than one (explicitly or otherwise); however, there are valid cases for doing so explicitly. Consider:

{
    alignas(alignof(A)) char data[sizeof(A)];    // Not an A object, so no
                                                 // call to dtor at scope end
    A* ptr = new (data) A();
    ptr->~A();    // object is now destructed but memory in `data` can be reused
}

the problem with destructor being invoked 3 times is actually quite simple.

In C++ objects constructed on the stack are destroyed automatically when they go out of scope. Whereas objects allocated with new must be explicitly deleted.

class MyClass
{
public:
    int Value;

    MyClass(int n) : Value(n) // initialize Value with n
    {
        cout << "MyClass::ctor(" << Value  << ")" << endl;
    }

    ~MyClass()
    {
        cout << "MyClass::dtor(" << Value << ")" << endl;
    }
};

int main()
{
    {
        MyClass a(10);                 // create a local object
        MyClass* b = new MyClass(20);  // create a dynamically allocated object

        delete b; // free dynamic memory and call destructor

    } // a goes out of scope and destructor is automatically invoked

    return 0;
}

So this doesn't really answer your question yet. Simply put, there is no way to avoid automatic destruction of local objects. The workaround is Cameron's example of using a local buffer and placement new:

MyClass* a = new (buffer) MyClass(10); // use placement new on a sufficient buffer
a->~MyClass();                         // explicitly call destructor

If you must have local explicit objects, then you can always keep track whether your object actually has anything to destroy or not:

class MyClass2
{
public:
    MyClass* Resource; // some resource we are managing

    MyClass2()      : Resource(nullptr)        {}
    MyClass2(int n) : Resource(new MyClass(n)) {}

    ~MyClass2()
    {
        if (Resource) // do we have anything to "destroy"?
        {
            delete Resource;    // call destructor, free memory
            Resource = nullptr; // ensure the resource is "destroyed" only once
        }
    }
};

So in effect, this only calls the "useful" part of the destructor if there really is something to "destroy".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top