4

On calling desctructor explicitly, it is executed two times. What's the reason for that?

#include <iostream>
using namespace std;

class A
{
    public:
        int x;

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

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

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

Output:

A's constructor called
A's desctructor called
A's desctructor called

Suma
  • 33,181
  • 16
  • 123
  • 191
user3747190
  • 1,627
  • 3
  • 20
  • 28

4 Answers4

6

Well, you called it for 'a', and then 'the language' called it again for 'a' when the object went out of scope. And then, of course, 'the language' called it for b. By 'the language', I mean, of course, the very basic rule that automatic-scope objects are constructed as their scope initialize, and destructed when their scope ends.

Using explicit calls to destructors is rarely a good idea.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
5

You shouldn't call the destructor by hand, it will get called automatically when the object goes out of scope.

The only place to manually call destructors is when you're writing your own allocator, but that is quite an advanced topic, so the rule of thumb would be to never call the destructor by hand.

Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327
3

[basic.life]/8:

If a program ends the lifetime of an object of type T with […] automatic (3.7.3) storage duration and if T has a non-trivial destructor, the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.

Hence we cannot explain the behavior of your program in general, but we could say "For your implementation a particular execution behaved as if the destructor was called two times."

Columbo
  • 60,038
  • 8
  • 155
  • 203
1

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

If the there is no object of the appropriate type there, the behavior is undefined. Typically the compiler generates code that would call the destructor and does so blindly, as that makes the 'defined 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 of the destructor does not mean the compiler will not try to destroy the object.

In fact, if your object was slightly more complex, it could easily lead to a crash.

Don't call the destructor of an object directly unless you used placement new (a variant of new that constructs an object and does not allocate any memory) or the equivalent on it, and don't use placement new unless you really know what you are doing.

There is another valid use, where you destruct and reconstruct in the same place, but that is dangerous, usually a bad idea, and hard to get right.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524