0% found this document useful (0 votes)
102 views32 pages

Polymorphism in C++

Polymorphism in C++ allows objects to take on multiple forms via method overriding. Function overriding occurs when a derived class redefines a function from its base class, changing the function's definition while keeping the same declaration. For overriding to work, the classes must be related via inheritance and the overriding function must have an identical declaration in the base and derived classes.

Uploaded by

bhandi sujata
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)
102 views32 pages

Polymorphism in C++

Polymorphism in C++ allows objects to take on multiple forms via method overriding. Function overriding occurs when a derived class redefines a function from its base class, changing the function's definition while keeping the same declaration. For overriding to work, the classes must be related via inheritance and the overriding function must have an identical declaration in the base and derived classes.

Uploaded by

bhandi sujata
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/ 32

C++ TUTORIALS

Polymorphism in C++
Polymorphism means having multiple forms of one thing. In inheritance, polymorphism is
done, by method overriding, when both super and sub class have member function with
same declaration bu different definition.

Function Overriding in C++


If we inherit a class into the derived class and provide a definition for one of the base
class's function again inside the derived class, then that function is said to
be overridden, and this mechanism is called Function Overriding

Requirements for Overriding a Function


1. Inheritance should be there. Function overriding cannot be done within a class. For
this we require a derived class and a base class.
2. Function that is redefined must have exactly the same declaration in both base and
derived class, that means same name, same return type and same parameter list.

Example of Function Overriding in C++


class Base
{
public:
void show()
{
cout << "Base class";
}
};

class Derived:public Base


{
public:
void show()
{
cout << "Derived Class";
}
}

In this example, function show() is overridden in the derived class. Now let us study how
these overridden functions are called in main() function.

Function Call Binding with class Objects


Connecting the function call to the function body is called Binding. When it is done
before the program is run, its called Early Binding or Static Binding or Compile-
time Binding.
class Base
{
public:
void shaow()
{
cout << "Base class\n";
}
};

class Derived:public Base


{
public:
void show()
{
cout << "Derived Class\n";
}
}
int main()
{
Base b; //Base class object
Derived d; //Derived class object
b.show(); //Early Binding Ocuurs
d.show();
}

Base class

Derived class

In the above example, we are calling the overrided function using Base class and
Derived class object. Base class object will call base version of the function and derived
class's object will call the derived version of the function.

Function Call Binding using Base class Pointer


But when we use a Base class's pointer or reference to hold Derived class's object, then
Function call Binding gives some unexpected results.
class Base
{
public:
void show()
{
cout << "Base class\n";
}
};

class Derived:public Base


{
public:
void show()
{
cout << "Derived Class\n";
}
}
int main()
{
Base* b; //Base class pointer
Derived d; //Derived class object
b = &d;
b->show(); //Early Binding Occurs
}

Base class

In the above example, although, the object is of Derived class, still Base class's method
is called. This happens due to Early Binding.

Compiler on seeing Base class's pointer, set call to Base class's show() function,
without knowing the actual object type.

Virtual Functions in C++


Virtual Function is a function in base class, which is overrided in the derived class, and
which tells the compiler to perform Late Binding on this function.

Virtual Keyword is used to make a member function of the base class Virtual.

Late Binding in C++


In Late Binding function call is resolved at runtime. Hence, now compiler determines the
type of object at runtime, and then binds the function call. Late Binding is also
called Dynamic Binding or RuntimeBinding.
Problem without Virtual Keyword
Let's try to understand what is the issue that virtual keyword fixes,

class Base

public:

void show()

cout << "Base class";

};

class Derived:public Base

public:

void show()

cout << "Derived Class";

int main()

Base* b; //Base class pointer

Derived d; //Derived class object

b = &d;
b->show(); //Early Binding Ocuurs

Base class

When we use Base class's pointer to hold Derived class's object, base class pointer or
reference will always call the base version of the function

Using Virtual Keyword in C++


We can make base class's methods virtual by using virtual keyword while declaring
them. Virtual keyword will lead to Late Binding of that method.

class Base

public:

virtual void show()

cout << "Base class\n";

};

class Derived:public Base

public:

void show()

cout << "Derived Class";


}

int main()

Base* b; //Base class pointer

Derived d; //Derived class object

b = &d;

b->show(); //Late Binding Ocuurs

Derived class

On using Virtual keyword with Base class's function, Late Binding takes place and the
derived version of function will be called, because base class pointer pointes to Derived
class object.

Using Virtual Keyword and Accessing Private Method


of Derived class
We can call private function of derived class from the base class pointer with the help of
virtual keyword. Compiler checks for access specifier only at compile time. So at run
time when late binding occurs it does not check whether we are calling the private
function or public function.

#include <iostream>

using namespace std;

class A
{

public:

virtual void show()

cout << "Base class\n";

};

class B: public A

private:

virtual void show()

cout << "Derived class\n";

};

int main()

A *a;

B b;

a = &b;

a->show();

}
Derived class

Mechanism of Late Binding in C++

To accomplich late binding, Compiler creates VTABLEs, for each class with virtual
function. The address of virtual functions is inserted into these tables. Whenever an
object of such class is created the compiler secretly inserts a pointer called vpointer,
pointing to VTABLE for that object. Hence when function is called, compiler is able to
resovle the call by binding the correct function using the vpointer.

Important Points to Remember

3. Only the Base class Method's declaration needs the Virtual Keyword, not the
definition.
4. If a function is declared as virtual in the base class, it will be virtual in all its derived
classes.
5. The address of the virtual Function is placed in the VTABLE and the copiler
uses VPTR(vpointer) to point to the Virtual Function.

C++ TUTORIALS

Abstract Class and Pure Virtual


Function in C++
Abstract Class is a class which contains atleast one Pure Virtual function in it. Abstract
classes are used to provide an Interface for its sub classes. Classes inheriting an
Abstract Class must provide definition to the pure virtual function, otherwise they will
also become abstract class.

Characteristics of Abstract Class


6. Abstract class cannot be instantiated, but pointers and refrences of Abstract class
type can be created.
7. Abstract class can have normal functions and variables along with a pure virtual
function.
8. Abstract classes are mainly used for Upcasting, so that its derived classes can use
its interface.
9. Classes inheriting an Abstract Class must implement all pure virtual functions, or
else they will become Abstract too.
Pure Virtual Functions in C++
Pure virtual Functions are virtual functions with no definition. They start
with virtual keyword and ends with = 0. Here is the syntax for a pure virtual function,

virtual void f() = 0;

Example of Abstract Class in C++


Below we have a simple example where we have defined an abstract class,

//Abstract base class

class Base

public:

virtual void show() = 0; // Pure Virtual Function

};

class Derived:public Base

public:

void show()

cout << "Implementation of Virtual Function in Derived


class\n";

};
int main()

Base obj; //Compile Time Error

Base *b;

Derived d;

b = &d;

b->show();

Implementation of Virtual Function in Derived class

In the above example Base class is abstract, with pure virtual show() function, hence we
cannot create object of base class.

Why can't we create Object of an Abstract Class?


When we create a pure virtual function in Abstract class, we reserve a slot for a function
in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the
VTABLE will be incomplete.

As the VTABLE for Abstract class is incomplete, hence the compiler will not let the
creation of object for such class and will display an errror message whenever you try to
do so.

Pure Virtual definitions


• Pure Virtual functions can be given a small definition in the Abstract class, which you
want all the derived classes to have. Still you cannot create object of Abstract class.
• Also, the Pure Virtual function must be defined outside the class definition. If you will
define it inside the class definition, complier will give an error. Inline pure virtual
definition is Illegal.

// Abstract base class

class Base

public:

virtual void show() = 0; //Pure Virtual Function

};

void Base :: show() //Pure Virtual definition

cout << "Pure Virtual definition\n";

class Derived:public Base

public:

void show()

cout << "Implementation of Virtual Function in Derived


class\n";

};
int main()

Base *b;

Derived d;

b = &d;

b->show();

Implementation of Virtual Function in Derived class

1. ← Prev

2. Next →

C++ TUTORIALS

Virtual Destructors in C++


Destructors in the Base class can be Virtual. Whenever Upcasting is done, Destructors
of the Base class must be made virtual for proper destrucstion of the object when the
program exits.

NOTE: Constructors are never Virtual, only Destructors can be Virtual.


Upcasting without Virtual Destructor in C++
Lets first see what happens when we do not have a virtual Base class destructor.
class Base
{
public:
~Base()
{
cout << "Base Destructor\n";
}
};

class Derived:public Base


{
public:
~Derived()
{
cout<< "Derived Destructor\n";
}
};

int main()
{
Base* b = new Derived; // Upcasting
delete b;
}

Base Destructor

In the above example, delete b will only call the Base class destructor, which is
undesirable because, then the object of Derived class remains undestructed, because
its destructor is never called. Which results in memory leak.
Upcasting with Virtual Destructor in C++
Now lets see. what happens when we have Virtual destructor in the base class.
class Base
{
public:
virtual ~Base()
{
cout << "Base Destructor\n";
}
};

class Derived:public Base


{
public:
~Derived()
{
cout<< "Derived Destructor";
}
};

int main()
{
Base* b = new Derived; // Upcasting
delete b;
}

Derived Destructor

Base Destructor

When we have Virtual destructor inside the base class, then first Derived class's
destructor is called and then Base class's destructor is called, which is the desired
behaviour.
Pure Virtual Destructors in C++
10. Pure Virtual Destructors are legal in C++. Also, pure virtual Destructors must be
defined, which is against the pure virtual behaviour.
11. The only difference between Virtual and Pure Virtual Destructor is, that pure virtual
destructor will make its Base class Abstract, hence you cannot create object of that
class.
12. There is no requirement of implementing pure virtual destructors in the derived
classes.

class Base
{
public:
virtual ~Base() = 0; // Pure Virtual Destructor
};

// Definition of Pure Virtual Destructor


Base::~Base()
{
cout << "Base Destructor\n";
}

class Derived:public Base


{
public:
~Derived()
{
cout<< "Derived Destructor";
}
};

• ← Prev
• Next →

C++ TUTORIALS

• Operator Overloading
• Operator Overloading
• Operator Overloading Examples

Operator Overloading in C++


Operator overloading is an important concept in C++. It is a type of polymorphism in
which an operator is overloaded to give user defined meaning to it. Overloaded operator
is used to perform operation on user-defined data type. For example '+' operator can be
overloaded to perform addition on various data types, like for Integer,
String(concatenation) etc.

Almost any operator can be overloaded in C++. However there are few operator which
can not be overloaded. Operator that are not overloaded are follows

13. scope operator - ::


14. sizeof
15. member selector - .
16. member pointer selector - *
17. ternary operator - ?:
Operator Overloading Syntax

Implementing Operator Overloading in C++


Operator overloading can be done by implementing a function which can be :

• Member Function
• Non-Member Function
• Friend Function

Operator overloading function can be a member function if the Left operand is an Object
of that class, but if the Left operand is different, then Operator overloading function must
be a non-member function.

Operator overloading function can be made friend function if it needs access to the
private and protected members of class.

Restrictions on Operator Overloading in C++


Following are some restrictions to be kept in mind while implementing operator
overloading.

3. Precedence and Associativity of an operator cannot be changed.


4. Arity (numbers of Operands) cannot be changed. Unary operator remains unary,
binary remains binary etc.
5. No new operators can be created, only existing operators can be overloaded.
6. Cannot redefine the meaning of a procedure. You cannot change how integers are
added.

1. ← Prev
2. Next →
C++ TUTORIALS

Available on:

• Overview of C++
• Introduction to C++
• OOPS concepts basic
• Basic Syntax and Structure
• Data types and Modifiers
• Variables in C++
• Operators in C++
• sizeof and typedef in C++
• Decision Making
• Loop types
• Storage Classes
• Functions

• Core C++ Concepts


• Classes and Objects
• Access Controls in classes
• Defining class and object
• Accessing Data Members
• Member Functions in class
• Types of Member Functions
• Inline Functions
• Function Overloading
• Constructor and Destructor
• Static Keyword
• Const Keyword
• Refrences
• Copy Constructor
• Pointer to Members

• Inheritance
• Introduction to Inheritance
• Types of Inheritance
• Order of Constructor Call
• Upcasting

• Polymorphism
• Function Overriding
• Virtual Functions
• Abstract class and Pure Virtual Functions
• Virtual Destructors

• Operator Overloading
• Operator Overloading
• Operator Overloading Examples

• C++ Miscellaneous
• File Streams
• Exception Handling
• Memory Management
• Multithreading
• Initializer List
• Defining Namespace

• STL in C++ →

• C++ Programs →

Operator Overloading Examples in


C++
Almost all the operators can be overloaded in infinite different ways. Following are some
examples to learn more about operator overloading. All the examples are closely
connected.

Overloading Arithmetic Operator in C++


Arithmetic operator are most commonly used operator in C++. Almost all arithmetic
operator can be overloaded to perform arithmetic operation on user-defined data type. In
the below example we have overridden the + operator, to add to Time(hh:mm:ss)
objects.

Example: overloading +Operator to add two Time class


object
#include <iostream.h>

#include <conio.h>

class Time

{
int h,m,s;

public:

Time()

h=0, m=0; s=0;

void setTime();

void show()

cout<< h<< ":"<< m<< ":"<< s;

//overloading '+' operator

Time operator+(time);

};

Time Time::operator+(Time t1) //operator function

Time t;

int a,b;

a = s+t1.s;

t.s = a%60;

b = (a/60)+m+t1.m;

t.m = b%60;

t.h = (b/60)+h+t1.h;
t.h = t.h%12;

return t;

void time::setTime()

cout << "\n Enter the hour(0-11) ";

cin >> h;

cout << "\n Enter the minute(0-59) ";

cin >> m;

cout << "\n Enter the second(0-59) ";

cin >> s;

void main()

Time t1,t2,t3;

cout << "\n Enter the first time ";

t1.setTime();

cout << "\n Enter the second time ";

t2.setTime();

t3 = t1 + t2; //adding of two time object using '+' operator

cout << "\n First time ";

t1.show();
cout << "\n Second time ";

t2.show();

cout << "\n Sum of times ";

t3.show();

getch();

While normal addition of two numbers return the sumation result. In the case above we
have overloaded the + operator, to perform addition of two Time class objects. We add
the seconds, minutes and hour values separately to return the new value of time.

In the setTime() funtion we are separately asking the user to enter the values for hour,
minute and second, and then we are setting those values to the Time class object.

For inputs, t1 as 01:20:30(1 hour, 20 minute, 30 seconds) and t2 as 02:15:25(2 hour,


15 minute, 25 seconds), the output for the above program will be:

1:20:30

2:15:25

3:35:55

First two are values of t1 and t2 and the third is the result of their addition.

Overloading I/O operator in C++


The first question before learning how to override the I/O operator should be, why we
need to override the I/O operators. Following are a few cases, where overloading the I/O
operator proves useful:

18. We can overload output operator << to print values for user defined datatypes.
19. We can overload output operator >> to input values for user defined datatypes.

In case of input/output operator overloading, left operand will be of


types ostream& and istream&
Also, when overloading these operators, we must make sure that the functions must be
a Non-Member function because left operand is not an object of the class.

And it must be a friend function to access private data members.

You have seen above that << operator is overloaded with ostream class object cout to
print primitive datatype values to the screen, which is the default behavious
of << operator, when used with cout. In other words, it is already overloaded by default.

Similarly we can overload << operator in our class to print user-defined datatypes to
screen. For example we can overload << in our Time class to display the value
of Time object using cout rather than writing a custom member function like show()to
print the value of Time class objects.

Time t1(3,15,48);

// like this, directly

cout << t1;

In the next section we will learn how to do that.

NOTE: When the operator does not modify its operands, the best way to overload the
operator is via friend function.

Example: overloading <<Operator to print Class Object


We will now overload the << operator in the Timeclass,

#include<iostream.h>

#include<conio.h>

class Time

int hr, min, sec;

public:

// default constructor

Time()
{

hr=0, min=0; sec=0;

// overloaded constructor

Time(int h, int m, int s)

hr=h, min=m; sec=s;

// overloading '<<' operator

friend ostream& operator << (ostream &out, Time &tm);

};

// define the overloaded function

ostream& operator << (ostream &out, Time &tm)

out << "Time is: " << tm.hr << " hour : " << tm.min << " min : "
<< tm.sec << " sec";

return out;

void main()

Time tm(3,15,45);
cout << tm;

Time is: 3 hour : 15 min : 45 sec

This is simplied in languages like Core Java, where all you need to do in a class is
override the toString() method of the String class, and you can define how to print
the object of that class.

Overloading Relational Operator in C++


You can also overload relational operators like == , != , >= , <= etc. to compare two
object of any class.

Let's take a quick example by overloading the ==operator in the Time class to directly
compare two objects of Time class.

class Time

int hr, min, sec;

public:

// default constructor

Time()

hr=0, min=0; sec=0;

// overloaded constructor

Time(int h, int m, int s)

{
hr=h, min=m; sec=s;

//overloading '==' operator

friend bool operator==(Time &t1, Time &t2);

};

/*

Defining the overloading operator function

Here we are simply comparing the hour, minute and

second values of two different Time objects to compare

their values

*/

bool operator== (Time &t1, Time &t2)

return ( t1.hr == t2.hr && t1.min == t2.min && t1.sec == t2.sec


);

void main()

Time t1(3,15,45);

Time t2(4,15,45);

if(t1 == t2)

{
cout << "Both the time values are equal";

else

cout << "Both the time values are not equal";

Both the time values are not equal

As the hour value of object t1 is 3 and for object t2 it is 4, hence they are not equal.

Copy Constructor vs. Assignment Operator


(=)
Assignment operator is used to copy the values from one object to another already
existing object. For example:

Time tm(3,15,45); // tm object created and initialized

Time t1; // t1 object created

t1 = tm; // initializing t1 using tm

Whereas, Copy constructor is a special constructor that initializes a new object from
an existing object.

Time tm(3,15,45); // tm object created and initialized

Time t1(tm); //t1 object created and initialized using tm object

In case of Copy constructor, we provide the object to be copied as an argument to the


constructor. Also, we first need to define a copy constructor in our class. We have
covered Copey constructor in detail here: Copy Constructor in C++
• ← Prev

• Next →

You might also like