Search This Blog

Tuesday, July 13, 2010

Is it necessary to specify virtual keyword in derived classes? (C++)

No - not at all necessary! BUT please do it so that the maintenance programmer wont have horror experience debugging your code :)

Let me support it with sample code :


#include <iostream>

using namespace std;

class Base {
public:
 Base() { cout << "Base::Base()" << endl; }
 virtual void VirtFun() { cout << "Base::VirtFun()" << endl; }
 virtual ~Base() { cout << "Base::~Base()" << endl; }
};

class Derived : public Base {
public:
 Derived() { cout << "Derived::Derived()" << endl; }
 void VirtFun() { cout << "Derived::VirtFun()" << endl; }
 ~Derived() { cout << "Derived::~Derived()" << endl; }
};

int main () {
 
 Base* pBase = new Derived();
 pBase->VirtFun();
 delete pBase;

 return 0;
}

Output of this program is :
Base::Base()
Derived::Derived()
Derived::VirtFun()          
Derived::~Derived()
Base::~Base()

Even though the virtual keyword is not specified in the Derived class - the VirtFunc() and Destructor of virtual class are automatically virtual (because virtual keyword is specified for them in Base class).

Also note that : only the functions which are specified as virtual in Base class will be by default virtual in the Derived classes. If the function is not virtual in Base class - then it is not so.

I am not sure whether this features is compiler dependent or not, I have tested this code using 'Microsoft Visual C++ 2005' and G++, both give same output.

Constructor Destructor and Virtual Keyword (C++)

One of the favorite interview question is -
Why destructor should be always virtual and constructor should never be virtual?

Let's discuss these 2 questions separately.

Before we start keep this class hierarchy in mind -

                                 Base
                                   ^
                                    |
        -------------------------------------------
       |                            |                             |
Derived1               Derived2                Derived3



1. Why is constructor never virtual?
While creating any object programmer always 'knows' which object he is creating i.e. Which class we want to instantiate.
e.g. Base *pBase = new Derived3();  // Though the pointer is of Base class type the programmer very
                                                         // well knows to write new Derived3()

In addition, also note that though virtual table in not specific to class instance (object), to call virtual function of any class first we need valid object of that class.
i.e. Virtual function can not be called unless we have constructed the object.

2. Why is destructor be always virtual?
There might be function of the type
void do_something_and_then_delete(Base *pBase) {
     // Do something with pBase

     delete pBase;
}

Now it is easy to understand that user might write some code like -
Base* pBase = new Derived1();
do_something_and_then_delete(pBase);
Base* pBase = new Derived2();
do_something_and_then_delete(pBase);
Base* pBase = new Derived3();
do_something_and_then_delete(pBase);

In all 3 cases correct destructor needs to get called.
User always knew name of the class to instantiate, but while deleting user did not have idea about which is the exact destructor he wants to call.
If the destructors of Derived classes are not virtual then the destructor of Base class will get called and it will lead to memory leaks and might be some other problems in the system.

If you have any better answer to improve this post please comment, I will modify the post.