Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Does Virtual Destructor work in C++

Tags:

c++

I will type an example :

class A
{
public:
virtual ~A(){}
};

class B: public A
{
public:
~B()
{
}

};



int main(void)
{
A * a =  new B;
delete a;
return 0;
}

Now in Above Example , destructors will be called recursively bottom to up . My Question is how Compiler do this MAGIC .

like image 732
PeerPandit Avatar asked Oct 13 '11 06:10

PeerPandit


People also ask

Why do we make destructor virtual?

Virtual destructors in C++ are used to avoid memory leaks especially when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects. A destructor can be virtual.

In what situation does a destructor create virtual?

When destroying instances of a derived class using a base class pointer object, a virtual destructor is used to free up memory space allocated by the derived class object or instance. Note: Only Destructors can be Virtual.

Is virtual deconstructor possible in C++?

In C++, the constructor cannot be virtual, because when a constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual.

Are destructors automatically virtual?

The destructor is not virtual (that is, the base class destructor is not virtual) All direct base classes have trivial destructors. All non-static data members of class type (or array of class type) have trivial destructors.


1 Answers

A suitable implementation of (virtual) destructors the compiler might use would be (in pseudocode)

class Base {
...
  virtual void __destruct(bool should_delete);
...
};

void Base::__destruct(bool should_delete)
{
  this->__vptr = &Base::vtable; // Base is now the most derived subobject

  ... your destructor code ...

  members::__destruct(false); // if any, in the reverse order of declaration
  base_classes::__destruct(false); // if any
  if(should_delete)
    operator delete(this);  // this would call operator delete defined here, or inherited
}

This function gets defined even if you didn't define a destructor. Your code would just be empty in that case.

Now all derived classes would override (automatically) this virtual function:

class Der : public Base {
...
  virtual void __destruct(bool should_delete);
...
};

void Der::__destruct(bool should_delete)
{
  this->__vptr = &Der::vtable;

  ... your destructor code ...

  members::__destruct(false);
  Base::__destruct(false);
  if(should_delete)
    operator delete(this);
}

A call delete x, where x is of pointer to class type, would be translated as

x->__destruct(true);

and any other destructor call (implicit due to variable going out of scope, explicit x.~T()) would be

x.__destruct(false);

This results in

  • the most derived destructor always being called (for virtual destructors)
  • operator delete from the most derived object being called
  • all members' and base classes' destructors being called.

HTH. This should be understandable if you understand virtual functions.

like image 181
jpalecek Avatar answered Oct 17 '22 11:10

jpalecek