How does virtual destructor work in this case of derived class

I was reading about deriving exception class for custom exceptions. That is when I came across this issue of virtual destructor. I have not actually written virtual destructor before so am asking here. In search it explains what happpens if we do/do not use a virtual destructor but does not explain *why* using it gives a certain result.

Code is here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include iostream.h
class Base
{
   	public:
      	Base(){ cout<<"Constructing Base";}
      	
     // this is a destructor:
	
	~Base(){ cout<<"Destroying Base";}
};

class Derive: public Base
{
        public:
       	Derive(){ cout<<"Constructing Derive";}
       	
       	~Derive(){ cout<<"Destroying Derive";}
 };

void main()
{
    	Base *basePtr = new Derive();
        
        delete basePtr;
}


This gives result:
1
2
3
Constructing Base  
Constructing Derive 
Destroying Base


Now if the base class is changed to have a virtual destructor like this

1
2
3
4
5
6
7
8
class Base
{
   	public:
      	Base(){ cout<<"Constructing Base";}

	// this is a virtual destructor:
	virtual ~Base(){ cout<<"Destroying Base";}
};


We get this result
1
2
3
4
Constructing Base  
Constructing Derive 
Destroying Derive
Destroying Base


My question is WHY does making base class destructor virtual cause this different result to be generated by calling derived class destructor first? Surely, both classes are different even though one inherits from the other and have their own destructors.
The difference is that the base class can find a virtual destructor of the derived class in the virtual function table. Otherwise the base class cannot know anything about the derived class.
The following link has some more details about base class destructors:

http://www.gotw.ca/publications/mill18.htm
@coder777: that seems to be poorly worded.
the base class still know nothing about its derived classes.
Also, you don't even mention an object or a pointer.
When you destroy an object, you don't only invoke the destructor of the object; the destructor of all base class objects is invoked as well. So if you have A, inherited by B, inherited by C, then when you destroy C, the following happens:

- the code in ~C() is executed
- ~C() invokes ~B()
- the code in ~B() is executed
- ~B() invokes ~A()
- the code in ~A() is executed

It's completely analogous to the constructors of a class also calling the constructors of the base classes.

If you think about it, it's obvious why it works this way. If B inherits from A, and there is some cleanup that has to be done when an A object is destroyed, then you obviously want that cleanup to be done when a B object is destroyed too.

As for your code examples, the rules of which destructor is invoked on your basePtr object are exactly the same as for any other method. With virtual methods, you get the benefits of polymorphism, and with non-virtual ones, you don't.

Do you understand the difference between virtual methods and non-virtual ones generally?
Last edited on
Topic archived. No new replies allowed.