+1  A: 

The compiler generates all necessary code to call destructors in the right order, whether it be a stack object or member variable going out of scope, or a heap object being deleted.

Marcelo Cantos
@Marcelo :If everything happens at the compile time , why does this implementation is called late binding? and how does compiler know at the time of compilation itself which DTOR to call? Apologies for my ignorance , appreciate your effort.
dicaprio
@dicaprio The compiler at compile time emits code to handle the destruction, using the virtual function mechanism. The code is executed at run time.
anon
@Neil : thanks much for your reply, does this mean compiler write the extra stuff to use virtual mechanism and the operator delete just use the address at the runtime to call the proper DTOR ?
dicaprio
@dicaprio: when `delete` is invoked, the compiler calls the destructor member function. If that destructor is virtual, then the most-derived destructor will be called. At that point, the behaviour is identical to what happens when a stack object of the same type goes out of scope.
Marcelo Cantos
@dicaprio It emits extra stuff.
anon
+1  A: 
  1. You instantiate the derived type, when it goes out of scope it calls the destructor, virtual or not.
  2. The compiler will generate code which makes a call to the destructors. It does not all happen on compile time. Code generation does, but lookin up what the address of the dtor is happens at runtime. Think about the case where you have more then 1 derived type and you do the delete using a base pointer.
  3. A base class destructor needs to be virtual to make a polymorphic delete call the dtor of the derived type.

If you want to find out more try overloading new and delete.

Eddy Pronk
@epronk : Thank you, I agree with you on 1, but 2 and 3 are still not clear. This again raise many question which I added in response to Marcelo below.
dicaprio
base* bPtr does not extend the lifetime of the object in any way and will go out of scope before drvd does. (stars go on the left side)
Eddy Pronk
@epronk : Good point!! your suggestion to overload new or delete operator, however, my understanding is we don't implement anything to call dtor of the class , do we ?
dicaprio
+1  A: 
  1. This is due to tha fact that in this case the compiler know everything about the object to be destructed which in this case is drvd and is of type derived. When drvd goes out of scope the compiler inserts code to call its destructer

  2. delete is a keyword for compiler. When compiler see delete it inserts the code to call the destructer and the code to call operator delete to deallocate the memory.Please keep in mind that keyword delete and operater delete are different.

  3. When compiler sees keyword delete being used for a pointer it needs to generate code for its proper destruction. For this it needs to know the type information of the pointer. The only thing the compiler know about the pointer is the pointer type, not the type of object to which the pointer is pointing to. The object to which the pointer is pointing to may be a base class or a derived class. In some cases the type of object may be very clearly defined for example

void fun()
{
    Base *base= new Derived(); 
    delete base;
}

But in most cases it is not, for example this one

void deallocate(Base *base)
{
    delete base;
}

So the compiler does not know which destructer to call of base or of derived. This is the way then it works

  1. If the Base class does not have a virtual function (member function or destructer). It directly insetrts thr code to call the destructer of base class
  2. If the Base class has virtual functions, then the compiler takes the information of destructer from vtable.
    1. If destructer is not virtual. The vtable will have the address of base destructer and thats what will be called. This is not right since the proper destructer is not being called here. This is why it is always recommended to declare destructer of base class as virtual
    2. If the destructer is virtual the vtable will have correcte address of destructer and compiler will insert proper code over there
Yogesh Arora
+1  A: 

+1 Good question BTW.

Look at how the virtual mechanism works for a non destructor method and you'll find a destructor behaves no differently.

There are 2 mechanism in play which may confuse the issue a little . Firstly a mechanism that isn't virtual is happening on construction and destruction of an object. The object is constructed from base class to derived class, in that order, and when destructed the destructor order is the reversed, so derived to based class. Nothing new here.

Consider calling a non virtual method on a based class pointer to a derived class object, what happens? The base class implementation is called. Now consider calling a virtual method from a base class pointer to a derived class object, what happens? The derived version of the method is called. Nothing you didn't already know.

Lets now consider the destructor scenario. Call delete on a base class pointer to a derived class object which has a non virtual destructor. The base class destructor is called, and if the base class had been derived from another class, then it's destructor would get called next. Because the virtual mechanism isn't in play , the derived destructor won't be called because destruction starts from the destructor you call in the hierarchy and works it way down to the base class.

Now consider the virtual destructor case. delete is called on a based class pointer to a derived class object. What happens when you call any virtual method on a base class pointer? The derived version gets called. So our derived class destructor is called . What happens during destruction, the object destructs from derived destructor to base class, but this time we started the destruction at the derived class level because of the virtual method mechanism.

Why does a stack object with either a non virtual or virtual destructor destruct from derived to base class when it goes out of scope? Because the destructor of the declared class is called in this case and the virtual mechanism has nothing to do with it.

Rich