CHAPTER 06g Polymorphism in C++
CHAPTER 06g Polymorphism in C++
POLYMORPHISM marks 16
Objectives:
Polymorphism concept & its types.
Program for overloading operators & functions.
6.1 Introduction, Types of polymorphism: Compile time, Run time
6.2 Compile time Polymorphism: Function overloading, operator overloading: Overloading unary and binary
operators, Rules for operator overloading.
6.3 Run time polymorphism: Virtual functions, rules for virtual functions, pure virtual function.
INTRODUCTION :
Ques – Explain the concept of polymorphism. (4M)
• Polymorphism is one of the crucial features of OOP.
• “Polymorphism is a Greek term means “The ability to take more than one
forms”. An operation may exhibit different behavior in different instances.
The behavior depends upon the types of data used in the operation.
• The polymorphism can be 1) Compile time polymorphism or 2) runtime polymorphism
• Operator over loading and function over loading are the best examples of Compile time polymorphism.
• C++ allows operators and functions to operate in different ways, depending upon on what they are operating.
• Consider the example of operator overloading. For example if operands are two numbers, the + operator will
generate a sum of two numbers. But if operands are strings the + operator generates the third string by
concatenation. This mechanism is called operator overloading.
• Similarly functions can be overloaded to perform different task for different situation, depending upon the data
types of the arguments. More than one function can have same name but different number of arguments and / or
with different data types. At the time of compilation compiler matches the number and data type of arguments.
And accordingly binds the function definition with each function calls. This mechanism is called function
overloading.
• In compile time polymorphism the linking of code to be executed in response to a particular function call is done
at the compilation that is why it is also called early binding.
• In Run time polymorphism the linking of code to be executed in response to a particular function call is done at
the run time that is why it is also called late binding.
• Example of late binding is virtual functions.
• To understand the concept of virtual function considers the following example.
• In the above example all three classes Circle Box and triangle are derived from the common base class Shape.
Shape
Draw()
Polymorphism
Shape
Draw()
FUNCTION OVERLOADING
CHAPTER 5
Ques : Polymorphism is implemented using function overloading . Justify the statement. The general meaning of
polymorphism is “The ability to take more than one forms” . Polymorphism can be achieved by using function
overloading.
• Function overloading is a feature of c++ that allows a function to behave in more than one way depending upon
the number and / or type of arguments passed to it.
• There can be more than one function -definitions with the same name but with the different number of arguments
or different data types in a program.
• The compiler determines which function code is be executed in response to the function call, just by matching the
number and /or type of arguments passed to it. Since the compiler knows this information at compile time, it is
called as compile time polymorphism or early binding.
• Thus, more than one the functions with the same name but with the different no. of arguments or different data
types can exist in program.
Example: consider the following function prototypes.
1) int add (int ,int); // function prototype to add two integers
2) double add ( double ,double); // function prototype to add two doubles
3) int add (int ,int ,int); // function prototype to add three integers
• Therefore when a function is called as add ( 10,20) ; the first definition will be called.
• For function call add(12.3 ,56.8); the second definition will be called.
• And for function call add ( 5,6,7); the third definition will be called.
NOTE : when functions are overloaded , compiler does not check for return data type. It only matches the no. and the
type of arguments passed to it.
Thus following function definitions will lead to an error.
int f (int );
void f (int );
Ex:
#include<iostream.h>
int volume(int s)
{ return (s*s*s);
}
double volume( double r,int h)
{ return (3.14*r*r*h);
}
void main()
{
cout<<”volume of cube is”<<volume(5);
cout<<”volume of cylinder is”<<volume(10.5,8);
getch();
}
CHAPTER 5
PROGRAM BASED ON FUNCTION OVERLOADING:
❖ Write a program to find out area of a circle and rectangle using function
overloading.
# include <iostream.h>
double area (int); // function prototype
double area ( int ,int ); // function prototype
void main()
{
double r1,r2;
r1=area( 4 );
r2=area( 4 ,8);
cout << “\n Area of circle is=” <<r1; // Invokes first definition
cout << “\n Area of rectangle is=” << r2; // Invokes second definition
}
double area ( int r)
{
double a;
a = 3.14 * r*r ;
return a;
}
double area (int l ,int b)
{
double a;
a = l*b;
return a;
}
❖ Write a program for function overloading which will find the maximum
number between three integers and maximum number between three double
numbers.
# include <iostream.h>
int max (int , int ,int); // function prototype for three integers
double max ( double, double, double); //function prototype for three double
void main()
{
cout << max ( 3, 6, 8); // Invokes first definition
cout << max ( 3.4 , 6.7 , 1.2); // Invokes second definition
}
CHAPTER 5
int max ( int a ,int b,int c)
{
if ( a > b && a >c)
return a;
elseif ( b > a && b > c)
return b;
else
return c;
}
double max (double a , double b , double c)
{
if ( a > b && a >c)
return a;
elseif ( b > a && b > c)
return b;
else
return c;
}
Program: Compile time polymorphism using function overloading: (Logic: 2Marks Syntax: 2Marks)
#include<iostream.h> #include<conio.h>
Class Example
{ private:
char ch;
int num;
public:
void show(char a)
{
ch = a;
cout<< “ The character is “ <<num << endl;
}
Void show(int b)
{
num = b;
cout<<”the integer is” << num << endl;
}};
Void main()
{
clrscr();
Example ob; // object of class example created
ob.show(12);
ob.show(„x‟);
getch();
}
O/p :
The integer is : 12
The character is : x
In above program class example has two functions with same name show() but different parameters. Hence we can say that
show() function has been overloaded. So it is called as function overloading to implement compile time polymorphism.
CHAPTER 5
OPERATOR OVERLOADING
• Operator overloading refers to giving normal c++ operators such as +, - ,*, / additional meaning when they are
applied to the user defined data types.
• It allows us to extend the functionality of an existing operator to operate on user defined data type.
• For example you can create your own data type complex and can overload + operator to add two complex
numbers.
Advantages of operator overloading
• Extends the functionality of existing operators so that they can work with user defined data type.
• Operator overloading makes the program more readable and easy to understand.
Operators
❖ Program to overload the ! operator to find out factorial of a number (specimen paper)
# include <iostream .h>
class fact
{
int no;
public:
fact (int a)//5
{
no=a; //no=5;
}
void operator !(void)
{
long int f = 1;
for (int I =1; I<=no ; I++)//1<= 5,1++ 2<=5 3<=5 4<=5 5<=5 6<=5 false
{
f = f * I;//f=1*1=1//1*2= 2 f=2*3=6 f=6*4=24 f=24*5=120
}
cout << “Factorial = “ << f;//120
}
};
void main()
{
fact f1 (5);
!f1;
}
❖ Write a program to overload ++ operator to increment the distance by one ( distance is in feet and inches)
# include <iostream.h>
Class distance
{
CHAPTER 5
int feet , inches;
public :
distance () // default constructor
{}
distance (int f , int I)
{
feet =f;
inches =I;
}
void operator ++ (void)
{
inches = inches + 1; // increment inches by 1
if ( inches >= 12 ) // if inches > 12 then convert inches into feet
{
inches = inches - 12;
feet++;
}
}
void showdata(void)
{
cout << feet << “Feet and ” << inches << “ Inches ” ;
}
};
void main()
{
distance d1(3,6);
++d1;
d1.showdata();
}
OUTPUT
3 feet and 7 inches
Overloading Binary operators:
Binary operator overloading requires one parameter (object of the same class) to the operator member function.
void getdata(void)
{
cout<< “ \n Enter the value of real part”;
cin>>real; //4 7
cout<< “ \n Enter the value of img part”;
cin>>img; //8 4
}
/*//default constructor to initialize
Complex()
{
real = 0;
imag = 0;
}
// parameterized constructor
Complex(float r, float i)
{
real = r;
imag = i;
}*/
CHAPTER 5
OUTPUT
8 + i 10
#include <iostream>
using namespace std;
class Distance
{
private:
int feet, inch;
public:
Distance(int f, int i)
{
this->feet = f;
this->inch = i;
}
CHAPTER 5
friend void operator--(Distance d1)
{
d1.feet--;
d1.inch--;
cout << "\nFeet & Inches(Decrement): " <<d1.feet << "'" << d1.inch;
}
};
int main()
{
Distance d2(8, 9);
--d2;
return 0;
}
# include <iostream.h>
class increment
{
private :
int no;
public :
increment (int x ) // constructor to initialize no
{
no = x ;
}
void display()
{
cout << “ no= “ << no;
}
# include <iostream>
using namespace std;
class decrement
{
private :
int no;
public :
decrement (int x ) // constructor to initialize no
{
no = x ;
}
void display()
{
cout << "no=" << no;
}
#include<iostream>
CHAPTER 5
using namespace std;
class Number{
private:
float number;
public:
Number(float n)
{
number=n;
}
Number( )
{
}
friend number operator -(Number &n);
void display()
{
cout<<"Number:"<<number<<endl;
}
};
int main(){
Number num1(10),num2;
cout<<"Beore operation: num1 and num2 are:"<<endl;
num1.display();
num2.display();
num2 = -num1;
cout<<"After operation: num1 and num2 are:"<<endl;
num1.display();
num2.display();
return 0;
}
CHAPTER 5
#include<iostream>
using namespace std;
class Number
{
private:
float number;
public:
Number(float n)
{
number=n;
}
Number( )
{
}
friend void operator -(Number &n);
void display()
{
cout<<"Number:"<<number<<endl;
}
};
int main()
{
Number num1(10);
cout<<"Before operation: num1 :"<<endl;
num1.display();
-num1;
cout<<"After operation: num1:"<<endl;
num1.display();
return 0;
CHAPTER 5
}
FUNCTION OVERRIDING:
“When a base class and derived class define a function of same name , same number of arguments with same
data types, the derived class function supersedes (take precedence over ) the base class function. This mechanism is
called function overriding.”
• The base class function will be called only if the derived class does not redefine the function.
• Here the base class function is said to be overridden by the derived class function.
class base
{
public :
void fun1 (void)
{
cout << “In base class fun1 “<<endl;
}
void fun2 (void)
{
cout << “In base class fun2 “<<endl;
}
};
class derived : public base
{
public :
void fun1 (void) // redefining fun1 ()
{
base:: fun1( );
cout << “In derived class fun1 “ <<endl;
}
void fun3 (void) // redefining fun1 ()
{
cout << “In derived class fun3 “ <<endl;
}
};
void main (void)
{
derived d1;
d1.fun1(); // Invokes derived :: fun1()
d1.fun2 () ; //Invokes base :: fun2()
d1.fun3(); // Invokes derived :: fun3()
}
OUTPUT
In derived class fun1
In base class fun2
In derived class fun3
• The rule is when the same function exist in both base and derived class the derived class function will be
executed.
Function overloading Function overriding
1)When more than one function exists with the same name 1)The same function name with the same prototype exist in
but with different no. of arguments and / or different data base class and derived class, it is called function overriding.
types it is called function overloading.
2) They can be static or non-static 2) They must be non-static members of classes
3) Overloaded functions can be friends 3) These functions cannot be friends
4) Constructor can be overloaded but destructors cannot be 4) Constructors & destructors cannot be override.
overloaded
5) The function to be executed is determined by matching 5) When function is overridden always the derived class
the no. and type of arguments passed to it. function is invoked.
Example:Class area Example:Class base
{ {
CHAPTER 5
public : void display() // overriden function
void area (int) // overloaded function { }
{} };
void area (int ,int ) // overloaded fun class derived : public base
{} {
}; void display ()
{ }
};
RUN TIME POLYMORPHISM
VIRTUAL FUNCTIONS:
Ques : Explain the concept of virtual function.
Ques : What is virtual function . Why do we need virtual function?
• Virtual function is that which does not really exist but nevertheless appears real to some part of the program.
• We use virtual functions when we have number of objects of different classes and we want to put them together on
a list and perform a particular operation using a single function call.
• When we use a pointer to base class to refer to the derived class object, always base class function is invoked,
even if the pointer contains the address of derived class object. This is because; compiler ignores the contents of
pointer and chooses the member function that matches the type of a pointer.
• Using virtual function mechanism we can force the compiler to look at the contents of the pointer rather than the
type of the pointer at the time invoking the function.
• When the same function exist in both base and derived class, the base class function is made virtual using
keyword virtual.
• When a function in a base class is made virtual, C++ determines which function to invoke at run time based on the
type of object pointed by the base class pointer rather than the type of the pointer.
• Thus by making the base class pointer to point to different objects, we can execute different versions of the virtual
functions.
• Runtime polymorphism is achieved only when a virtual function is accessed through a pointer to the base class.
void draw ()
{
// code to draw a circle
}
};
class box :public shape
{
public: void draw()
{
// assume code to draw a box
}
};
class rectangle :public shape
{
public: void draw()
{
// assume code to draw a rectangle
}
};
void main()
{
shape *p;
circle c;
p =&c ;
c -> draw() ; // invokes circle :: draw();
rectangle r;
p = & r;
p -> draw(); // invokes rectangle :: draw()
box b;
p =&b;
p-> draw(); // Invokes box :: draw()
}
}
};
class triangle: public shape
{
public:void display_area()
{
float area;
area = 0.5 * a*b;
cout <<”Area of triangle : “<<area;
}
};
CHAPTER 5
❖ Program to overload the ! operator to find out factorial of a number (specimen paper)
# include <iostream .h>
class fact
{
int no;
public:
fact (int a)//5
{
no=a; //no=5;
}
void operator !(void)
{
long int f = 1;
for (int I =1; I<=no ; I++)//1<= 5,1++ 2<=5 3<=5 4<=5 5<=5 6<=5 false
{
f = f * I;//f=1*1=1//1*2= 2 f=2*3=6 f=6*4=24 f=24*5=120
}
cout << “Factorial = “ << f;//120
}
};
void main()
{
fact f1 (5);
!f1;
}
❖ Write a program to overload ++ operator to increment the distance by one ( distance is in feet and
inches)
# include <iostream.h>
class distance
{
int feet , inches;
public :
distance () // default constructor
{}
distance (int f , int i)
{
feet =f;
inches =i;
}
void operator ++ (void)
{
inches = inches + 1; // increment inches by 1
if ( inches >= 12 ) // if inches > 12 then convert inches into feet
{
inches = inches - 12;
feet++;
}
CHAPTER 5
}
void showdata(void)
{
cout << feet << “Feet and ” << inches << “ Inches ” ;
}
};
void main()
{
distance d1(3,6);
++d1;
d1.showdata();
}
OUTPUT
3 feet and 7 inches
Overloading Binary operators:
Binary operator overloading requires one parameter (object of the same class) to the operator member function.
❖ Write a program to overload + operator to add two Time objects.
# include <iostream.h>
class time
{
int hr , min;
public :
time()
{
hr =0 ; min =0;
}
time (int h1, int m1)
{
hr = h1;
min =m1;
}
void showdata (void)
{
cout << hr << “:” << min ;
}
time operator + ( time t2)
{
time temp;
CHAPTER 5
temp.hr = hr + t2.hr; //7
temp.min = min + t2.min; //80
if ( temp.min >= 60 ) //80>= 60 true
{
temp.hr = temp.hr + (temp.min / 60); //temp.hr=7+(80 / 60)=7+1=8
temp.min = temp.min % 60; //80% 60=20
}
return temp;
}
};
void main()
{
time t1(3,50), t2( 4,30) ;
time t3; // default constructor is invoked
t3 =t1 + t2 ; // result is in t3
t3.showdata();
}
OUTPUT
8 : 20
void getdata(void)
{
cout<< “ \n Enter the value of real part”;
cin>>real; //4 7
cout<< “ \n Enter the value of img part”;
cin>>img; //8 4
}
complex operator + ( complex c2)
{
complex temp; // create a temporary object
temp. real = real + c2.real ;// 12
temp. img = img + c2.img; //11 // result is in temp object
return temp; // return temp object to the main prog.
}
void showdata (void)
CHAPTER 5
{
cout << “\n”<<real << “+”<< img<< “i”;
{
};
void main(void)
{
complex c1,c2,c3;
c1.getdata();
c2.getdata();
c3 =c1 + c2 ; // c2 is explicitly passed , result will be in c3.
c1.showdata();
c2.showdata();
c3.showdata();
}
❖ Write a program to overload + operator to add two complex numbers using friend
function.
OUTPUT
8 + i 10
CHAPTER 5
#include <iostream>
using namespace std;
class Distance
{
private:
int feet, inch;
public:
Distance(int f, int i)
{
this->feet = f;
this->inch = i;
}
friend void operator--(Distance d1)
{
d1.feet--;
d1.inch--;
cout << "\nFeet & Inches(Decrement): " <<d1.feet << "'" << d1.inch;
}
};
int main()
{
Distance d1(8, 9);
--d1;
return 0;
}
CHAPTER 5
# include <iostream.h>
class increment
{
private :
int no;
public :
increment (int x ) // constructor to initialize no
{
no = x ;
}
void display()
{
cout << “ no= “ << no;
}
# include <iostream>
using namespace std;
class decrement
{
private :
int no;
CHAPTER 5
public :
decrement (int x ) // constructor to initialize no
{
no = x ;
}
void display()
{
cout << "no=" << no;
}
#include<iostream>
using namespace std;
class Number{
private:
float number;
public:
Number(float n)
{
number=n;
}
Number( )
{
CHAPTER 5
}
friend number operator -(Number &n);
void display()
{
cout<<"Number:"<<number<<endl;
}
};
int main(){
Number num1(10),num2;
cout<<"Beore operation: num1 and num2 are:"<<endl;
num1.display();
num2.display();
num2 = -num1;
cout<<"After operation: num1 and num2 are:"<<endl;
num1.display();
num2.display();
return 0;
}
#include<iostream>
using namespace std;
class Number
{
CHAPTER 5
private:
float number;
public:
Number(float n)
{
number=n;
}
Number( )
{
}
friend void operator -(Number &n);
void display()
{
cout<<"Number:"<<number<<endl;
}
};
int main()
{
Number num1(10);
cout<<"Before operation: num1 :"<<endl;
num1.display();
-num1;
cout<<"After operation: num1:"<<endl;
num1.display();
return 0;
}