0% found this document useful (0 votes)
12 views76 pages

Unit 4

The document provides an overview of polymorphism in object-oriented programming, specifically in C++. It explains the two types of polymorphism: compile-time (function and operator overloading) and run-time (method overriding), along with their respective rules and examples. Additionally, it covers type casting, data conversion, and the use of keywords like 'explicit' and 'mutable' in C++.

Uploaded by

rutu.bidarkar
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)
12 views76 pages

Unit 4

The document provides an overview of polymorphism in object-oriented programming, specifically in C++. It explains the two types of polymorphism: compile-time (function and operator overloading) and run-time (method overriding), along with their respective rules and examples. Additionally, it covers type casting, data conversion, and the use of keywords like 'explicit' and 'mutable' in C++.

Uploaded by

rutu.bidarkar
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/ 76

Object Oriented Programming

Unit 4
Polymorphism
Introduction
• The word poly means many, and morphism means several forms. Both the
words are derived from Greek language.
• Thus, by combining these two words, a new whole word called polymorphism
is created, which means various forms.
• In C++, the function can be bound at either compile time or run time.
Deciding a function call at compile time is called compile time or early or static
binding.
• Deciding a function call at run time is called run time or late or dynamic
binding.
• Dynamic binding permits to suspend the decision of choosing a suitable
member function until run time.

2
Introduction
• Polymorphism is the ability to use an operator or method in different ways.
Polymorphism gives different meanings or functions to the operators or
methods.

Or

• Polymorphism is a concept in which an object can be treated in different ways.


• It means that objects of a class can be used as objects of their derived classes.

3
Types of Polymorphism
Compile time polymorphism: The overloaded functions are invoked by matching the type and
number of arguments. This information is available at the compile time and, therefore, compiler
selects the appropriate function at the compile time. It is achieved by function overloading and
operator overloading

Run time polymorphism: Run time polymorphism is achieved when the object's method is
invoked at the run time instead of compile time. It is achieved by method overriding which is also
known as dynamic binding or late binding.

4
1. Compile-Time Polymorphism
A. Function Overloading
• When there are multiple functions with the same name but different parameters,
then the functions are said to be overloaded, hence this is known as Function
Overloading.
• Functions can be overloaded by changing the number of
arguments or/and changing the type of arguments.
• In simple terms, it is a feature of object-oriented programming providing many
functions that have the same name but distinct parameters when numerous tasks
are listed under one function name.

5
6
7
Below is the C++ program to show function overloading or compile-time polymorphism:

8
1. Compile-Time Polymorphism
B. Operator Overloading
• C++ has the ability to provide the operators with a special meaning for a data
type, this ability is known as operator overloading.
• For example, we can make use of the addition operator (+) for string class to
concatenate two strings.
• We know that the task of this operator is to add two operands. So a single
operator ‘+’, when placed between integer operands, adds them and when
placed between string operands, concatenates them.

9
Continue..
• 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:
• Scope operator (::)
• Sizeof
• member selector(.)
• member pointer selector(*)
• ternary operator(?:)
10
Continue..
• Syntax of Operator Overloading

➢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.

11
Rules for Operator Overloading
• Existing operators can only be overloaded, but the new operators cannot be
overloaded.
• The overloaded operator contains at least one operand of the user-defined data type.
• We cannot use friend function to overload certain operators. However, the member
function can be used to overload those operators.
• 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.
• 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.

12
Continue..

13
14
15
Fundamentals of Operator Overloading:
• C++ allows you to specify more than one definition for a function name or an operator in the same scope, which is
called function overloading and operator overloading respectively.
• C++ provides a special function to change the current functionality of some operators within its class which is often
called as operator overloading. Operator Overloading is the method by which we can change the function of some
specific operators to do some different task.
This can be done by declaring the function, its syntax is,

Return_Type classname :: operator op(Argument list) { Function Body }

• Suppose we have created three objects c1, c2 and result from a class named Complex that represents complex numbers.
• Since operator overloading allows us to change how operators work, we can redefine how the + operator works and use
it to add the complex numbers of c1 and c2 by writing the following code:

result = c1 + c2;instead of something like


result = c1.addNumbers(c2);

16
Syntax for C++ Operator Overloading
To overload an operator, we use a special operator function. We define the function inside the class or structure whose
objects/variables we want the overloaded operator to work with.

class className {
... .. ...
public
returnType operator symbol (arguments) {
... .. ...
}
... .. ...
};

Here,
• returnType is the return type of the function.
• operator is a keyword.
• symbol is the operator we want to overload. Like: +, <, -, ++, etc.
• arguments is the arguments passed to the function.
Operator Overloading in Unary Operators :
• Unary operators operate on only one operand. The increment operator ++ and decrement operator -- are examples of unary
operators.
• In unary operator function, no arguments should be passed. It works only with one class objects. It is a overloading of an
operator operating on a single operand.
• Example:
Assume that class Distance takes two member object i.e. feet and inches, create a function by which Distance object should
decrement the value of feet and inches by 1 (having single operand of Distance Type).
// Overloading(-) operator to perform decrement
// C++ program to show unary operator overloading // operation of Distance object
#include <iostream> void operator-()
{
using namespace std; feet--;
inch--;
class Distance { cout << "\nFeet & Inches(Decrement): " <<
public: feet << "'" << inch;
}
// Member Object };
int feet, inch;
// Driver Code
// Constructor to initialize the object's value int main()
Distance(int f, int i) {
{ // Declare and Initialize the constructor
this->feet = f; Distance d1(8, 9);
this->inch = i;
} // Use (-) unary operator by single operand
-d1;
return 0;
}
Output:
Feet & Inches(Decrement): 7'8

• In the above program, it shows that no argument is passed and no return_type value is returned, because unary operator
works on a single operand. (-) operator change the functionality to its member function.
• Note: d2 = -d1 will not work, because operator-() does not return any value.

Overloading Binary Operator: In binary operator overloading function, there should be one argument to be passed. It is
overloading of an operator operating on two operands.
Binary operators work on two operands. For example,
result = num + 9;
• Here, + is a binary operator that works on the operands num and 9.

• When we overload the binary operator for user-defined types by using the code:

obj3 = obj1 + obj2;


• The operator function is called using the obj1 object and obj2 is passed as an argument to the function.
// C++ program to overload the binary operator + // Overload the + operator
// This program adds two complex numbers Complex operator + (const Complex& obj) {
Complex temp;
#include <iostream> temp.real = real + obj.real;
using namespace std; temp.imag = imag + obj.imag;
return temp;
class Complex { }
private:
float real; void output() {
float imag; if (imag < 0)
cout << "Output Complex number: " << real << imag <<
public: "i";
// Constructor to initialize real and imag to 0 else
Complex() : real(0), imag(0) {} cout << "Output Complex number: " << real << "+" <<
imag << "i";
void input() { }
cout << "Enter real and imaginary parts };
respectively: ";
cin >> real;
cin >> imag;
}
int main() {
Complex complex1, complex2, result;
Output
cout << "Enter first complex number:\n";
complex1.input(); Enter first complex number:
Enter real and imaginary parts respectively: 9 5
cout << "Enter second complex number:\n"; Enter second complex number:
complex2.input(); Enter real and imaginary parts respectively: 7 6
Output Complex number: 16+11i
// complex1 calls the operator function In this program, the operator function is:
// complex2 is passed as an argument to the function
result = complex1 + complex2;
result.output();

return 0;
}
Complex operator + (const Complex& obj) {
// code
}
Instead of this, we also could have written this function like:

Complex operator + (Complex obj) {


// code
}

However,
• using & makes our code efficient by referencing the complex2 object instead of making a duplicate object inside the
operator function.
• using const is considered a good practice because it prevents the operator function from modifying complex2.
Things to Remember in C++ Operator Overloading
• Two operators = and & are already overloaded by default in C++. For example, to copy objects of the same class, we
can directly use the = operator. We do not need to create an operator function.
• Operator overloading cannot change the precedence and associativity of operators. However, if we want to change the
order of evaluation, parentheses should be used.
• There are 4 operators that cannot be overloaded in C++. They are:
✓ :: (scope resolution)
✓ . (member selection)
✓ .* (member selection through pointer to function)
✓ ?: (ternary operator)

Overloading Binary Operator using a Friend function:


• In this approach, the operator overloading function must precede with friend keyword, and declare a function class
scope. Keeping in mind, friend operator function takes two parameters in a binary operator, varies one parameter in a
unary operator. All the working and implementation would same as binary operator function except this function will be
implemented outside of the class scope.
• Let’s take the same example using the friend function.
// C++ program to show binary operator overloading
// Constructor to initialize the object's value
#include <iostream>
// Parameterized Constructor
Distance(int f, int i)
using namespace std;
{
this->feet = f;
class Distance {
this->inch = i;
public:
}
// Member Object
// Declaring friend function using friend keyword
int feet, inch;
friend Distance operator+(Distance&, Distance&);
};
// No Parameter Constructor
Distance()
{
this->feet = 0;
this->inch = 0;
}
Type Casting
• Type casting/Automatic/implicit type conversion:
• Conversion that takes place automatically or implicitly.
• Type casting is nothing but process of conversing a variable from one data type to
another.
• Built-in to built-in:
eg. int a;
float d = 7.2361 ;
a = d;

27
Type Casting(implicit and explicit)
• Implicit type conversion or automatic type conversion is done by type compiler on its
own. There is no external trigger required by the user to type cast a variable from one
type to another.

• //Implicit Type casting


Int a=10;
Double b=3.14;
Double a2=a;
Cout<<“a2”<<a2;
Int b2=b;
Cout<<“b2”<<b2;
• OUTPUT
10
3
28
Type Casting(implicit and explicit)
• Explicit Type casting is done by explicitly defining the required type in front of the
expression in parenthesis. This can be also considered as forceful casting.

• // Explicit Type casting


Int a=10;
Double b=3.14;
Double a2=(double)a;
Cout<<“a2”<<a2;
Int b2= (double)b;
Cout<<“b2”<<b2;

• OUTPUT
10
3
29
Data Conversion

30
Example:

31
Data Conversion
• A user-defined data types are designed by the user to suit their requirements, the
compiler does not support automatic type conversions for such data types therefore, the
user needs to design the conversion routines by themselves if required.

• There can be 3 types of situations that may come in the data conversion between
incompatible data types:
1. Basic to user-defined; • Through Constructors that take a argument of the type to be
converted.
2. User-defined to Basic; • Overloaded casting operator which uses a general syntax as
operator type-name() { }
3. One class to another class type. Constructor or Conversion function

32
1. Conversion from built-in type to class type:

• The constructors can be used for default type conversion from argument’s type to the
constructor’s class type.

33
Continue..

34
output

35
Continue..

36
output

37
2. Conversion from class type to built-in type :
• C++ allows to define a overloaded casting operator.
• It is also called as conversion function., that could be used to convert a class type data to basic type.
• The general form of an overloaded casting operator function is :

Operator typename ()
{
}

Eg:

Operator int ()
{
}

The conversion function must satisfy the following conditions:


1. It must be a class member.
2. 2. It must not specify a return value.
3. It must not have any arguments.
38
Continue..

Output:

39
Example:

Output:

40
3. Conversion from one class type to another class type:
• Such conversions can be carried out by constructor or conversion function.

41
Example:

Output:

42
43
Pitfalls of Op Overloading and Conversion
• Code can be innovative and readable but it may also be hard to
understand.

• Similar meaning and syntax should be given to the overloaded operators


else it makes difficult to understand the functionality.

• Ambiguity should be avoided.

• Remember that all operators cannot be overloaded

44
Keyword explicit
• The explicit keyword is related to type conversions and constructors.

• Sometimes type conversion is unwanted. To prevent such type


conversion we can define the constructor with keyword explicit.

• The constructor is defined with keyword ‘explicit’.

45
Keyword explicit

Output:
Value=3

46
Keyword explicit

Output:
Error

47
Keyword mutable
• The keyword is used for declaring data members of a class.
• If a member function of class is declared/defined as ‘const’ function, it
cant modify any data members of the class.
• But, sometimes it is expected that some of data members should be
permitted to modify through const function.
• These data members which can be modified through const functions are
declared with keyword ‘mutable’.
• Mutable data members can not be ‘static’ or reference variable.

48
Example

Output: a=30 b=40

49
Continue..

Output:
ERROR

50
Run Time Polymorphism

51
Pointers to Base class
• A pointer is a type of variable or a memory location that contain the address of
other variables or object.
• In Object Oriented Programming language the base class is defined as a class
whose data members and functionality can be inherited by other classes.
• On the other hands a derived class is defined as a class that inherits all the
properties from an existing or base class.
• We will use the pointer to access the data member and the member function of
the base class as well as the derived class.

52
Example:
class Base {
public: //Display function to print the derived and
int base_data_member; //base class members.

//Display function to print the base class void show()


members.
{
void show() cout << "Derived Class:" << endl
{ << "Data members of Derived Class: "
cout << "Base Class:" << endl << << derived_data_member << endl;
<< "Data members of Base Class: " cout << "Base Class:" << endl
<< base_data_member << endl; << "Data members of Base Class: "
} << base_data_member << endl;
}; class Derived : public Base { }
public: };
int derived_data_member; 53
Example:
Create a pointer to the base class and bPointer->show(); //callling to the base
access the member function of that base class member function
class:
Base* bPointer;
Base bObject; //Creating a object of the • Output:
Base class
• Base Class: Data member of Base
Class: 100
bPointer = &bObject; //pointing to the
base class object

bPointer->base_data_member = 100;

54
Example:
Create a pointer to the derived class to dPointer->show();
access the data members and member
function of the derived class and the
base class:
Derived* dPointer; • Output:
Derived dObject; //Creating a object of • Derived class: Data member of
the Derived class Derived Class: 99 Base Class: Data
member of Base Class: 1

dPointer = &dObject;

dPointer->derived_data_member = 99;
dPointer->base_data_member = 1;

55
Virtual function and its significance
• Virtual function is a member function that is declared within the base
class and can be redefined by the derived class.
• A virtual function is a member function which is declared within a base
class and is re-defined(Overridden) by a derived class. When you refer
to a derived class object using a pointer or a reference to the base class,
you can call a virtual function for that object and execute the derived
class’s version of the function.

56
Example
#include <iostream> public: }
using namespace std; void show() };
class base { int main()
{ std::cout << "Derived class {
1" << std::endl;
public: base *b;
}
void show() derived1 d1;
};
{ derived2 d2;
class derived2 : public base
std::cout << "Base class" << st b=&d1;
d::endl; {
b->show();
} public:
b=&d2;
}; void show()
b->show();
class derived1 : public base {
return 0;
{ std::cout << "Derived class
}
2" << std::endl;

57
Explanation
• In the above code, we have not used the virtual method. We have created
a base class that contains the show() function. The two classes are also
created named as 'derived1' and 'derived2' that are inheriting the
properties of the base class. Both 'derived1' and 'derived2' classes have
redefined the show() function. Inside the main() method, pointer variable
'b' of class base is declared. The objects of classes derived1 and derived2
are d1 and d2 respectively. Although the 'b' contains the addresses of d1
and d2, but when calling the show() method; it always calls the show()
method of the base class rather than calling the functions of the derived1
and derived2 class.

58
Explanation
• To overcome the above problem, we need to make the method as virtual
in the base class. Here, virtual means that the method exists in
appearance but not in reality. We can make the method as virtual by
simply adding the virtual keyword preceeding to the function. In the
above program, we need to add the virtual keyword that precedes to the
show() function in the base class shown as below:
virtual void show()
{
std::cout << "Base class" << std::endl;
}

59
Example 2
#include <iostream> }
using namespace std; };
class B {
public: int main(void) {
virtual void s() //virtual function { D d; // An object of class D
cout<<" In Base \n"; B *b= &d;// A pointer of type B* pointing to
} d
}; b->s();// prints"D::s() called"
return 0;
class D: public B { }
public:
void s() { Output : In Derived
cout<<"In Derived \n";

60
Pure virtual function and virtual table
• A pure virtual function (or abstract function) in C++ is a virtual function
for which we don’t have an implementation, we only declare it. A pure
virtual function is declared by assigning 0 in the declaration.

• A pure virtual function is a virtual function that has no definition within


the class. Let's understand the concept of pure virtual function through
an example.

• In the above pictorial representation, shape is the base class while


rectangle, square and circle are the derived class. Since we are not
providing any definition to the virtual function, so it will automatically
be converted into a pure virtual function.
61
Continue..
• Similarities between virtual function and pure virtual function
1. These are the concepts of Run-time polymorphism.
2. Prototype i.e. Declaration of both the functions remains the same
throughout the program.
3. These functions can’t be global or static.

62
Continue..
Syntax
• There are two ways of creating a virtual function:

virtual void display() = 0;


or
virtual void display() {}

63
Example 1
#include<iostream> }
using namespace std; };
class B {
public: int main() {
virtual void s() = 0; // Pure Virtual B *b;
Function D dobj; // An object of class D
}; b = &dobj;// A pointer of type B*
pointing to dobj
class D:public B { b->s();// prints"D::s() called"
public: }
void s() { Output
cout << " Virtual Function in Virtual Function in Derived class
Derived class\n";
64
Example 2
#include <iostream> Square(float l)
using namespace std; { Circle(float x)
// Abstract class a = l; {
class Shape } r = x;
{ float calculateArea() }
public: { float calculateArea()
virtual float calculateArea() return a*a; {
= 0; // pure virtual function. } return 3.14*r*r ;
};
}; }
class Square : public Shape class Circle : public Shape };
{ {
float a;
float r;
public: public:

65
Continue..
class Rectangle : public Sha return l*b; int a2 = shape-
pe } >calculateArea();
{ }; shape = &c;
float l; int main() int a3 = shape-
float b; >calculateArea();
{ std::cout << "Area of the
public: square is " <<a1<< std::endl
Rectangle(float x, float y ;
) Shape *shape;
std::cout << "Area of the
{ Square s(3.4); rectangle is " <<a2<< std::e
Rectangle r(5,6); ndl;
l=x;
Circle c(7.8); std::cout << "Area of the
b=y; circle is " <<a3<< std::endl;
} shape =&s;
float calculateArea() int a1 =shape- return 0;
>calculateArea();
{ }
shape = &r;

66
Difference between virtual function and pure virtual function in
C++
Virtual function Pure virtual function

A pure virtual function is a member function of base class


whose only declaration is provided in base class and should
A virtual function is a member function of base class which
be defined in derived class otherwise derived class also
can be redefined by derived class.
becomes abstract.

Classes having virtual functions are not abstract. Base class containing pure virtual function becomes abstract.

Syntax:
Syntax:
virtual<func_type><func_name>()
{ virtual<func_type><func_name>()
// code = 0;
}

Definition is given in base class. No definition is given in base class.

67
Difference between virtual function and pure virtual function in
C++
Virtual function Pure virtual function

Base class having virtual function can be instantiated Base class having pure virtual function becomes
i.e. its object can be made. abstract i.e. it cannot be instantiated.

If derived class do not redefine virtual function of


If derived class do not redefine virtual function of
base class, then no compilation error but derived class
base class, then it does not affect compilation.
also becomes abstract just like the base class.

All derived class must redefine pure virtual function of


All derived class may or may not redefine virtual
base class otherwise derived class also becomes
function of base class.
abstract just like base class.

68
virtual destructor
• When we delete a derived object using base class pointer, then generally
only object is destroyed without destroying the child class object.

69
Example:

70
Output:

71
virtual destructor
• When we define the destructor of Base/Parent class using virtual
keyword, then it is called virtual destructor.

• The virtual destructor ensures that while deleting the child class object
using base class pointer, the child object is destroyed first, then the
parent object is deleted.

72
Example:

73
Output:

74
Abstract base class
• Abstract class is a class which has at least one pure virtual function.
• The object of abstract class can not be created.
• The main objective of abstract class is to provide some traits to the derived
classes and to create a base pointer for achieving runtime polymorphism.

75
Thank You

You might also like