Polymorphism in C++ - Runtime Polymorphism Using Virtual Functions
1. 1
Polymorphism
• It simply means ‘one name, multiple forms’.
• We have already seen how the concepts of
polymorphism implemented using overloaded
function.
• The overloaded member function are selected
for invoking by matching arguments.
• This information is known to the compiler at
compile time and it is known as early binding .
Also known as compile time polymorphism.
2. #include <iostream.h>
class A
{
public :
float sum() {
return 10;
}
float sum(float i, float j,float k) {
return i+j+k;
}
};
class B : public A
{
public:
using A::sum;
float sum(float i) {
return i;
}
float sum(float i, int j) {
return i+j;
}
};
void main()
{
B calculate;
cout<<calculate.sum(25.5)<<endl;
cout<<calculate.sum(4.5,5)<<endl;
cout<<calculate.sum(4.5,3.5,2.5)<<endl;
cout<<calculate.sum()<<endl;
}
Output
25.5
9.5
10.5
10
3. 3
• Consider the situation where the function name and
prototype is same in both the base and derived classes.
class A {
int x;
public:
void show(){…..}
};
class B : public A {
public:
void show(){…..}
};
• Since the prototype is same, function is not overloaded.
• Virtual function and pointer are used to invoke appropriate
member function while the program is running and it is
known as late binding .
• Also known as runtime polymorphism.
4. وائل
قصاص 4
// pointers to base class
#include <iostream.h>
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b) {
width=a; height=b;
}
};
class CRectangle : public CPolygon {
public:
int area (void){ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area (void){
return (width * height / 2);
}
};
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * p1 = ▭
CPolygon * p2 = &trgl;
p1->set_values (4,5);
p2->set_values (4,5);
cout << rect.area() << endl;
cout << trgl.area() << endl;
return 0;}
20
10
Code
5. • The function main creates two pointers that point to objects of class
CPolygon, that are *p1 and *p2. These are assigned to the addresses
of rect and trgl, and because they are objects of classes derived
from CPolygon they are valid assignations.
• The only limitation of using *p1 and *p2 instead of rect and trgl is
that both *p1 and *p2 are of type CPolygon* and therefore we can
only refer to the members that CRectangle and CTriangle inherit
from CPolygon. For that reason when calling the area() members
we have not been able to use the pointers *p1 and *p2.
• To make it possible for the pointers to class CPolygon to admit area
() as a valid member, this should also have been declared in the base
class and not only in its derived ones.
6. 6
Virtual members
• In order to declare an element of a class which
we are going to redefine in derived classes we
must precede it with the keyword virtual so
that the use of pointers to objects of that class
can be suitable.
7. وائل
قصاص 7
#include <iostream.h>
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b) {
width=a; height=b;
}
virtual int area (void) { return (0); }
};
class CRectangle: public CPolygon {
public:
int area (void){
return (width * height);
}
};
class CTriangle: public CPolygon {
public:
int area (void) {
return (width * height / 2);
}
};
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon poly;
CPolygon * p1 = ▭
CPolygon *p2=&trgl;
CPolygon * p3 = &poly;
p1->set_values(4,5);
p2->set_values(4,5);
p3->set_values (4,5);
cout << p1->area() << endl;
cout << p2->area() << endl;
cout << p3->area() << endl;}
20
10
0
8. • The three classes (CPolygon, CRectangle and CTriangle) have the
same members: width, height, set_values() and area().
• area() has been defined as virtual because it is later redefined in
derived classes. You can verify if you want that if you remove this
word (virtual) from the code and then you execute the program the
result will be 0 for the three polygons instead of 20,10,0. That is
because instead of calling the corresponding area() function for
each object (CRectangle::area(), CTriangle::area() and
CPolygon::area(), respectively), CPolygon::area() will be called
for all of them since the calls are via a pointer to CPolygon.
• Therefore, what the word virtual does is to allow a member of a
derived class with the same name as one in the base class be suitably
called when a pointer to it is used
9. Abstract base classes
• Abstract classes are similar to the class CPolygon of our previous example.
The only difference is that in our previous example we have defined a valid
area() function for objects that were of class CPolygon (like object poly),
whereas in an abstract base class we could have simply left without
defining this function by appending = 0 to the function declaration.
• The class CPolygon could have been thus:
// abstract class CPolygonclass
CPolygon {
protected:
int width, height;
public:
void set_values(int a, int b){
width=a; height=b;
}
virtual int area (void) = 0;
};
10. • This type of function is called a pure virtual function, and all classes
that contain a pure virtual function (do-nothing function) are
considered abstract base classes.
• The greatest difference of an abstract base class is that instances
(objects) of it cannot be created, but we can create pointers to them.
Therefore a declaration likes:
CPolygon poly; // incorrect
CPolygon * ppoly1; //correct
• This is because the pure virtual function that it includes is not defined
and it is impossible to create an object if it does not have all its
members defined. A pointer that points to an object of a derived class
where this function has been defined is perfectly valid.
• The main objective of an abstract base class is to provide some traits to
the derived classes and to create a base pointer required for achieving
run time polymorphism.
11. #include <iostream.h>
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) = 0;
};
class CRectangle: public CPolygon {
public:
int area (void)
{return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area (void)
{return (width * height / 2); }
};
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
return 0;
}
20
10
12. وائل
قصاص 12
#include <iostream.h>
class Polygon {
protected: int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0;
void printarea (void)
{ cout << area() << endl; }
};
class Rectangle: public Polygon {
public:
int area (void)
{ return (width * height); }
};
class Triangle: public Polygon {
public:
int area (void)
{ return (width * height / 2); }
};
int main () {
Rectangle rect;
Triangle trgl;
Polygon * p1 = ▭
Polygon * p2 = &trgl;
p1->set_values (4,5);
p2->set_values (4,5);
p1->printarea();
p2->printarea();
return 0;
}
20
10