C++ Polymorphism
Polymorphism literally means "having many forms." It is used when there is a hierarchy of classes related by inheritance.
Polymorphism in C++ means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.
In the following example, the base class Shape is derived into two classes:
Example
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// Store the address of Rectangle
shape = &rec;
// Call area function of Rectangle
shape->area();
// Store the address of Triangle
shape = &tri;
// Call area function of Triangle
shape->area();
return 0;
}
When the above code is compiled and executed, it produces the following result:
Parent class area :
Parent class area :
The reason for the incorrect output is that the call to the area() function is set to the base class version by the compiler. This is known as static polymorphism or static linkage - the function call is set before the program is executed. Sometimes this is also called early binding because the area() function is set during compilation.
Now, let's make a small change to the program. Place the keyword virtual before the declaration of the area() function in the Shape class, as shown below:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
After making this change, when the previous example code is compiled and executed, it produces the following result:
Rectangle class area :
Triangle class area :
Now, the compiler looks at the contents of the pointer rather than its type. Therefore, since the addresses of the tri and rec class objects are stored in the *shape pointer, their respective area() functions are called.
As you can see, each subclass has a separate implementation of the area() function. This is the general way polymorphism is used. With polymorphism, you can have multiple classes with a function of the same name but different implementations, and the function parameters can even be the same.
Virtual Function
A virtual function is a function declared in the base class using the keyword virtual. When redefining the virtual function in the derived class, it tells the compiler not to statically link to the function.
What we want is to choose the function to call based on the object type at the point in the program, which is known as dynamic linkage or late binding.
Pure Virtual Function
You might want to define a virtual function in the base class so that it can be redefined in the derived class to better suit the object, but you cannot provide a meaningful implementation for the virtual function in the base class. This is where pure virtual functions come into play.
We can modify the virtual function area() in the base class as follows:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
The = 0
tells the compiler that the function has no body, making the virtual function above a pure virtual function.