0% found this document useful (0 votes)
30 views14 pages

Polymorphism

The document discusses polymorphism and how it is achieved through compile time polymorphism and run time polymorphism. It also discusses pointers, abstract classes, virtual functions and late binding in object oriented programming.

Uploaded by

Vani Vats
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views14 pages

Polymorphism

The document discusses polymorphism and how it is achieved through compile time polymorphism and run time polymorphism. It also discusses pointers, abstract classes, virtual functions and late binding in object oriented programming.

Uploaded by

Vani Vats
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Polymorphism

Introduction
Polymorphism is the combination of two greek words one is poly means many and other
one is morphism means form.
“whose meaning is same having different behavior.”
Types –
a) Compile Time polymorphism: achieved by compile time called static
polymorphism/ early binding.
Example: Method overloading.

b) Run Time polymorphism: Polymorphism, which is achieved by run time, called


dynamic polymorphism/ late binding.
Example: Method overriding.

Polymorphism

Compile Time Run Time

Function Operator Operator


Overloading Overloading Overloadin

Void add (int x, int y)


{
….

}
Void add (int x, float y)
{
….
}
When an object is created from its class, the member variables and member functions
are allocated memory spaces. The memory spaces have unique addresses. Pointer is a
mechanism to access these memory locations using their address rather than the name
assigned to them. You will study the implications and applications of this mechanism
in detail in this chapter.

Pointer is a variable which can hold the address of a memory location rather than the
value at the location. Consider the following statement
int num = 84;
This statement instructs the compiler to reserve a 2-byte of memory location and puts
the value 84 in that location. Assume that the compiler allocates memory location 1001
to num. Diagrammatically, the allocation can be shown as:
num Variable name

84 Value

1001 Address of memory location


Figure 9.1
As the memory addresses are themselves numbers, they can be assigned to some other
variable For example, ptr be the variable to hold the address of variable num.
Thus, we can access the value of num by the variable ptr. We can say “ptr points to
num” as shown in the figure below.

Abstract class:
A class which contain atleast one pure virtual function. We cannot declare the object
of abstract class.
Syntax:
Class A
{
Public:
Virtual void show()=0;

};

Virtual Functions
Virtual functions, one of advanced features of OOP is one that does not really exist but
it appears real in some parts of a program. This section deals with the polymorphic
features which are incorporated using the virtual functions.

The general syntax of the virtual function declaration is:


class use_detined_name{
private:
public:
virtual return_type function_name1 (arguments);
virtual return_type function_name2(arguments);
------------------
};
To make a member function virtual, the keyword virtual is used in the methods while it
is declared in the class definition but not in the member function definition. The
keyword virtual precedes the return type of the function name. The compiler gets
information from the keyword virtual that it is a virtual function and not a conventional
function declaration.
For. example, the following declararion of the virtual function is valid.
class point {
intx;
inty;
public:
virtual int length ( );
virtual void display ( );
};

Remember that the keyword virtual should not be repeated in the definition if the
definition occurs outside the class declaration. The use of a function specifier virtual in
the function definition is invalid.
For example
class point {
intx ;
inty ;
public:
virtual void display ( );
};
virtual void point: : display ( ) //error
{
Function Body
}

A virtual function cannot be a static member since a virtual member is always a member
of a particular object in a class rather than a member of the class as a whole.
class point {
int x ;
int y ;
public:
virtual static int length ( ); //error
};
int point: : length ( )
{
Function body
}
A virtual function cannot have a constructor member function but it can have the
destructor member
function.
class point {
int x ;
int y ;
public:
virtual point (int xx, int yy) ; // constructors, error
void display ( ) ;
int length ( ) ;
};

A destructor member function does not take any argument and no return type can be
specified for it
not even void.
class point {
int x ;
int y ;
public:
virtual point (int xx, int yy) ; //invalid
void display ( ) ;
int length ( ) ;
Late Binding
As we studied in the earlier unit, late binding means selecting functions during the
execution. Though late binding requires some overhead it provides increased power and
flexibility. The late binding is implemented through virtual functions as a result we have
to declare an object of a class either as a pointer to a class or a reference to a class.

For example the following shows how a late binding or run time binding can be carried
out with the help of a virtual function. The following program demonstrates the run
time binding of the member functions of a class. The same message is given to access
the derived class member functions from the array of pointers. As function are declared
as virtual, the C++ compiler invokes the dynamic binding.
#include <iostream>
using namespace std;
class baseA
{
public :
virtual void display() {
cout<< "One \n"; }
};
class derivedB : public baseA
{
public:
virtual void display() {
cout<< "Two\n"; }
};
class derivedC: public derivedB
{
public:
virtual void display ( ) {
cout<< "Three \n"; }
};
int main ( )
{
baseA obja; //define three objects
derivedB objb;
derivedC objc;
baseA *ptr [3]; //define an array of pointers to baseA
ptr [0] = &obja;
ptr [1] = &objb;
ptr [2] = &objc;
for ( int i = 0; i <=2; i ++ )
ptr [i]->display (); //same message for all objects
}

Output
One
Two
Three

The program listed below illustrates the static binding of the member functions of
a class. In program there are two classes student and academic. The class academic is
derived from class student. The two member function getdata and display are defined
for both the classes. *obj is defined for class student, the address of which is stored in
the object of the class academic. The functions getdata ( ) and display ( ) of student class
are invoked by the pointer to the class.
#include<iostream>
using namespace std;
class student
{
private:
int rollno;
char name [20];
public:
void getdata();
void display();
};
class academic: public student
{
private:
char stream;
public:
void getdata();
void display();
};
void student :: getdata()
{
cout<< "Enter Roll no\n";
cin>> rollno;
cout<< "Enter Name \n";
cin>> name;
}
void student:: display()
{
cout<< "the student’s roll number is : "<< rollno;
cout<< "\n and name is : " << name ;
cout<< endl;
}
void academic :: getdata()
{
cout<< "Enter stream of a student? \n";
cin >> stream;
}
void academic :: display()
{
cout<< "Students stream \n";
cout << stream << endl;
}
int main()
{
student *ptr;
academic obj;
ptr = &obj;
ptr -> getdata();
ptr -> display();
}
output
Enter Roll no : 20
Enter Name : rajat
the student’s roll number is : 20
and name is : rajat

The program listed below illustrates the dynamic binding of member functions of a
class. In this program there are two classes student and academic. The class academic
is derived from student. Student function has two virtual functions getdata ( ) and
display (). The pointer for student class is defined and object . for academic class is
created. The pointer is assigned the address of the object and function of derived class
are invoked by pointer to student.
#include <iostream>
using namespace std;
class student
{
private:
int rollno;
char name [20];
public:
virtual void getdata();
virtual void display();
};
class academic: public student
{
private:
char stream[10];
public:
void getdata ();
void display () ;
};
void student:: getdata()
{
cout<< "Enter Rollno\n";
cin >> rollno;
cout<< "Enter Name \n";
cin >>name;
}
void student:: display()
{ cout<< "The student’s roll number is "<< rollno;
cout<< "and name is "<<name; }
void academic:: getdata()
{ cout << "Enter stream of a student? \n";
cin>> stream; }
void academic:: display()
{
cout<< "Students stream : ";
cout<< stream << endl;
}
int main()
{
student *ptr;
academic obj;
ptr = &obj;
ptr->getdata();
ptr->display();
}
output
Enter stream of a student?
CSE
Students stream : CSE
Pure Virtual Functions
1) Pure virtual function are virtual function which have no definition. They start with
virtual keyword and ends with equal to zero.
2) If we don’t override the virtual function in derive class than derive class also becomes
abstract class.
3) We cannot change the signature of pure virtual function.
The following program demonstrates how a pure virtual function is defined, declared
and invoked from the object of a derived class through the pointer of the base class.
#include<iostream>
using namespace std;
class A
{
public:
virtual void show()=0;
void disp()
{
cout<<"Hi i am base class"<<"\n";
}
};
class B: public A
{
public:
void show()
{
cout<<"Hi i am derived class"<<"\n";
}
};
int main()
{
B obj;
obj.disp();
obj.show();
}
Output:
Hi i am base class
Hi i am derived class

If we want to access class A pointer variables.

#include<iostream>
using namespace std;
class A
{
public:
virtual void show()=0;
void disp()
{
cout<<"Hi i am base class"<<"\n";
}
};
class B: public A
{
public:
void show()
{
cout<<"Hi i am derived class"<<"\n";
}
};
int main()
{
A *p;
B obj;
p=&obj;
p->disp();
p->show();
}

Output:
Hi i am base class
Hi i am derived class

In the example there are two classes employee and grade. The class employee is base
class and the grade is derived class. The functions getdata ( ) and display ( ) are declared
for both the classes. For the class employee the functions are defined with empty body
or no code inside the function. The code is written for the grade class. The methods of
the derived class are invoked by the pointer to the base class.
#include<iostream>
using namespace std;
class employee
{
int code;
char name [20] ;
public:
virtual void getdata ( ) ;
virtual void display ( ) ;
};
class grade: public employee
{
char grd [90] ;
float salary ;
public :
void getdata ( ) ;
void display ( );
};
void employee :: getdata()
{
}
void employee:: display()
{
}
void grade :: getdata()
{
cout<< " enter employee’s grade ";
cin>> grd ;
cout<< "\n enter the salary " ;
cin>> salary;
}
void grade :: display()
{
cout<<" Grade salary \n";
cout<< grd<< " "<< salary<< endl;
}
int main()
{
employee *ptr;
grade obj;
ptr = &obj;
ptr->getdata();
ptr->display();
}
Output
enter employee’s grade A
enter the salary 250000
Grade salary
A 250000
Object Slicing:

In C++, a derived class object can be assigned to a base class object, but the other
way is not possible.

class Base { int x, y; };


class Derived : public Base { int z, w; };
int main()
{
Derived d;
Base b = d; // Object Slicing, z and w of d are sliced off
}

Object Slicing happens when a derived class object is assigned to a base class object,
additional attributes of a derived class object are sliced off to form the base class
object.
#include <iostream>
using namespace std;

class Base
{
protected:
int i;
public:
Base(int a) { i = a; }
virtual void display()
{ cout << "I am Base class object, i = " << i << endl; }
};

class Derived : public Base


{
int j;
public:
Derived(int a, int b) : Base(a) { j = b; }
virtual void display()
{ cout << "I am Derived class object, i = "
<< i << ", j = " << j << endl; }
};
// Global method, Base class object is passed by value
void somefunc (Base obj)
{
obj.display();
}

int main()
{
Base b(33);
Derived d(45, 54);
somefunc(b);
somefunc(d); // Object Slicing, the member j of d is sliced off
return 0;
}

Output:

I am Base class object, i = 33


I am Base class object, i = 45

We can avoid above unexpected behavior with the use of pointers or references. Object
slicing doesn’t occur when pointers or references to objects are passed as function
arguments since a pointer or reference of any type takes same amount of memory. For
example, if we change the global method myfunc() in the above program to following,
object slicing doesn’t happen.

// rest of code is similar to above


void somefunc (Base &obj)
{
obj.display();
}
// rest of code is similar to above

Output:

I am Base class object, i = 33


I am Derived class object, i = 45, j = 54

We get the same output if we use pointers and change the program to following.

// rest of code is similar to above


void somefunc (Base *objp)
{
objp->display();
}
int main()
{
Base *bp = new Base(33) ;
Derived *dp = new Derived(45, 54);
somefunc(bp);
somefunc(dp); // No Object Slicing
return 0;
}

Output:

I am Base class object, i = 33


I am Derived class object, i = 45, j = 54

Object slicing can be prevented by making the base class function pure virtual there
by disallowing object creation. It is not possible to create the object of a class which
contains a pure virtual method.

LECTURE-33

C++ Function Overriding

You might also like