While compile-time polymorphism is fast and resolved by the compiler, it lacks flexibility. Often, you want to write generic code that can process a variety of objects without knowing their exact types until the program is actually running. This is where Runtime Polymorphism (Late Binding) shines.
In C++, runtime polymorphism is achieved using Inheritance and Virtual Functions.
Consider an inheritance scenario where a derived class redefines a function from the base class (this is called Function Overriding).
If you use a base class pointer to hold a derived class object, calling the overridden function will result in the base class version executing. This happens because the compiler binds the function call based on the pointer's type (Animal*), not the object's actual type.
class Animal {
public:
void speak() { cout << "Animal sound" << endl; }
};
class Dog : public Animal {
public:
void speak() { cout << "Woof" << endl; } // Overriding
};
int main() {
Animal* myPet = new Dog();
myPet->speak(); // Output: "Animal sound" (Static Binding!)
return 0;
}To fix this, we use the virtual keyword in the base class. A virtual function tells the compiler not to perform early binding. Instead, the program will look at the actual type of the object in memory at runtime, and call the appropriate function (Late Binding).
#include <iostream>
using namespace std;
class Animal {
public:
// The virtual keyword enables runtime polymorphism
virtual void speak() {
cout << "Animal sound" << endl;
}
};
class Dog : public Animal {
public:
// It's good practice to use the 'override' keyword (C++11)
// to explicitly state you are overriding a virtual function.
void speak() override {
cout << "Woof!" << endl;
}
};
class Cat : public Animal {
public:
void speak() override
Sometimes a base class shouldn't have an implementation for a function at all—it merely exists to force derived classes to provide their own implementation. This is done using a Pure Virtual Function, indicated by = 0.
A class containing at least one pure virtual function is called an Abstract Class. You cannot instantiate an abstract class.
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
};
// Shape s; // ERROR: Cannot instantiate abstract classvirtual keyword in the base class enables late binding.= 0) to enforce an interface that derived classes must implement.Polymorphism resolved at runtime, where the program determines which function to invoke based on the actual object type, not the pointer type.
Providing a new implementation in a derived class for a function already defined in the base class.
A member function declared with the 'virtual' keyword in a base class that is redefined by a derived class to achieve dynamic binding.
Test your understanding with 2 questions
Which keyword is required in the base class to achieve runtime polymorphism?
If you have a base class pointer pointing to a derived class object, and you call a non-virtual overridden function, which version executes?
2 Modules
2 Modules