January 13, 2021

C++ OOP – Virtual Functions

In this lesson, we would cover Virtual Functions. We’ll also see example where it is used.

  1. Introduction to Virtual Functions
  2. Using Virtual Functions
  3. Benefits of Virtual Functions
  4. Pure Virtual Function

 

1. Introduction to Virtual Functions

A virtual function is a member function in the base class define with the virtual keyword. It is expected to be overridden in derived classes. In order words, a virtual function is a function that should be overriden.

A use case for virtual functions is where a pointer of the base class is pointing to an object of the derived class.

Take for example,

#include <iostream>
using namespace std;

class Parent {
   public:
    void show() {
        cout<<"I am parent!";
    }
};

class Child : public Parent {
   public:
    void show() {
        cout<<"I am child!";
    }
};


int main() {

	Parent* parent;
	Child child;

	parent = &child;

	parent->show();

   return 0;
}

In this example, we have a pointer of Parent type but it holds the address of child. So we expect that the child method will be called. But no, it calls the parent method. In order words, the parent function is not overridden. Here’s to output;

I am parent!

The reason, for this is that the call to the show() function is set once by the compiler as the version defined in the Parent class. This is known as static resolution, static linkage or early binding.

Note the arrow operator(->) is used to access member functions through a pointer.

 

2. Using Virtual Function

In order to fix the problem describe, we can declare the show() function of the Parent as virtual. Simply add the virtual keyword. Like so:

class Parent {
   public:
    virtual void show() {
        cout<<"I am parent!";
    }
};

In this case, this function will always be overridden. This is even though the pointer is a pointer of type Parent. But it holds the address of the Child.

The virtual keyword tells the compiler that we don’t want early binding for the given function. We’ll use late binding or dynamic linkage.

 

3. Benefit of Virtual Function

Let’s now look at an example to illustrates the benefit of virtual function. In this example

We have a base class, Vehicle and two derived classes: Bus and Car.

Each of these classes has a data member named ‘make’. Assuming this data member is initialized through their constructors. Then we have:

class Vehicle {
	private: string make;
	
	public: Vehicle(): make("Vehicle") {} //initialize make
   
   public:string getMake(){
	   return make;
   }
};


class Car : public Vehicle {
	private: string make;	
	
	public: Car():make("Car") {} //initialize make
	
	public:	string getMake() {
		return make;
	}
};


class Bus: public Vehicle {
	private: string make;
	
	public: Bus():make("Bus") {} //initialize make
	
	public: string getMake(){
		return make;
	}		
};

In both Car and Bus, we override getMake() in Vehicle.Now, this is fine. But we also want another method, display(). This method would display the make to the output.

We could create this method separately for each class. But we can do better. We would make the getMake() function virtual in the Vehicle class. Next, we create a single display() function outside all the classes. This function will accept a pointer to Vehicle type as it’s argument.

So when this function executes, it calls the getMake() function which is virtual. Therefore the getMake in the particular derived class is called.

The display() method and the main method is shown below:

void display(Vehicle* v){
	cout << "Vehicle: " << v->getMake()<<endl;
}


int main() {

	Vehicle* vehicle1 = new Vehicle();
	Vehicle* car1 = new Car();
	Vehicle* bus1 = new Bus();

	display(vehicle1);
	display(car1);
	display(bus1);

   return 0;
}

So we have considerable reduced he amount of code required. The output is shown below:

Vehicle: Vehicle
Vehicle: Car
Vehicle: Bus

 

4. Pure Virtual Functions

A pure virtual function is a function declared in the base class without any definition. In other words, the function has no body.

For example

class Parent {
	
   public:
	//Pure virtual function
    virtual void show();
};

In this code, the only function that could possibly be executed is the on in a derived class.

Leave a Reply

Your email address will not be published. Required fields are marked *