0% found this document useful (0 votes)
27 views26 pages

Polymorphism - MCA

This document covers Object-Oriented Programming (OOP) concepts in C++, focusing on polymorphism, exception handling, and operator overloading. It explains compile-time and run-time polymorphism, including function and operator overloading, along with their rules and examples. The unit aims to enhance understanding of inheritance, pointers, and virtual functions in C++.

Uploaded by

rahuljohri22
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)
27 views26 pages

Polymorphism - MCA

This document covers Object-Oriented Programming (OOP) concepts in C++, focusing on polymorphism, exception handling, and operator overloading. It explains compile-time and run-time polymorphism, including function and operator overloading, along with their rules and examples. The unit aims to enhance understanding of inheritance, pointers, and virtual functions in C++.

Uploaded by

rahuljohri22
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/ 26

OOPS using C++

UNIT –V

STRUCTURE

5.0. Objectives
5.1. Introduction
5.2. Polymorphism:
5.2.1. Introduction & types of polymorphism
5.2.2. Function overloading
5.2.3. operator overloading,
5.2.4. rules for overloading operators
5.2.5. overloading of unary & binary operators.
5.3. Exception Handling:
5.3.1. Try
5.3.2. Throw
5.3.3. Catch
5.3.4. Throwing and Exception
5.3.5. Catching an Exception.
5.4. Let Us Sum Up
5.5. Key Words
5.6. Some Useful Books
5.7. Answer to check your progress
5.8. Terminal Questions

5.0. OBJECTIVES
After studying this unit, you will be able to:
• Understand different types of Inheritance
• Understand the concept of Pointers
• Create Virtual Functions
• Implement polymorphism

154
OOPS using C++

5.1. INTRODUCTION

Polymorphism means the ability to take multiple forms. It means 'one


name, multiple forms'. Polymorphism is an important feature of OOP;we
have already discussedhow the concept of polymorphism is implemented
using the overloaded function and operators.
Compiler selects the appropriate member functions by matching
arguments (both type and number) at the compile. This is called or static
binding or early binding or compiletime polymorphism. Static binding
simply means that an object is bound to its function at compile time.

5.2. POLYMORPHISM:

5.2.1. Introduction & types of polymorphism

For example,
Consider an example in which the function name and prototype are the
same in both base class and derived class
class X
{
int a;
public :
void show() // function in base class
{
……..
}
};
class Y: public X
{

155
OOPS using C++

int b;
public:
void show() // functionin derived class
{
………
}
};

Suppose we want to print the values of objects of both the classes X and
Y. Since the prototype of show () is the same in both the places we can’t
apply overloading principle. In such type of situations we can use the class
resolution operator to identify the class while invoking the functions using
the derived class objects.
The appropriate function can be selected while the program isexecuting,
which is known as run time polymorphism. C++ allows a mechanism
called virtual function to achieve run time polymorphism.
The appropriate 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 run time.
Following figure shows the catagories of polymorphism

Polymorphism

Compile time
Runtime

Virtual function Function overloading Operator


overloading

Figure 5.5 function in base class

156
OOPS using C++

Categorization of polymorphism techniques


We have seen that there are mainly two types of polymorphism, namely,
compile lime polymorphism and run time polymorphism.

Compile time polymorphism


Function overloading and operators overloading are examples of compile
time polymorphism. The overloaded member functions are considered for
invoking by matching arguments, both type and number. The compiler
knows this information at the compile time and, therefore, compiler is able
to select the appropriate function for a particular function call at the
compile time itself. It means that an object is bound to its function call at
compile time.

Run time polymorphism


In run time polymorphism, an appropriate member function is invoked
when executing the program. It is called late or dynamic binding because
the appropriate function is selected dynamically at run time. C++ supports
run time polymorphism with the help of virtual functions. Dynamic
binding requires use of pointers to objects and is one of the powerful
features of C++
There are four main types of polymorphism:

Let’s look at each.


Subtype polymorphism (Runtime)

157
OOPS using C++

Subtype polymorphism is the most common kind of polymorphism. It is


usually the one referenced when someone says, “The object is
polymorphic.”
A subtype polymorphism uses one class name to reference multiple kinds
of subtypes at once. In the car example above, we create the object class,
“Car”, and define multiple subtypes of it to be: Ford, Chevrolet, Kia,
Nissan, Volkswagen, BMW, Audi, and Tesla. Each car has its property
color.
All subtypes can be referenced interchangeably by using class Car.
Every car has a property, color, and now we can get the color from each
subtype of the Car class.
The polymorphism takes place at runtime. We can write a function to fetch
the color of any one of the car subtypes. The function may look like this
(not written in any specific programming language):
Copy
getColor(BMW)
→ returns red
getColor(Audi)
→ returns blue
getColor(Kia)
→ returns yellow
Parametric polymorphism (Overloading)
A parametric polymorphism specifically provides a way to use one
function (the same code) to interact with multiple types.
An example would be a list of types. A parametric polymorphism could
remove, add, or replace elements of this list regardless of the element’s
type.
The code, which could be a parametric polymorphism function written
in Python:
Copy
for (element in list):
list.remove(element)
Ad hoc polymorphism (Compile-time)
For ad hoc polymorphism, functions with the same name act differently
for different types.

158
OOPS using C++

Python is dynamically typed (it does not require the type to be specified).
The Python addition function is an ad hoc polymorphism because it is a
single function of the same name, “+”, that works on multiple types.
Both (Python):
Copy
3+4
"Foo" + "bar"
Return a value of their corresponding types, int and String, respectively.
Copy
→7
→ "Foobar"
For values of type int, the addition function adds the two values together,
so 3+4 returns 7. For values of type String, the addition function
concatenates the two strings, so “Foo” + “bar” returns, “Foobar”.
Coercion polymorphism (Casting)
Coercion polymorphism is the direct transformation of one type into
another. It happens when one type gets cast into another type. Before,
polymorphism occurred through interacting with different types through
the object class or the functions. An object’s type could be selected when
the program was run. A single function could work with different types.
A simple example is transforming number values from ints, to doubles, to
floats, and vice versa. Depending on the programming language, either the
type can be defined on the variable, or sometimes there exists a method on
the types to convert their value to another type.
Python will convert types like this:
Copy
int(43.2) #Converts a double to an int
float(45) #Converts an int to a float
Java might convert the type simply by defining the type:
Copy
int num = 23;
double dnum = num;
or
Copy
double dnum = Double.valueOf(inum);

159
OOPS using C++

5.2.2. Function overloading

Function Overloading is defined as the process of having two or more


function with the same name, but different in parameters is known as
function overloading in C++. In function overloading, the function is
redefined by using either different types of arguments or a different
number of arguments. It is only through these differences compiler can
differentiate between the functions.
The advantage of Function overloading is that it increases the readability
of the program because you don't need to use different names for the same
action.
C++ Function Overloading Example
Let's see the simple example of function overloading where we are
changing number of arguments of add() method.
// program of function overloading when number of arguments vary.
1. #include <iostream>
2. using namespace std;
3. class Cal {
4. public:
5. static int add(int a,int b){
6. return a + b;
7. }
8. static int add(int a, int b, int c)
9. {
10. return a + b + c;
11. }
12. };
13. int main(void) {
14. Cal C; // class object declarat
ion.
15. cout<<C.add(10, 20)<<endl;
16. cout<<C.add(12, 20, 23);
17. return 0;
18. }

160
OOPS using C++

Output:
30
55
Let's see the simple example when the type of the arguments vary.
// Program of function overloading with different types of arguments.
1. #include<iostream>
2. using namespace std;
3. int mul(int,int);
4. float mul(float,int);
5.
6.
7. int mul(int a,int b)
8. {
9. return a*b;
10. }
11. float mul(double x, int y)
12. {
13. return x*y;
14. }
15. int main()
16. {
17. int r1 = mul(6,7);
18. float r2 = mul(0.2,3);
19. std::cout << "r1 is : " <<r1<< std::endl;
20. std::cout <<"r2 is : " <<r2<< std::endl;
21. return 0;
22. }
Output:
r1 is : 42
r2 is : 0.6
Function Overloading and Ambiguity
When the compiler is unable to decide which function is to be invoked
among the overloaded function, this situation is known as function
overloading.

161
OOPS using C++

When the compiler shows the ambiguity error, the compiler does not run
the program.

5.2.3. operator overloading,

Operator overloading is a compile-time polymorphism in which the


operator is overloaded to provide the special meaning to the user-defined
data type. Operator overloading is used to overload or redefines most of
the operators available in C++. It is used to perform the operation on the
user-defined data type. For example, C++ provides the ability to add the
variables of the user-defined data type that is applied to the built-in data
types.
The advantage of Operators overloading is to perform different operations
on the same operand.
Operator that cannot be overloaded are as follows:
o Scope operator (::)
o Sizeof
o member selector(.)
o member pointer selector(*)
o ternary operator(?:)
Syntax of Operator Overloading
1. return_type class_name : : operator op(argument_list)
2. {
3. // body of the function.
4. }
Where the return type is the type of value returned by the function.
class_name is the name of the class.
operator op is an operator function where op is the operator being
overloaded, and the operator is the keyword.
Rules for Operator Overloading
o Existing operators can only be overloaded, but the new operators
cannot be overloaded.

162
OOPS using C++

o The overloaded operator contains atleast one operand of the user-


defined data type.
o We cannot use friend function to overload certain operators.
However, the member function can be used to overload those
operators.
o When unary operators are overloaded through a member function
take no explicit arguments, but, if they are overloaded by a friend
function, takes one argument.
o When binary operators are overloaded through a member function
takes one explicit argument, and if they are overloaded through a
friend function takes two explicit arguments.
C++ Operators Overloading Example
Let's see the simple example of operator overloading in C++. In this
example, void operator ++ () operator function is defined (inside Test
class).
// program to overload the unary operator ++.
1. #include <iostream>
2. using namespace std;
3. class Test
4. {
5. private:
6. int num;
7. public:
8. Test(): num(8){}
9. void operator ++() {
10. num = num+2;
11. }
12. void Print() {
13. cout<<"The Count is: "<<num;
14. }
15. };
16. int main()
17. {
18. Test tt;
19. ++tt; // calling of a function "void operator ++()"

163
OOPS using C++

20. tt.Print();
21. return 0;
22. }
Output:
The Count is: 10
Let's see a simple example of overloading the binary operators.
// program to overload the binary operators.
1. #include <iostream>
2. using namespace std;
3. class A
4. {
5.
6. int x;
7. public:
8. A(){}
9. A(int i)
10. {
11. x=i;
12. }
13. void operator+(A);
14. void display();
15. };
16.
17. void A :: operator+(A a)
18. {
19.
20. int m = x+a.x;
21. cout<<"The result of the addition of two objects is : "<<m;
22.
23. }
24. int main()
25. {
26. A a1(5);
27. A a2(4);
28. a1+a2;

164
OOPS using C++

29. return 0;
30. }
Output:
The result of the addition of two objects is : 9

5.2.4. rules for overloading operators

There are some rules for the operator overloading. These rules are like
below
• Only built-in operators can be overloaded. If some operators are
not present in C++, we cannot overload them.
• The arity of the operators cannot be changed
• The precedence of the operators remains same.
• The overloaded operator cannot hold the default parameters except
function call operator “()”.
• We cannot overload operators for built-in data types. At least one
user defined data types must be there.
• The assignment “=”, subscript “[]”, function call “()” and arrow
operator “->” these operators must be defined as member
functions, not the friend functions.
• Some operators like assignment “=”, address “&” and comma “,”
are by default overloaded.

5.2.5. overloading of unary & binary operators.

Unary Operator Overloading

As the name suggests, Unary operators operate on single operand or data.


Following are the examples of Unary operators:
• Unary minus ( – ) operator
• Logical not ( ! ) operator
• Decrement ( — ) and Increment ( ++ ) operator

165
OOPS using C++

Note : If increment/decrement operators are used before variable, they are


called prefix operators i.e ++x. And if increment/decrement operators are
used after variable, they are called postfix operators i.e x++.
Example: C++ program to illustrate the use of unary operator
overloading, increment ++ and decrement -- operator overloading
// unary_operator_overloading.cpp
#include <iostream>
using namespace std;

class check_count
{
public:
int count_plus;
int count_minus;

check_count()
{
count_plus = 0;
count_minus = 2;
};
void operator ++() { ++count_plus; } // count increment
void operator --() { --count_minus; } // count increment
};
int main()
{
check_count x, y; //creating objects

//before increment/decrement
cout << "x =" << x.count_plus<<"\n";
cout <<"y =" << y.count_minus<<"\n";

++x;
--y;

//after increment/decrement

166
OOPS using C++

cout<<"\nAfter increment/decrement\n";
cout<<"x ="<<x.count_plus<<"\n";
cout<<"y ="<<y.count_minus<<"\n";
return 0;
}
Output

Binary Operator Overloading

As the name suggests, those operators which operate on two operands or


data are called binary operators.
Here is an example to show how binary operators are overloaded in C++.
Example: C++ program to illustrate binary operator overloading
#include<iostream>
using namespace std;

class complex
{
private:
int real,imag;
public:
void getvalue()
{
cout<<"Enter the value of real number:";
cin>>real;
cout<<"Enter the value of imaginary number:";
cin>>imag;
}
complex operator+(complex obj)

167
OOPS using C++

{
complex temp;
temp.real=real+obj.real;
temp.imag=imag+obj.imag;
return(temp);
}
complex operator-(complex obj)
{
complex temp;
temp.real=real-obj.real;
temp.imag=imag-obj.imag;
return(temp);
}
void display()
{
cout<<real<<"+"<<"("<<imag<<")"<<"i"<<"\n";
}
};

int main()
{
complex c1,c2,c3,c4;

c1.getvalue();
c2.getvalue();

c3 = c1+c2;
c4 = c1-c2;

cout<<"Result is:\n";
c3.display();
c4.display();

return 0;

168
OOPS using C++

}
Output

5.3. EXCEPTION HANDLING:

When executing C++ code, different errors can occur: coding errors made
by the programmer, errors due to wrong input, or other unforeseeable
things.
When an error occurs, C++ will normally stop and generate an error
message. The technical term for this is: C++ will throw
an exception (throw an error).

5.3.1. Try

Exception handling in C++ consist of three


keywords: try, throw and catch:
The try statement allows you to define a block of code to be tested for
errors while it is being executed.

5.3.2. Throw

The throw keyword throws an exception when a problem is detected,


which lets us create a custom error.

169
OOPS using C++

The catch statement allows you to define a block of code to be executed,


if an error occurs in the try block.
The try and catch keywords come in pairs:
Example
try {
// Block of code to try
throw exception; // Throw an exception when a problem arise
}
catch () {
// Block of code to handle errors
}

5.3.3. Catch

• catch − A program catches an exception with an exception handler


at the place in a program where you want to handle the problem.
The catch keyword indicates the catching of an exception.

5.3.4. Throwing and Exception

Exception handling in C++ is done using three


keywords: try, catch and throw.
To catch exceptions, a portion of code is placed under exception
inspection. This is done by enclosing this portion of code in a try block.
When an exception occurs within the try block, control is transferred to
the exception handler. If no exception is thrown, the code continues
normally and the handlers are ignored.
An exception in C++ is thrown by using the throw keyword from inside
the try block. The throw keyword allows the programmer to define custom
exceptions.
Exception handlers in C++ are declared with the catch keyword, which is
placed immediately after the try block. Multiple handlers

170
OOPS using C++

(catch expressions) can be chained - each one with a different exception


type. Only the handler whose argument type matches the exception type
in the throw statement is executed.
C++ does not require a finally block to make sure resources are released if
an exception occurs.

C++ Throw Exception Example


The following example shows the syntax for throwing and catching
exceptions in C++:
#include <iostream>
#include <stdexcept>

using namespace std;

int AddPositiveIntegers(int a, int b)


{
if (a < 0 || b < 0)
throw std::invalid_argument("AddPositiveIntegers arguments must
be positive");

return (a + b);
}

int main()
{
try
{
cout << AddPositiveIntegers(-1, 2); //exception
}

catch (std::invalid_argument& e)
{
cerr << e.what() << endl;
return -1;
}

171
OOPS using C++

return 0;
}
In this C++ throw exception example, the AddPositiveIntegers() function
is called from inside the try block in the main() function.
The AddPositiveIntegers() expects two integers a and b as arguments, and
throws an invalid_argument exception in case any of them are negative.
The std::invalid_argument class is defined in the standard library in the
<stdexcept> header file. This class defines types of objects to be thrown
as exceptions and reports errors in C++ that occur because of illegal
argument values.
The catch block in the main() function catches
the invalid_argument exception and handles it.

5.3.5. Catching an Exception.

A C++ exception handler is a catch clause. When an exception is thrown


from statements within a try block, the list of catch clauses that follows
the try block is searched to find a catch clause that can handle the
exception.
A catch clause consists of three parts: the keyword catch, the declaration
of a single type or single object within parentheses (referred to as
an exception declaration), and a set of statements within a compound
statement. If the catch clause is selected to handle an exception, the
compound statement is executed. Let's examine the catch clauses for the
exceptions pushOnFull and popOnEmpty in the function main() in more
detail.
catch ( pushOnFull ) {
cerr << "trying to push a value on a full stack\n";
return errorCode88;
}
catch ( popOnEmpty ) {
cerr << "trying to pop a value on an empty stack\n";

172
OOPS using C++

return errorCode89;
}
Both catch clauses have an exception declaration of class type; the first
one is of type pushOnFull, and the second one is of type popOnEmpty. A
handler is selected to handle an exception if the type of its exception
declaration matches the type of the exception thrown. (We will see in
Chapter 19 that the types do not have to match exactly: a handler for a base
class can handle exceptions of a class type derived from the type of the
handler's exception declaration.) For example, when the pop() member
function of the class iStack throws a popOnEmpty exception, the second
catch clause is entered. After an error message is issued to cerr, the
function main() returns errorCode89.
If these catch clauses do not contain a return statement, where does the
execution of the program continue? After a catch clause has completed its
work, the execution of the program continues at the statement that follows
the last catch clause in the list. In our example, the execution of the
program continues with the return statement in main() and, after the catch
clause for popOnEmpty generates an error message to cerr, main() returns
the value 0.
int main() {
iStack stack( 32 );

try {
stack.display();
for ( int ix = 1; ix < 51; ++ix )
{
// same as before
}
}
catch ( pushOnFull ) {
cerr << "trying to push a value on a full stack\n";
}
catch ( popOnEmpty ) {
cerr << "trying to pop a value on an empty stack\n";
}

173
OOPS using C++

// execution of the program continues here


return 0;
}
The C++ exception handling mechanism is said to be nonresumptive;
once the exception has been handled, the execution of the program does
not resume where the exception was originally thrown. In our example,
once the exception has been handled, the execution of the program does
not continue in the pop() member function where the exception was
thrown.

Check your progress1

1. Which among the following best describes polymorphism?


a) It is the ability for a message/data to be processed in more than one form
b) It is the ability for a message/data to be processed in only 1 form
c) It is the ability for many messages/data to be processed in one way
d) It is the ability for undefined message/data to be processed in at least
one way

2. What do you call the languages that support classes but not
polymorphism?
a) Class based language
b) Procedure Oriented language
c) Object-based language
d) If classes are supported, polymorphism will always be supported

3. Which among the following is the language which supports classes but
not polymorphism?
a) SmallTalk
b) Java
c) C++
d) Ada

174
OOPS using C++

4. If same message is passed to objects of several different classes and all


of those can respond in a different way, what is this feature called?
a) Inheritance
b) Overloading
c) Polymorphism
d) Overriding

5. Which class/set of classes can illustrate polymorphism in the following


code?
abstract class student
{
public : int marks;
calc_grade();
}
class topper:public student
{
public : calc_grade()
{
return 10;
}
};
class average:public student
{
public : calc_grade()
{
return 20;
}
};
class failed{ int marks; };
a) Only class student can show polymorphism
b) Only class student and topper together can show polymorphism
c) All class student, topper and average together can show polymorphism
d) Class failed should also inherit class student for this code to work for
polymorphism

175
OOPS using C++

5.4. LET US SUM UP

• The overloaded member functions are considered for invoking by


matching arguments, both type and number. The compiler knows
this information at the compile time and, therefore, compiler is able
to select the appropriate function for a particular function call at
the compile time itself. It means that an object is bound to its
function call at compile time.
• In run time polymorphism, an appropriate member function is
invoked when executing the program. It is called late or dynamic
binding because the appropriate function is selected dynamically
at run time. C++ supports run time polymorphism with the help of
virtual functions. Dynamic binding requires use of pointers to
objects and is one of the powerful features of C++

5.5. KEY WORDS

• well-defined interface. See also: access control, abstract class,


separate compilation. TC++PL 2.4.

• inheritance - a derived class is said to inherit the members of


its base classes. TC++PL 2.6.2, 12.2, 23.4.3.1, D&E 3.5, 7.2,
12.

176
OOPS using C++

• initialization - giving an object an initial value. Initialization


differs from assignment in that there is no previous value
involved. Initialization is done by constructors.

• initializer list - comma-separated list of expressions enclosed


in curly braces, e.g. { 1, 2, 3 } used to initialize a struct or an
array. TC++PL 5.2.1, 5.7, 11.3.3.

• inline function - function declared inline using the inline


keyword or by being a member function defined in-class.
Compilers are encouraged to generate inline code rather than
function calls for inline functions. Most benefits from inlining
comes with very short functions. TC++PL 7.1.1, 9.2, 10.2.9,
D&E 2.4.1 .

• inlining - see inline function.

• input - see iostream.

• inserter - (1) an iostream << (put to) function. (2) an STL


operation yielding an iterator to be used for adding elements to
a containter. TC++PL 19.2.4, 21.2, D&E 8.3.1. See also:
extracter, back_inserter, front_inserter.

5.6. SOME USEFUL BOOKS

• Balagurusamy E (2008) Object oriented Programming With C++


.Tata Mc Graw-Hill Publishing Company : New Delhi
• Sourav Sahay (2012) Object Oriented Programming with
C++ .Oxford University: Press India
• Rajesh K. Shukla (2008) Object- Oriented Programming In
C++, Wiley Private Limited India
177
OOPS using C++

• Dr. A. K. Saini (2012) C++ and Object Oriented


Programming, Gullybaba Publishing House (P) Ltd
• Sarang Poornachandra (2009) Object - Oriented Programming
with C++, PHI Learning

5.7. ANSWER TO CHECK YOUR PROGRESS

Answer: a
Explanation: It is actually the ability for a message / data to be processed
in more than one form. The word polymorphism indicates many-forms. So
if a single entity takes more than one form, it is known as polymorphism.
Answer: c
Explanation: The languages which support classes but doesn’t support
polymorphism, are known as object-based languages. Polymorphism is
such an important feature, that is a language doesn’t support this feature,
it can’t be called as a OOP language.
Answer: d
Explanation: Ada is the language which supports the concept of classes
but doesn’t support the polymorphism feature. It is an object-based
programming language. Note that it’s not an OOP language.
Answer: c
Explanation: The feature defined in question defines polymorphism
features. Here the different objects are capable of responding to the same
message in different ways, hence polymorphism.
Answer: c
Explanation: Since Student class is abstract class and class topper and
average are inheriting student, class topper and average must define the
function named calc_grade(); in abstract class. Since both the definition
are different in those classes, calc_grade() will work in different way for
same input from different objects. Hence it shows polymorphism

178
OOPS using C++

5.8. TERMINAL QUESTIONS

1. What is an exception in C++ program? ...


2. By default, what a program does when it detects an exception? ...
3. Why do we need to handle exceptions? ...
4. How Exception handling is implemented in the C++ program? ...
5. What is the correct syntax of the try-catch block?
6. Explain pointers to objects with example.
7. Explain 'this' pointer with example.
8. Explain pointer to derived class.
9. Explain virtual function with example.
10. Explain Run time polymorphism with example.

179

You might also like