Login

Username:

Password: 

Join us Now |  Forgot Password? | Forgot UserName?

C++

Learn step by step



Polymorphism in C++

Polymorphism means having many forms.

C++ polymorphism means that a call to the member function will cause a different function to be executed depending on the type of object that invokes the function.

Consider following example where a base class has been derived by other two classes:


#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 rectangle area.
shape->area();

// store the address of Triangle
shape = &tri;
// call triangle area.
shape->area();

return 0;
}

Output

Parent class area
Parent class area

The reason for the incorrect output is that the call of the function area() is being set once by the compiler as the version defined in base class. This is called static resolution of the function call, or static linkage - the function call is fixed before the program is executed. Sometimes this is also called early binding because the area() function is set during the compilation of the program.

But now, let's make a slight modification in our program and precede the declaration of area() in the Shape class with the keyword virtual so that it looks like this:


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;
}
};

Output

Rectangle class area
Triangle class area

This time, the compiler looks at the contents of the pointer instead of it's type. Hence, because addresses of objects of tri and rec classes are stored in *shape the respective area() function is called.

As we can see, each of the child classes has a separate implementation for the function area(). This is how the polymorphism is generally used. We have different classes with a function of the same name, and even with the same parameters, but with different-different implementations.

Virtual members

A virtual member is a member function that can be redefined in a derived class. Syntax for a function to become virtual is to precede its declaration with the virtual keyword:


// virtual members
#include <iostream>
using namespace std;

class Polygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area ()
{ return 0; }
};

class Rectangle: public Polygon {
public:
int area ()
{ return width * height; }
};

class Triangle: public Polygon {
public:
int area ()
{ return (width * height / 2); }
};

int main () {
Rectangle rect;
Triangle trgl;
Polygon poly;
Polygon * ppoly1 = &rect;
Polygon * ppoly2 = &trgl;
Polygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << ppoly1->area() << '\n';
cout << ppoly2->area() << '\n';
cout << ppoly3->area() << '\n';
return 0;
}

Output

20
10
0

In this example, all three classes (Polygon, Rectangle and Triangle) have the same members: width, height, and functions set_values and area.

The area of member function has been declared as virtual in the base class because it is later redefined in each of the derived classes. The members which non-virtual can also be redefined in derived classes, but non-virtual members of the derived classes cannot be accessed through a reference of the base class: i.e., if virtual keyword is removed from the declaration of area in the example above, all calls to area would return a zero, because in all cases, the version of the base class would have been called instead.

So, essentially, what the virtual keyword does is to allow a member of the derived class with the same name as one of in base class to be appropriately called from a pointer, and more precisely when the type of the pointer is a pointer to the base class that is pointing to an object of the derived class, as in the above example.

A class that declares/inherits a virtual function is called a polymorphic class.

Note: despite of the virtuality of one of its members, Polygon was a regular class, of which even an object was instantiated (poly), with its own definition of member area that always returns 0.



Related Videos