Why We Say Destructor Call When Object Goes out of Scope?

2.8k views Asked by At

I learned that the destructor is called when an object goes out of scope and also the destructor deletes the objects. Ok fine, but what's happening here?

I'm calling the destructor explicitly, if it deletes the object then why is the destructor implicitly called? Even though there no object now because it's already deleted with the explicitly destructor calling. Sorry may be I'm wrong about explicitly and implicitly But try to understand my problem.

#include <iostream>
using namespace std;
class A{
    public:
        A(){
            cout << "Constructor" << endl;
        }
        ~A(){
            cout << "Destructor" << endl;
        }

};
int main(){
    A obj;
    obj.~A();
    cout << "End" << endl;
}

Now

obj.~A();

The above line deletes the object. Then why again is the destructor called? Even though no object is there.

Output:

Constructor
Destructor
End
Destructor
4

There are 4 answers

2
Sneftel On BEST ANSWER

An object which goes out of scope has its destructor called. That is an unchangeable guarantee which is mandated by the C++ language standard. It doesn't matter if you've manually called the destructor beforehand; when it goes out of scope, the destructor will be called. If you've written your destructor such that bad things happen if it's called twice, or if the extra behavior which the compiler inserts into the destructor code doesn't want to be called twice, bad things will happen.

This is one of many reasons why you should never manually call a destructor.

0
QuentinUK On

Your object does not contain any pointers. It does not free any objects in the destructor when called so no harm is done when it is called multiple times. If the destructor deletes pointers and those pointers are not set to 0, which is often the case in destructors, then the second call of the destructor would be harmful because it would cause a memory error.

0
James Kanze On

The destructor does not delete the object, it destructs it. And unless the object is a POD type (basically, something you could define in C), destructing an already destructed object is undefined behavior. Since all variables will automatically have their destructor called when their lifetime ends, you should never explicitly call the destructor on them. Similarly, if you have created the object with a non-placement form of new: explicitly calling the destructor will not free the memory; you should use delete, which calls the destructor and then frees the memory.

The only time you should explicitly call the destructor is when you have used placement new to construct the object, in order to separate allocation and initialization. Today, such techniques should really be considered advanced, and it is rare for a programmer to need them.

2
Patrick On

Your provided class doesn't manage any data, so its destructor doesn't have any objects to free. That's why you're able to call the destructor twice with no consequences. Here's an example class that would fail the same test:

#include <iostream>


class A {
 public:
  A() {
    std::cout << "constructing..." << '\n';
    val = new int;
  }

  ~A() {
    std::cout << "destructing..." << '\n';
    delete val;
  }

 private:
  int* val;
};


int main() {
  A obj;
  obj.~A();
  std::cout << "End" << '\n';
  return 0;
}

The constructor allocates space on the heap for val, and the destructor runs delete to free up that space. ~A() is called twice in main() (first explicitly, then implicitly), which understandably causes a memory error.

Check out this link for more info on how destructors work: https://isocpp.org/wiki/faq/dtors