You are on page 1of 12

Module 7

Polymorphism is one of the crucial features of OOP.

 It means “ONE NAME, MULTIPLE FORMS”

• Early binding/ static binding/ static linking:


The overloaded member functions are selected for invoking by matching arguments, both
type and number. This information is known to the compiler at the compile time and therefore,
compiler is able to select the appropriate function for a particular call at the compile time itself.
This is called early binding/ static binding/ static linking.

• Function Overloading:
#include<iostream.h>
#include<conio.h>
class A
{
int x,y;
public:
void show(int a){x=a;cout << "I am 1st and x="<<x<<"\n";}
void show(int a,int b)
{x=a;y=b;cout<<"\nI am 2nd and x="<<x<<" & y="<<y<<"\n";}
};

void main()
{
clrscr();
OUTPUT:
A a1;
a1.show(10); I am 1st and x=10
a1.show(20,30);
getch(); I am 2nd and x=20 & y=30
}

ANIRBAN SEAL, LECTURER(CST)


1
Module 7

• Function Overriding:
When the function name in the base and derived class is same, then the function in the derived
class will override on the base class function.

#include<iostream.h>
#include<conio.h>
class A
{
int x;
public:
void show(int a){x=a;cout << "I am A and x="<<x;}
};
class B:public A
{
int y;
public:
void show(int b){y=b;cout << "I am B and y="<<y;}
};
void main()
{ clrscr();
B b1; OUTPUT:
b1.show(10);
getch(); I am B and y=10
}

ANIRBAN SEAL, LECTURER(CST)


2
Module 7

Polymorphism

Compile time Polymorphism Runtime Polymorphism

Function overloading Operator Overloading Virtual Function

Achieving polymorphism

• Runtime Polymorphism:
It would be nice if the appropriate member function could be selected while the program is
running. This is known as runtime polymorphism. C++ supports a mechanism called Virtual
Function to achieve runtime polymorphism.

• Late Binding:
At runtime, when it is known what class objects are under consideration, the appropriate
version of the function is called. Since the function is linked with a particular class much later
after the compilation, this process is termed as late binding.

It is also known as dynamic binding because the selection of the appropriate function is
done dynamically at runtime.

• Dynamic binding is implemented by the following processes:


(1) Pointers to Objects (2) Object pointer and (3) Virtual functions

ANIRBAN SEAL, LECTURER(CST)


3
Module 7

• POINTER TO OBJECTS:
Object pointers are useful in creating objects at runtime.
They access the public members of objects.
#include<iostream.h>
#include<conio.h>
class item
{ int code;
float price;
public:
void getdata(int a,float b)
{ code=a; price=b;}
void show()
{ cout << "CODE: "<<code<<endl;
cout << "PRICE: "<<price<<endl;
}
};
const int size=2;
void main()
{ item *p=new item[size];
item *d=p;
int x,i;
float y;
for(i=0;i<size;i++)
{
cout << "Enter CODE and PRICE for item "<<i+1<<endl;
cin >> x >> y;
p->getdata(x,y);
p++; OUTPUT:
} Input CODE and PRICE for item1 20 300
for(i=0;i<size;i++) Input CODE and PRICE for item2 30 400
{ ITEM: 1
cout << "ITEM: "<<i+1<<endl; CODE: 20
d->show(); PRICE: 300
d++; ITEM: 2
} CODE: 30
getch(); PRICE: 400
}

ANIRBAN SEAL, LECTURER(CST)


4
Module 7

• ‘this’ POINTER:
C++ uses a unique keyword called ‘this’ to represent an object that invokes a member function.
‘this’ is a pointer that points to the object for which ‘this’ function was called. ‘this’ unique
pointer is automatically passed to a member function when it is called. The pointer ‘this’ acts as
an implicit argument to all the member functions.

class ABC
{
int a;
a=12
Say here member variable a=12 is same as this
…….
…….
};

 Example:
#include<iostream.h>
#include<conio.h>
#include<string.h>
class person
{
char name[20];
float age;
public:
person(char *s,float a)
{
strcpy(name,s);
age=a;
}
person & person::greater(person & x)
{
if(x.age>=age)
return x; //argument object
else
return *this; //invoking object
}
void display(void)
{
cout << "Name: "<<name<<endl;
cout << "Age: "<<age<<endl;

ANIRBAN SEAL, LECTURER(CST)


5
Module 7

}
};
void main()
{
clrscr();
person p1("Sachin",37.50);
person p2("Sourav",29.0);
person p3("Rahul",40.25);
person p('\0',0);
p=p1.greater(p3);
OUTPUT:
cout << "Elder person is: \n";
Elder person is:
p.display();
Name: Rahul
p=p1.greater(p2);
Age: 40.25
cout << "Elder person is: \n";
Elder person is:
p.display();
Name: Sachin
getch();
Age: 37.5
}

Here

return *this

will return the object that invoked the function. This statement assumes importance when we
want to compare two or more objects inside a member function and return the invoking object as
a result.

The function

A.greater(B)

Will return the object B(argument object) if the age of the person B is greater than that of A,
otherwise, it will return the object A(invoking object) using the pointer this.

* is dereference operator produces the contents at the address contained in the pointer this.

ANIRBAN SEAL, LECTURER(CST)


6
Module 7

• POINTER TO DERIVED CLASSES:


 We can use pointer not only to the base objects but also to the objects of derived
classes.

 Pointers to objects of a base class are type-compatible with pointers to objects of a


derived class.

 A base class pointer can point to any object derived from the base but cannot
directly access all the members of the derived class.

 A derived class pointer can access all the members of derived class and base
class(only public members)

 Base class pointer bptr can be type casted to derived class type to access all the
derived class members and functions directly.

#include<iostream.h>
#include<conio.h>
class base
{
public:
int b;
void show()
{
cout <<"b= "<<b<<"\n";
}
};
class derived:public base
{
public:
int d;
void show()
{
cout <<"b= "<<b<<"\n";
cout <<"d= "<<d<<"\n";
}
};

ANIRBAN SEAL, LECTURER(CST)


7
Module 7

void main()
{
clrscr();
base *bptr;
base bobj;
bptr=&bobj;
bptr->b=100;
cout <<"bptr points to base object \n";
bptr->show();
//derived class
derived dobj;
bptr=&dobj; //address of derived object
bptr->b=200; //access derived via base pointer
/* bptr->d=300 */ //will not work as bptr is a base class pointer
cout <<"bptr now points to derived object \n";
bptr->show();
//accessing d using a pointer of type class derived
derived *dptr;
dptr=&dobj;
dptr->d=300;
cout <<"dptr is derived type pointer \n";
dptr->show();
cout << "using ((derived *)bptr)\n";
((derived *)bptr)->d=400; //cast bptr to derived class type
((derived *)bptr)->show();
getch();
}

OUTPUT:
bptr points to base object
b= 100
bptr now points to derived object
b= 200
dptr is derived type pointer
b= 200
d=300
using ((derived *)bptr)
b= 200
d= 400

ANIRBAN SEAL, LECTURER(CST)


8
Module 7

• VIRTUAL FUNCTION:

We have seen in the earlier topic i.e. “Pointers to Derived object” that,
 A base class pointer can point to any object derived from the base but cannot
directly access all the members of the derived class.

But in polymorphism similar function (same function name) of different objects should
be referred regardless of their associative classes. Thus a single pointer variable of base class is
needed to refer to the objects of the base and the derived class too.
To achieve this requirement the function in the base class needed to be virtual so that
C++ compiler can determine which function to use at runtime based on the type of object
pointed to the base pointer, rather than the type of the pointer. Thus by making the base pointer
to point different objects we can execute different versions of the virtual function.

#include<iostream.h>
#include<conio.h>

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); }
};
class CTriangle: public CPolygon
{
public:
int area()
{ return(width * height / 2); }
};

ANIRBAN SEAL, LECTURER(CST)


9
Module 7

void main ()
{
clrscr();
CRectangle rect; OUTPUT:
CTriangle trgl;
CPolygon poly; Area of Rectangle: 20 sq. unit
CPolygon * ppoly1 = &rect;
Area of Triangle: 10 sq. unit
CPolygon * ppoly2 = &trgl;
CPolygon * ppoly3 = &poly; Area of Polygon: 0 sq. unit
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
ppoly3->set_values (4,5);
cout << "Area of Rectangle: "<<ppoly1->area()<<" sq. unit"<< endl;
cout << "Area of Triangle: "<<ppoly2->area()<<" sq. unit"<< endl;
cout << "Area of Polygon: "<<ppoly3->area()<<" sq. unit"<< endl;
getch();
}

• Rules of Virtual functions:


1. The virtual functions must be members of some class.
2. They can’t be static members.
3. They are accessed by using object pointers.
4. A virtual function can be a friend of another class.
5. A virtual function in the base class must be defined even though it may not be used.
6. The prototypes of the base class version of a virtual function and all the derived class
versions must be identical. If two functions with same name but different parameters will
be treated as function overloading rather than virtual function by C++ compiler.
7. We can’t have virtual constructors but can have virtual destructors.
8. A base pointer can point any type of derived object but a derived pointer can’t point an
object of base type.[Program of ‘POINTER TO DERIVED OBJECTS’ proves it]
9. If a virtual function is defined in the base class, it may not be necessarily redefined in the
derived class. Here the call will invoke base function.

ANIRBAN SEAL, LECTURER(CST)


10
Module 7

• PURE VIRTUAL FUNCTION:

It is a “DO NOTHING” function having the following way of declaration:

virtual void function_name( )=0

 A pure virtual function is a function declared in a base class that has no definition
relative to the base class.
 In such cases the C++ compiler requires each derived class to either define the
function or re- declare it as a pure virtual function.
 A base class containing pure virtual functions can’t be used to declare any objects
of its own. Such classes are called abstract base classes. The abstract base class
creates base pointer required for achieving runtime polymorphism.

Example:

#include<iostream.h>
#include<conio.h>

class CPolygon
{
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
virtual int area (void) =0; //pure virtual function makes class abstract
};
class CRectangle: public CPolygon
{
public:
int area (void)
{ return (width * height); }
};
class CTriangle: public CPolygon
{
public:
int area (void)

ANIRBAN SEAL, LECTURER(CST)


11
Module 7

{ return (width * height / 2); }


};

void main ()
{
clrscr();
// CPolygon poly; //Can't create object of an abstract class
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = &rect;
CPolygon * ppoly2 = &trgl;
// CPolygon * ppoly3 = &poly;
ppoly1->set_values (4,5);
ppoly2->set_values (4,5);
// ppoly3->set_values (4,5);

cout << "Area of Rectangle: "<<ppoly1->area()<<" sq. unit"<< endl;


cout << "Area of Triangle: "<<ppoly2->area()<<" sq. unit"<< endl;
// cout << "Area of Polygon: "<<ppoly3->area()<<" sq. unit"<< endl;
getch();
}

OUTPUT:

Area of Rectangle: 20 sq. unit

Area of Triangle: 10 sq. unit

ANIRBAN SEAL, LECTURER(CST)


12

You might also like