Let’s say we have a class called Base and a derived class called Derived which is derived from Base class as below:

Scenario #1: Base and Derived Class Definition


class Base {
public:
void welcome_message() {cout << "Welcome to Base class" << endl;}
};

class Derived : public Base {
public:
void welcome_message() {cout << "Welcome to Derived class" << endl;}
};

As can be seen our Base and Derived class doesn’t do much except providing a welcome message function in its public interface. Now, few facts about our Base and Derived class:

Scenario #2: Derived Class object calls member function

If we create a Derived class object and using the object handle call the welcome_message() function we will see the below:


int main()
{
Derived d;
d.welcome_message();

return 0;
}

print1

Scenario #3: Derived Class pointer pointing Derived Class object

If we create a derived class pointer pointing to a derived class object and call the welcome_message() function of the class it will look like as below:


int main()
{
Derived *dptr = new Derived();
dptr->welcome_message();
return 0;
}

print1

So now in both the cases the messages being printed is “Welcome to Derived class” which is anticipated.

Now, what if we create a Base class pointer which points to the Derived class object and then using the Base class pointer we call the welcome_message() function? The below happens:

Scenario #4: Base Class pointer pointing to Derived Class object


int main()
{
Base *bptr = new Derived();
bptr->;welcome_message();

return 0;
}

print1

As you can see when we used the Base class pointer to point to the Derived class object and then called the welcome_message() function of the Derived class, it didn’t get called instead the Base class welcome_message was called.

This is because the compiler doesn’t have any idea what is the type of the object is and hence assumes the type is of Base as the pointer type in this case is of type Base.

So the problem here is even if our object is of type Derived, as it is pointer by a Base class type pointer the function which is being called is the one defined in the Base class not the Derived class.

virtual keyword

Now, to overcome this issue we have the the mechanism of virtual function. Virtual keyword is used to specify a virtual function. The keyword makes the compiler and the C++ run time look for the actual type of the object while calling the member function and not determine by the type of the pointer. Lets have a look how it works:


class Base {
public:
virtual void welcome_message() {cout << "Welcome to Base class" << endl;}
};

class Derived : public Base {
public:
void welcome_message() {cout << "Welcome to Derived class" << endl;}
};

Above we have just redefined the Base class member function welcome_message() and added the keyword virtual in front of it. After this modification if we run the below code we will see the Derived class version of the welcome_message() is being called rather than the Base class version. Lets have a look at the code and the new output:


int main()
{
Base *bptr = new Derived();
bptr->;welcome_message();

return 0;
}

print1.png

As you can see the Derived class version of the welcome_message() function is being called not the Base class one unlike in the previous scenario.

At this point I am not going into the details of how the virtual function mechanism is implemented in C++ as that is quite a detailed subject and I would like to keep it separate from this post.

However, one question which might come into your mind as why would one should use a Base class pointer to point to a Derived class object at all. If you have noticed if we use a  Derived class pointer to point to a Derived class object which is described in Section 3, there is absolutely no problem. The problem starts when we use a Base class pointer pointing to a Derived class object, and use that pointer to call a function defined in both class and the Derived class. For why we care to use the Base class pointer please refer to the post Why we need virtual function?

Leave a Reply