By
Dr. Ahmed Taha
Lecturer, Computer Science Department,
Faculty of Computers & Artificial Intelligence,
Benha University Lecture 10
1
Lecture Ten
Polymorphism
2
3
4
Pointers to Base
Class
// pointers to base class
#include <iostream>
using namespace std;
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 (){return (width * height);}
};
5
Pointers to Base
Class
class CTriangle: public CPolygon 20
{ 10
public:
int area (){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 << rect.area() << endl;
cout << trgl.area() << endl;
return 0;
}
6
Pointers to Base
Class
• In the previous example, we assign references to rect and trgl
to two pointers (ppoly1 and ppoly2) of type CPolygon, and
because both are objects of classes derived from CPolygon,
both are valid assignment operations.
• The only limitation in using *ppoly1 and *ppoly2 instead of
rect and trgl is that we can only use these pointers to refer to
the members that CRectangle and CTriangle inherit from
CPolygon.
7
Pointers to Base
Class
• For that reason, when we call the area() members,
we have had to use directly the objects rect and trgl
instead of the pointers *ppoly1 and *ppoly2.
• The problem is that CRectangle and CTriangle
implement different versions of area, therefore we
cannot implement it in the base class.
8
Virtual Members
• A member of a class that can be redefined in its
derived classes is known as a virtual member.
• In order to declare a member of a class as virtual, we
must precede its declaration with the keyword
virtual.
9
Virtual Members
// virtual members
#include <iostream>
using namespace std;
class CPolygon
{
protected:
int width, height;
public:
void set_values (int a, int b)
{width=a; height=b;}
virtual int area (){return (0);}
};
class CRectangle: public CPolygon
{
public:
int area() { return (width * height); }
};
10
Virtual Members
class CTriangle: public CPolygon
{ 20
public: 10
int area (){return(width*height/2);}
}; 0
int main ()
{
CRectangle rect;
CTriangle trgl;
CPolygon poly;
CPolygon * ppoly1 = ▭
CPolygon * ppoly2 = &trgl;
CPolygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << ppoly1->area() << endl;
cout << ppoly2->area() << endl;
cout << ppoly3->area() << endl;
return 0;
}
11
Virtual Members
• Now the three classes (CPolygon, CRectangle and
CTriangle) have all the same members: width, height,
set_values() and area().
• The member function area() has been declared as
virtual in the base class because it is later redefined
in each derived class.
12
Virtual Members
• A class that declares or inherits a virtual function is
called a polymorphic class.
• Note that despite of its virtuality, we have also been
able to declare an object of type CPolygon and to call
its own area() function, which always returns 0.
13
Abstract Base
Classes
• We could leave that area() member function without
implementation at all in the base class. This is done
by appending =0 (equal to zero) to the function
declaration.
// abstract class CPolygon
class CPolygon
{
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area () =0;
}; 14
Abstract Base
Classes
• Notice how we appended =0 to virtual int area ()
instead of specifying an implementation for the
function.
• This type of function is called a Pure Virtual Function,
and all classes that contain at least one pure virtual
function are Abstract Base Classes.
15
Abstract Base
Classes
• The main difference between an abstract base class
and a regular polymorphic class is that because in
abstract base classes at least one of its members lacks
implementation we cannot create instances (objects)
of it.
16
Abstract Base
Classes
• A class that cannot instantiate objects is not totally useless. We
can create pointers to it and take advantage of all its
polymorphic abilities.
CPolygon poly; // not valid for the abstract base class
• However, pointers to this abstract base class can be used to
point to objects of derived classes.
CPolygon * ppoly1; // valid
CPolygon * ppoly2; // valid
17
Abstract Base
Classes
// abstract base class
#include <iostream>
using namespace std;
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);}
};
18
Abstract Base
Classes
class CTriangle: public CPolygon
{ 20
public: 10
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;
}
19
Polymorphism
• Virtual members and abstract classes grant C++ the
polymorphic characteristics that make object-oriented
programming such a useful instrument in big projects.
• Of course, we have seen very simple uses of these
features, but these features can be applied to arrays
of objects or dynamically allocated objects.
20
Polymorphism
// dynamic allocation and polymorphism
#include <iostream>
using namespace std;
class CPolygon
{
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<<this->area()<<endl;}
};
class CRectangle: public CPolygon
{
public:
int area (void){return(width*height);}
};
21
Polymorphism
class CTriangle: public CPolygon
{ 20
public: 10
int area(void){return(width*height/2);}
};
int main ()
{
CPolygon * ppoly1 = new CRectangle;
CPolygon * ppoly2 = new CTriangle;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly1->printarea();
ppoly2->printarea();
delete ppoly1;
delete ppoly2;
return 0;
}
22
23