When calling the destructor for an object, is it called twice?

When a descriptor is called explicitly, it is executed twice. What is the reason for this?

#include <iostream>
using namespace std;

class A
{
    public:
        int x;

        A() { cout << "A constructor called " << endl;  }

        ~A(){
            cout<<"A desctructor called "<<endl;
        }
};

int main()
{
    A a;
    A b;
    a.~A();
}

      

Output:

A constructor called a Deconstructor called a Descctor called

+3


source to share


4 answers


Well, you called it "a" and then "language" called it "a" again when the object went out of scope. And then, of course, the "language" called it the letter b. By "language" I mean, of course, the most basic rule that auto-scoped objects are built as they initialize their scope and destroyed when their scope ends.



Using explicit calls to destructors is rarely a good idea.

+6


source


You don't have to call the destructor manually, it will be called automatically when the object goes out of scope.



The only place to manually invoke destructors is when you write your own allocator, but this is a pretty advanced topic, so a rule of thumb to never invoke a destructor manually.

+5


source


[basic.life] / 8:

If the program ends the lifetime of an object of the type T

using [...] (3.7.3), and if it T

has a non-trivial destructor, the program must ensure that the object of the original type occupies the same storage location when the implicit destructor is called , otherwise the program's behavior undefined.

Therefore, we cannot explain the behavior of your program as a whole, but we could say, "For your implementation, the concrete execution behaved as if the destructor were called twice."

+3


source


When a variable goes out of scope, its destructor is implicitly called.

If there is no object of the corresponding type, the behavior is undefined. Typically, the compiler generates code that will invoke the destructor and does so blindly, since this makes the "certain behavior" path efficient and simple, and the "undefined behavior" path is considered your fault.

So what you are seeing is a symptom of undefined behavior. Your call to the destructor does not mean that the compiler will not try to destroy the object.

In fact, if your object was a little more complex, it could easily crash.

Don't call the object's destructor directly unless you've used allocation new (a variant new

that builds the object and doesn't allocate any memory) or the equivalent on it, and don't use the new allocation unless you really know what you're doing.

There is another acceptable use where you destroy and restore the same place, but this is dangerous, usually a bad idea and difficult to get right.

+1


source







All Articles