0% found this document useful (0 votes)
98 views135 pages

OOPS IN C++ Notes

Uploaded by

Random Guy
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)
98 views135 pages

OOPS IN C++ Notes

Uploaded by

Random Guy
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/ 135

OOPS IN C++ Notes P age |1

What is Structured Programming


Structured Programming divides a program into a set of functions or modules. Modular programming is
another name for this. These functions have statements embraced inside curly braces. Each of these functions
performs a subtask. Usually, as each function represents a specific functionality, it is easier for the programmer
to test and debug the code, but this can differ depending on the program. C language and Pascal are two
common structured programming languages.

In the structured programming C, the user can create his own user-defined functions. The main function calls
the other functions. It indicates the execution of the program. When there is a function call, the control is
passed to that function. After completing the function, the control passes back to the main program. Moreover,
a variable inside a function is a local variable, and global variables are accessible by all the functions.

What is Object Oriented Programming?


Object oriented programming allows the programmer to represent real-world scenarios using objects. An
object is any entity that has states and behaviours. States represent the attributes or data of an object, whereas
the methods represent the behaviours of objects. Student, Employee, Book etc. are objects. These objects
interact with other objects by passing messages. Furthermore, a class is a blueprint for creating an object. It is
necessary to have a class to create objects. For example, to create an Employee object, there should be an
Employee class.

[email protected] contact 03354900611


OOPS IN C++ Notes P age |2

In addition to classes and objects, there are four major pillars in OOP. They are as follows.

Encapsulation – Binds or combines properties and methods into a single unit


Inheritance – Allows a class to use properties and methods of an already existing class
Polymorphism – Allows an object to perform in multiple ways – Overloading and overriding are two ways of
achieving polymorphism.
Abstraction – Hides the internal details and displays only the functionalities to the user – Moreover, abstract
classes and interfaces help to achieve abstraction.
Overall, object oriented programming makes it easier to develop the program. Furthermore, it provides data
security, maintainability and code reusability.

Difference Between Structured and Object Oriented Programming

Definition
Structured programming is a programming paradigm which divides the code into modules or function, while
OOP is a programming paradigm based on the concept of objects, which contain data in the form of fields
known as attributes, and code in the form of procedures known as methods. Thus, this explains the main
difference between structured and object oriented programming.

Main Focus
Furthermore, structured programming focuses on dividing the program into a set of functions in which each
function works as a subprogram while object oriented programming focuses on representing a program using a
set of objects which encapsulates data and object.

Modification
Moreover, it is difficult to modify the structured programs while it is easier to modify the Object Oriented
programs.

Communication
In structured programming, the main method communicates with the functions by calling those functions in the
main program whereas, in object oriented programming, the objects communicate with each other by passing
messages. Hence, this is an important difference between structured and object oriented programming.

Access Specifiers
There are no access specifiers in structured programming while there are access specifiers such as private,
public and protected in Object Oriented Programming. Thus, this is also an important difference between
structured and object oriented programming.

Security
Besides, data is not secure in structured programming, but it is secure in object oriented programming.

Code Reusability
Also, it is difficult to reuse code in structured programming, whereas it is easier to reuse code in object
oriented programming.

[email protected] contact 03354900611


OOPS IN C++ Notes P age |3

Oops Concept in C++


The main purpose of C++ programming was to add object orientation to the C programming language,
which is in itself one of the most powerful programming languages. If any programming language follow
below oops concept then that language called object oriented programming language.
 Object
 Class
 Encapsulation
 Abstraction
 Inheritance
 Polymorphism

Object
Object is the physical as well as logical entity where as class is the only logical entity.
It is a basic unit of Object-Oriented Programming and represents the real-life entities. A C++ program
creates many objects which interact by invoking methods.
Class
Class: Class is a blue print which is containing only list of variables and method and no memory is
allocated for them. A class is a group of objects that has common properties.
A class is a user-defined blueprint or prototype from which objects are created. It represents the set of
properties or methods that are common to all objects of one type.
Encapsulation
Encapsulation is a process of wrapping of data and methods in a single unit is called encapsulation.
Encapsulation is achieved in C++ language by class concept. The main advantage of using of encapsulation

[email protected] contact 03354900611


OOPS IN C++ Notes P age |4

is to secure the data from other methods, when we make a data private then these data only use within the
class, but these data not accessible outside the class.
Abstraction
Abstraction is the concept of exposing only the required essential characteristics and behavior with respect
to a context.
Hiding of data is known as data abstraction. In object oriented programming language this is
implemented automatically while writing the code in the form of class and object.

Inheritance
The process of obtaining the data members and methods from one class to another class is known
as inheritance. It is one of the fundamental features of object-oriented programming.
Polymorphism
The process of representing one Form in multiple forms is known as Polymorphism. Here one form
represent original form or original method always resides in base class and multiple forms represents
overridden method which resides in derived classes.

Class and Object in C++


Object is the physical as well as logical entity where as class is the only logical entity.
Class: Class is a blue print which is containing only list of variables and method and no memory is
allocated for them. A class is a group of objects that has common properties.

A class in C++ contains, following properties;

 Data Member
 Method
 Constructor
 Block
 Class and Interface
Object: Object is a instance of class, object has state and behaviors.

An Object in C++ has three characteristics:

 State
 Behavior
 Identity

Syntax
class_name object_reference;

Example

Employee e;

State: Represents data (value) of an object.


Behavior: Represents the behavior (functionality) of an object such as deposit, withdraw etc.

[email protected] contact 03354900611


OOPS IN C++ Notes P age |5

Identity: Object identity is typically implemented via a unique ID. The value of the ID is not visible to the
external user. But,it is used internally by the JVM to identify each object uniquely.

Class is also can be used to achieve user defined data types.

In real world many examples of object and class like dog, cat, and cow are belong to animal's class. Each
object has state and behaviors. For example a dog has state:- color, name, height, age as well as behaviors:-
barking, eating, and sleeping.
Vehicle class
Car, bike, truck these all are belongs to vehicle class. These Objects have also different different states and
behaviors. For Example car has state - color, name, model, speed, Mileage. as we;; as behaviors - distance
travel

Difference between Class and Object in C++

Class Object

Class is a container which collection of variables


1 object is a instance of class
and methods.

Sufficient memory space will be allocated for


2 No memory is allocated at the time of declaration all the variables of class at the time of
declaration.

One class definition should exist only once in the


3 For one class multiple objects can be created
program.

Syntax to declare a Class


Syntax
[email protected] contact 03354900611
OOPS IN C++ Notes P age |6

class Class_Name
{
data member;
method;
}

A class can contain any of the following variable types .


 Local variables: Variables defined inside methods, constructors or blocks are called
local variables. The variable will be declared and initialized within the method and the
variable will be destroyed when the method has completed.
 Instance variables: Instance variables are variables within a class but outside any
method. These variables are initialized when the class is instantiated. Instance variables
can be accessed from inside any method, constructor or blocks of that particular class.
 Class variables: Class variables are variables declared with in a class, outside any
method, with the static keyword.
Simple Example of Object and Class
In this example, we have created a Employee class that have two data members eid and ename. We are
creating the object of the Employee class and printing the objects value.
Example

#include<iostream.h>
#include<conio.h>

class Employee
{
public:
int salary // data member
void sal()
{
cout<<"Enter salary: ";
cin>>salary;
cout<<"Salary: "<<salary;
}
};
void main()
{
clrscr();
Employee e; //creating an object of Employee
e.sal();
getch();
}

Output
Enter salary: 4500
Salary: 4500

Class Member Functions


Functions help us manipulate data. Class member functions can be defined in two ways:

[email protected] contact 03354900611


OOPS IN C++ Notes P age |7

 Inside the class definition


 Outside the class definition
If a function is to be defined outside a class definition, we must use the scope resolution operator (::). This
should be accompanied by the class and function names.

Example

#include <iostream>
#include <string>
using namespace std;
class test
{
public:
string tutorial_name;
int id;
void printname();
void printid()
{
cout << "Tutorial id is: "<< id;
}
};
void test::printname()
{
cout << "Tutorial name is: " << tutorial_name;
}
int main() {
test t;
t.tutorial_name = "C++";
t.id = 1001;
t.printname();
cout << endl;
t.printid();
return 0;
}

Class Objects as Function Arguments (Parameters)


Like any other data-type, an object may be used as a function argument. This can be done in two ways:

1. A copy of the entire object is passed to the function


2. Only the address of the object is transferred to the function

The first method is called pass-by-value. Since a copy of the object is passed to the function, any changes
made to the object inside the function do not affect he object used to call the function.

The second method is called pass-by-reference. When an address of the object is passed, the called function
works directly on the actual object used in the call. This means that any changes made to the object inside the
function will reflect in the actual object. The pass-by-reference method is more efficient since it requires to
pass only the address of the object and not the entire object.

Pass object to a function

[email protected] contact 03354900611


OOPS IN C++ Notes P age |8

#include <iostream>
using namespace std;
class A {
public:
int n=100;
char ch='A';
void disp(A a){
cout<<a.n<<endl;
cout<<a.ch<<endl;
}
};
int main() {
A obj;
obj.disp(obj);
return 0;
}

Output:

100
A

Return object from a function


#include <iostream>
using namespace std;
class Student {
public:
int stuId;
int stuAge;
string stuName;
/* In this function we are returning the Student object. */
Student input(int n, int a, string s){
Student obj;
obj.stuId = n;
obj.stuAge = a;
obj.stuName = s;
return obj;
}
/* In this function we are passing object
* as an argument.
*/
void disp(Student obj){
cout<<"Name: "<<obj.stuName<<endl;
cout<<"Id: "<<obj.stuId<<endl;
cout<<"Age: "<<obj.stuAge<<endl;
}
};
int main() {
Student s;
s = s.input(1001, 29, "Naeem");
s.disp(s);
[email protected] contact 03354900611
OOPS IN C++ Notes P age |9

return 0;
}

Output:
Name: Naeem
Id: 1001
Age: 29

Access Specifiers in C++


Access specifiers in C++ define how the members of the class can be accessed. C++ has 3 new keywords
introduced, namely.
 public
 private
 protected

The keywords public, private, and protected are called access specifiers. A class can have multiple public,
protected, or private labeled sections.

Note: By default, all members and function of a class is private i.e if no access specifier is specified.

Syntax of Declaring Access Specifiers in C++


Syntax

class
{
private:
// private members and function
public:
// public members and function
protected:
// protected members and function

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 10

};

Public Access Specifier in C++


Public class members are accessible outside the class and it is available for everyone.
Syntax

class Public_Access_Specifier
{
public: // public access specifier
int a; // Data Member Declaration
void display(); // Member Function declaration
}

Private Access Specifier in C++


Private class members are accessible with the class and friend function. it is not accessible outside the
class. If someone try to access outside the it gives compile time error. By default class variables and
member functions are private.
Syntax

class Private_Access_Specifier
{
private: // private access specifier
int a; // Data Member Declaration
void display(); // Member Function declaration
}

Private and Public Access Specifier Example in C++


Example

#include<iostream.h>
#include<conio.h>

class A
{
private:
int a;
public:
int b;

public:

void show()
{
a=10 ;
b=20;
clrscr();
//Every members can be access here, same class
cout<<"\nAccessing variable within the class"<<endl;
cout<<"Value of a: "<<a<<endl;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 11

cout<<"Value of b: "<<b<<endl;
}
};

void main()
{
A obj; // create object
obj.show();

cout<<"\nAccessing variable outside the class"<<endl;


'a' cannot be accessed as it is private
//cout<<"value of a: "<<obj.a<<endl;
//'b' is public as can be accessed from any where
cout<<"value of b: "<<obj.b<<endl;

getch();
}

Note: If here, we access variable a inside main method it will give compile time error
Output

Accessing variable within the class


value of a: 10
value of b: 20
value of c: 30
Accessing variable outside the class
Value of b: 20

Protected Access Specifier in C++


It is similar to private access specifier. It makes class member inaccessible outside the class. But they can
be accessed by any subclass of that class.

Syntax

class Protected_Access_Specifier
{
protected: // protected access specifier
int a; // Data Member Declaration
void display(); // Member Function Declaration
}

Access Specifier Example in C++

In below example all these access specifier public, private and protected.
Access Specifier Example in C++

#include<iostream.h>

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 12

#include<conio.h>
//using namespace std;

class Declaration
{
private:
int a;
public:
int b;
protected:
int c;
public:

void show()
{
a=10;
b=20;
c=30;
//Every members can be access here, same class

cout<<"\nAccessing variable within the class"<<endl;


cout<<"Value of a: "<<a<<endl;
cout<<"Value of b: "<<b<<endl;
cout<<"Value of c: "<<c<<endl;
}
};

class Sub_class:public Declaration


{
public:
void show()
{
b=5;
c=6;
cout<<"\nAccessing variable in sub the class"<<endl;

// a is not accessible here it is private


//cout<<"Value of a: "<<a<<endl;
//b is public so it is accessible any where
cout<<"Value of b: "<<b<<endl;
//'c' is declared as protected, so it is accessible in sub class
cout<<"Value of c: "<<c<<endl;
}
};

void main()
{
clrscr();
Declaration d; // create object
d.show();

Sub_class s; // create object


s.show(); // Sub class show() function

cout<<"\nAccessing variable outside the class"<<endl;


[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 13

//'a' cannot be accessed as it is private


//cout<<"value of a: "<<d.a<<endl;
//'b' is public as can be accessed from any where

cout<<"value of b: "<<d.b<<endl;

//'c' is protected and cannot be accesed here


//cout<<"value of c: "<<d.c<<endl;
getch();
}

Output

Accessing variable within the class


value of a: 10
value of b: 20
value of c: 30

Accessing variable in sub class


value of b: 5
value of c: 6

Accessing variable outside the class


Value of b: 20

Inline Function in C++


Inline Function is powerful concept in C++ programming language. If a function is inline, the compiler
places a copy of the code of that function at each point where the function is called at compile time.
To make any function inline function just preceded that function with inline keyword.

Why use Inline function


Whenever we call any function many time then, it take a lot of extra time in execution of series of
instructions such as saving the register, pushing arguments, returning to calling function. For solve this
problem in C++ introduce inline function.
Any change to an inline function could require all clients of the function to be recompiled because compiler
would need to replace all the code once again otherwise it will continue with old functionality.
In many places we create the functions for small work/functionality which contain simple and less number
of executable instruction. Imagine their calling overhead each time they are being called by callers.
When a normal function call instruction is encountered, the program stores the memory address of the
instructions immediately following the function call statement, loads the function being called into the
memory, copies argument values, jumps to the memory location of the called function, executes the
function codes, stores the return value of the function, and then jumps back to the address of the instruction
that was saved just before executing the called function. Too much run time overhead.
The C++ inline function provides an alternative. With inline keyword, the compiler replaces the function
call statement with the function code itself (process called expansion) and then compiles the entire code.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 14

Thus, with inline functions, the compiler does not have to jump to another location to execute the function,
and then jump back as the code of the called function is already available to the calling program.
Pros
 The main advantage of inline function is it makes the program faster.
 It speeds up your program by avoiding function calling overhead.
 It save overhead of variables push/pop on the stack, when function calling happens.
 It save overhead of return call from a function.
 By marking it as inline, you can put a function definition in a header file (i.e. it can be included in
multiple compilation unit, without the linker complaining)
Cons
 It increases the executable size due to code expansion.
 C++ inlining is resolved at compile time. Which means if you change the code of the inlined
function, you would need to recompile all the code using it to make sure it will be updated
 When used in a header, it makes your header file larger with information which users don’t care.
Syntax

inline function_name()
{
//function body
}

Example

#include<iostream.h>
#include<conio.h>

inline void show()


{
cout<<"Hello world";
}

void main()
{
show(); // Call it like a normal function
getch();
}

Output

Hello word

Where inline function not work?


 If inline function are recursive
 If function contain static variables.
 If return statement are exits but not return any value.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 15

Function Overloading in C++


Whenever same method name is exiting multiple times in the same class with different number of
parameter or different order of parameters or different types of parameters is known as method
overloading.

Why method Overloading


Suppose we have to perform addition of given number but there can be any number of arguments, if we
write method such as a(int, int)for two arguments, b(int, int, int) for three arguments then it is very
difficult for you and other programmer to understand purpose or behaviors of method they cannot identify
purpose of method. So we use method overloading to easily figure out the program. For example above two
methods we can write sum(int, int) and sum(int, int, int) using method overloading concept.

Syntax

class class_Name
{
Returntype method()
{
...........
...........
}
Returntype method(datatype1 variable1)
{
...........
...........
}
Returntype method(datatype1 variable1, datatype2 variable2)
{
...........
...........
}
};

Different ways to overload the method


There are two ways to overload the method in C++
 By changing number of arguments or parameters
 By changing the data type

By changing number of arguments


In this example, we have created two overloaded methods, first sum method performs addition of two
numbers and second sum method performs addition of three numbers.

Program Function Overloading in C++

#include<iostream.h>
#include<conio.h>

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 16

class Addition
{
public:
void sum(int a, int b)
{
cout<<a+b;
}
void sum(int a, int b, int c)
{
cout<<a+b+c;
}
};
void main()
{
clrscr();
Addition obj;
obj.sum(10, 20);
cout<<endl;
obj.sum(10, 20, 30);
}

Output

30
60

By changing the data type


In this example, we have created two overloaded methods that differs in data type. The first sum method
receives two integer arguments and second sum method receives two float arguments.
Function Overloading Program in C++

#include<iostream.h>
#include<conio.h>

class Addition
{
public:
void sum(int a, int b)
{
cout<<a+b;
}
void sum(float a, float b)
{
cout<<a+b+c;
}
};
void main()
{
clrscr();
Addition obj;
obj.sum(10, 20);

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 17

cout<<endl;
obj.sum(10, 20, 30);
}

Output

30
25.25

Note: The scope of overloading is within the class.


Friend Function in C++
In C++ a Friend Function that is a "friend" of a given class is allowed access to private and protected data
in that class.
A function can be made a friend function using keyword friend. Any friend function is preceded
with friend keyword. The declaration of friend function should be made inside the body of class (can be
anywhere inside class either in private or public section) starting with keyword friend.
A friend can be a function, function template, or member function, or a class or class template, in which
case the entire class and all of its members are friends.
Why use friend function?
You do not access private or protected data member of any class, to access private and protected data
member of any class you need a friend function.
Syntax

class class_name
{
......
friend returntype function_name(arguments);
}

Characteristics of a Friend function:


o The function is not in the scope of the class to which it has been declared as a friend.
o It cannot be called using the object as it is not in the scope of that class.
o It can be invoked like a normal function without using the object.
o It cannot access the member names directly and has to use an object name and dot membership
operator with the member name.
o It can be declared either in the private or the public part.

Example Friend function

In below example you can access private function of class employee by using friend function.
Example

#include<iostream.h>
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 18

#include<conio.h>

class employee
{
private:
friend void sal();
};

void sal()
{
int salary=4000;
cout<<"Salary: "<<salary;
}

void main()
{
employee e;
sal();
getch();
}

Output

Salary: 4000

Example

#include <iostream>
using namespace std;
class Box
{
private:
int length;
public:
Box(): length(0) { }
friend int printLength(Box); //friend function
};
int printLength(Box b)
{
b.length += 10;
return b.length;
}
int main()
{
Box b;
cout<<"Length of box: "<< printLength(b)<<endl;
return 0;
}

Output:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 19

Length of box: 10

Friend class
Similarly like, friend function a class can be made a friend of another class using keyword friend. Similar
to friend functions, a friend class is a class whose members have access to the private or protected members of
another class:
When we create a friend class then all the member functions of the friend class also become the friend of the
other class. This requires the condition that the friend becoming class must be first declared or defined
(forward declaration).

Syntax

class A
{
friend class B; // class B is a friend class
......
}
class B
{
......
}

When a class is made a friend class, all the member functions of that class becomes friend function.
If B is declared friend class of A then, all member functions of class B can access private and protected
data of class A but, member functions of class A cannot private and protected data of class B.

Note: Remember, friendship relation in C++ is always granted not taken.

Forward Declaration refers to the beforehand declaration of the syntax or signature of an identifier,
variable, function, class, etc. prior to its usage (done later in the program)

In C++, Forward declarations are usually used for Classes. In this, the class is pre-defined before its use so that
it can be called and used by other classes that are defined before this.

Example:
// Forward Declaration class A
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 20

class A;

// Definition of class A
class A{
// Body
};
Example without using forward declaration

#include <iostream>
using namespace std;

class B {
public:
int x;

void getdata(int n)
{
x = n;
}
friend int sum(A, B);
};

class A {
public:
int y;
void getdata(int m)
{
y = m;
}
friend int sum(A, B);
};

int sum(A m, B n)
{
int result;
result = m.y + n.x;
return result;
}

int main()
{
B b;
A a;
a.getdata(5);
b.getdata(4);
cout << "The sum is : " << sum(a, b);
return 0;
}

Output:
Compile Errors :
prog.cpp:14:18: error: 'A' has not been declared
friend int sum(A, B);

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 21

Explanation: Here the compiler throws this error because, in class B, the object of class A is being used,
which has no declaration till that line. Hence compiler couldn’t find class A.
Let us add the forward declaration to the above example and check the output again.

#include <iostream>
using namespace std;

// Forward declaration
class A;
class B;

class B {
int x;

public:
void getdata(int n)
{
x = n;
}
friend int sum(A, B);
};

class A {
int y;

public:
void getdata(int m)
{
y = m;
}
friend int sum(A, B);
};
int sum(A m, B n)
{
int result;
result = m.y + n.x;
return result;
}

int main()
{
B b;
A a;
a.getdata(5);
b.getdata(4);
cout << "The sum is : " << sum(a, b);
return 0;
}

Output:
The sum is : 9

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 22

The program runs without any errors now. A forward declaration tells the compiler about the existence of an
entity before actually defining the entity. Forward declarations can also be used with other entity in C++, such
as functions, variables and user-defined types.

Example
#include <iostream>
using namespace std;

// forward declaration
class ClassB;

class ClassA {
private:
int numA;
friend class ClassB; // friend class declaration

public:
ClassA() : numA(12) {} // constructor to initialize numA to 12

};

class ClassB {
private:
int numB;

public:
ClassB() : numB(1) {} // constructor to initialize numB to 1

// member function to add numA


// from ClassA and numB from ClassB
int add() {
ClassA objectA;
return objectA.numA + numB;
}
};

int main() {
ClassB objectB;
cout << "Sum: " << objectB.add();
return 0;
}

Output
Sum: 13

Here, ClassB is a friend class of ClassA. So, ClassB has access to the members of classA. In ClassB, we
have created a function add() that returns the sum of numA and numB. Since ClassB is a friend class, we
can create objects of ClassA inside of ClassB
C++ Accessor & Mutator Member Functions

Accessor Member Function


[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 23

The accessor member function gets the value of a private data member of the class. This method is also known
as Get or Getter method.
//C++ Accessor Member Function
string getName()
{
return name; // return employees's name
}

Mutator Member Function


The mutator member function sets a new value to the private data member of the class. There are other use
cases where we use the mutator method to clean or ensure that the private data variable can only have valid
data. This method is also known as Set or Setter method.
//C++ Mutator Member Function
void setName(string name)
{
this->name = name; // set employees's name
}
Example

class Student
{
private: // private data member
int rollno;

public:
// public function to get value of rollno - getter
int getRollno()
{
return rollno;
}
// public function to set value for rollno - setter
void setRollno(int i)
{
rollno=i;
}
};

int main()
{
Student A;
A.rollono=1; //Compile time error
cout<< A.rollno; //Compile time error

A.setRollno(1); //Rollno initialized to 1


cout<< A.getRollno(); //Output will be 1
}
Constructor in C++
A Constructor is a special member method which will be called implicitly (automatically) whenever an
object of class is created. In other words, it is a member function which initializes a class which is called
automatically whenever a new instance of a class is created.
Features of Constructor
 The same name as the class itself.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 24

 no return type.

Syntax

classname()
{
....
}

Note: If you do not specify a constructor, the compiler generates a default constructor for you (expects no
parameters and has an empty body).
Why use constructor?
The main use of constructor is placing user defined values in place of default values.
How Constructor eliminate default values?
Constructor are mainly used for eliminate default values by user defined values, whenever we create an
object of any class then its allocate memory for all the data members and initialize there default values. To
eliminate these default values by user defined values we use constructor.
Example of Constructor in C++

#include<iostream.h>
#include<conio.h>
class sum
{
int a,b,c;
sum()
{
a=10;
b=20;
c=a+b;
cout<<"Sum: "<<c;
}
};

void main()
{
sum s;
getch();
}

Output

Sum: 30

In above example when we create an object of "Sum" class then constructor of this class call and initialize
user defined value in a=10 and b=20. And here we no need to call sum() constructor.

C++ Parameterized Constructor


In C++, a constructor with parameters is known as a parameterized constructor. This is the preferred method
to initialize member data.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 25

Example

// C++ program to calculate the area of a wall

#include <iostream>
using namespace std;

// declare a class
class Wall {
private:
double length;
double height;

public:
// parameterized constructor to initialize variables
Wall(double len, double hgt) {
length = len;
height = hgt;
}

double calculateArea() {
return length * height;
}
};

int main() {
// create object and initialize data members
Wall wall1(10.5, 8.6);
Wall wall2(8.5, 6.3);

cout << "Area of Wall 1: " << wall1.calculateArea() << endl;


cout << "Area of Wall 2: " << wall2.calculateArea();

return 0;
}

Output

Area of Wall 1: 90.3


Area of Wall 2: 53.55

C++ Copy Constructor


The copy constructor in C++ is used to copy data of one object to another. A copy constructor is a special
constructor in the C++ programming language for creating a new object as a copy of an existing object.

Example

class_name (const class_name&);


{
......

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 26

Example

#include <iostream>
using namespace std;
// declare a class
class Wall {
private:
double length;
double height;

public:
// initialize variables with parameterized constructor
Wall(double len, double hgt) {
length = len;
height = hgt;
}
// copy constructor with a Wall object as parameter
// copies data of the obj parameter
Wall(Wall &obj) {
length = obj.length;
height = obj.height;
}

double calculateArea() {
return length * height;
}
};

int main() {
// create an object of Wall class
Wall wall1(10.5, 8.6);
// copy contents of wall1 to wall2
Wall wall2 = wall1;
// print areas of wall1 and wall2
cout << "Area of Wall 1: " << wall1.calculateArea() << endl;
cout << "Area of Wall 2: " << wall2.calculateArea();

return 0;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 27

Output

Area of Wall 1: 90.3


Area of Wall 2: 90.3

In this program, we have used a copy constructor to copy the contents of one object of the Wall class to
another. The code of the copy constructor is:

Wall(Wall &obj) {
length = obj.length;
height = obj.height;
}

Notice that the parameter of this constructor has the address of an object of the Wall class.
We then assign the values of the variables of the obj object to the corresponding variables of the object calling
the copy constructor. This is how the contents of the object are copied.
In main(), we then create two objects wall1 and wall2 and then copy the contents of wall1 to wall2:

// copy contents of wall1 to wall2


Wall wall2 = wall1;

Here, the wall2 object calls its copy constructor by passing the address of the wall1 object as its argument
i.e. &obj = &wall1.
Constructor overloading in C++
As there is a concept of function overloading, similarly constructor overloading is applied. When we overload
a constructor more than a purpose it is called constructor overloading.
The declaration is the same as the class name but as they are constructors, there is no return type.
The criteria to overload a constructor are to differ the number of arguments or the type of arguments.

Example

// C++ program to demonstrate constructor overloading


#include <iostream>
using namespace std;
class Person {
private:
int age; // data member
public:
// 1. Constructor with no arguments
Person()
{
age = 20; // when object is created the age will be 20
}
// 2. Constructor with an argument
Person(int a)

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 28

{ // when parameterised Constructor is called with a value the


age = a; // age passed will be initialised
}
intgetAge()
{ // getter to return the age
return age;
}
};
int main()
{
Person person1, person2(45); // called the object of person class in different way

cout<< "Person1 Age = " << person1.getAge() <<endl;


cout<< "Person2 Age = " << person2.getAge() <<endl;
return 0;
}

Output

Person1 Age = 20
Person2 Age = 45

Destructor
Destructor is a member function which deletes an object. A destructor function is called automatically
when the object goes out of scope:
When destructor call
 when program ends
 when a block containing temporary variables ends
 when a delete operator is called

Features of destructor
 The same name as the class but is preceded by a tilde (~)
 no arguments and return no values
Syntax

~classname()
{
......
}

Note: If you do not specify a destructor, the compiler generates a default destructor for you.
Example of Destructor in C++

#include<iostream.h>

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 29

#include<conio.h>

class sum
{
int a,b,c;
sum()
{
a=10;
b=20;
c=a+b;
cout<<"Sum: "<<c;
}
~sum()
{
cout<<<<endl;"call destructor";
}
delay(500);
};

void main()
{
sum s;
cout<<<<endl;"call main";
getch();
}

Output
Sum: 30
call main
call destructor

Explanation: In above example when you create object of class sum auto constructor of class is call and
after that control goes inside main and finally before end of program destructor is call.

Copy constructor vs assignment operator in C++


The Copy constructor and the assignment operators are used to initializing one object to another object. The
main difference between them is that the copy constructor creates a separate memory block for the new object.
But the assignment operator does not make new memory space. It uses the reference variable to point to the
previous memory block.

Copy Constructor (Syntax)


classname (const classname &obj) {
// body of constructor
}

Assignment Operator (Syntax)


classname Ob1, Ob2;

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 30

Ob2 = Ob1;

Let us see the detailed differences between Copy constructor and Assignment Operator.

Copy constructor Assignment operator

It is called when a new object is created from an This operator is called when an already initialized object
existing object, as a copy of the existing object is assigned a new value from another existing object.

It creates a separate memory block for the new It does not create a separate memory block or new
object. memory space.

It is an overloaded constructor. It is a bitwise operator.

#include <iostream>
#include <stdio.h>
using namespace std;

class Test {
public:
Test() {}
Test(const Test& t)
{
cout << "Copy constructor called " << endl;
}

Test& operator=(const Test& t)


{
cout << "Assignment operator called " << endl;
return *this;
}
};

// Driver code
int main()
{
Test t1, t2;
t2 = t1; //assignment operator
Test t3 = t1; // copy constructor
getchar();
return 0;
}
Output
Assignment operator called
Copy constructor called
Explanation: Here, t2 = t1; calls the assignment operator, same as t2.operator=(t1); and Test t3 =
t1; calls the copy constructor, same as Test t3(t1);

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 31

Shallow Copy
A shallow copy of an object copies the "main" object, but doesn’t copy the inner objects. The "inner objects"
are shared between the original object and its copy.
The problem with the shallow copy is that the two objects are not independent. If you modify the one object,
the change will be reflected in the other object.
Whenever we do not create our own user-defined copy constructor and we do copying, the compiler creates its
own hidden copy constructor.
 Whenever this happens the member variables etc share the same memory locations.
 Any change in object1 is also reflected in object2
This default copy constructor does shallow copy. The code below reflects what happens in shallow copy.

Shallow Copy Example

#include<iostream>
using namespace std;

class PrepInsta
{
int *var;
public:

// Parmeterized constructor

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 32

PrepInsta(int x) {
var = new int;
*var = x;
}

// setter
void setValue(int val){
*var = val;
}

// getter
int getValue(){
return *var;
}

// the compiler would create its own hidden copy constructor


// as we have not created our own user defined copy constructor here
// shallow copy will happen i.e. objects variables etc will share memory

};
int main()
{
// calling the normal constructor
PrepInsta obj1(10);

// calling default copy constructor of compiler (Shallow Copy)


PrepInsta obj2 = obj1;

cout << "Before value change - " << endl;


// printing the values, assigned by constructors
cout << "obj1.var = " << obj1.getValue() << endl;
cout << "obj2.var = " << obj2.getValue() << endl;

obj1.setValue(20);
cout << "\nAfter value change - " << endl;
// printing the values, assigned by constructors
cout << "obj1.var = " << obj1.getValue() << endl;
cout << "obj2.var = " << obj2.getValue() << endl;
// since we did shallow copy as we didnt make any
// user defined copy constructor
// change in obj1 is reflected in obj2
return 0; }
Output
Before value change -
obj1.var = 10
obj2.var = 10

After value change -


obj1.var = 20
obj2.var = 20

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 33

Deep Copy
A deep copy is a fully independent copy of an object. If we copied our object, we would copy the entire object
structure. If you modify the one object, the change will not be reflected in the other object.
Whenever we create our own user-defined copy constructor and we do the copying.
 Whenever this happens the member variables etc for any objects have their own memory locations.
 For example, any change in object1 is not reflected in object2

User-defined copy constructor do a deep copy. Code below reflects what happens in shallow copy

Deep Copy Example

#include<iostream>
using namespace std;

class PrepInsta
{
public:
int var;

PrepInsta(int x) {
var = x;
}

// Overriding default copy constructor


[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 34

// with user defind copy contructor


PrepInsta(const PrepInsta &obj) {
var = obj.var;
}
};

int main()
{
// calling the normal constructor
PrepInsta obj1(10);

// calling user defined copy constructor (Deep Copy)


PrepInsta obj2 = obj1;

cout << "Before value change - " << endl;

// printing the values, assigned by constructors


cout << "obj1.var = " << obj1.var << endl;
cout << "obj2.var = " << obj2.var << endl;

obj1.var = 20;

cout << "\nAfter value change - " << endl;

// printing the values, assigned by constructors


cout << "obj1.var = " << obj1.var << endl;
cout << "obj2.var = " << obj2.var << endl;

// since we did deep copy using user defined copy constructor


// change in obj1 is not reflected in obj2

return 0;
}
Output
Before value change -
obj1.var = 10
obj2.var = 10

After value change -


obj1.var = 20
obj2.var = 10

Static Data Members in C++


 When a static data member is created, there is only a single copy of the data member which is shared
between all the objects of the class. if the data members are not static then every object has an
individual copy of the data member and it is not shared. If any variable we declared as static is
known as static variable.
 Static variable is used for fulfill the common requirement. For Example company name of
employees, college name of students etc. Name of the college is common for all students.
 The static variable allocate memory only once in class area at the time of class loading.
Advantage of static variable
 Using static variable we make our program memory efficient (i.e it saves memory).

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 35

When and why we use static variable


 Suppose we want to store record of all employee of any company, in this case employee id is unique
for every employee but company name is common for all. When we create a static variable as a
company name then only once memory is allocated otherwise it allocate a memory space each time
for every employee.
Syntax
static data_type data_member

Static Methods in C++


 When a static method is created, they become independent of any object and class. Static methods
can only access static data members and static methods. Static methods can only be accessed using the
(::) scope resolution operator.
 A static member function shares the single copy of the member function to any number of the class'
objects. We can access the static member function using the class name or class' objects. If the static
member function accesses any non-static data member or non-static member function, it throws an
error.
 An example program is shown below to demonstrate static data members and static methods in C++.

Example
class Employee
{
int id;
static int count;

public:
void setData(void)
{
cout << "Enter the id" << endl;
cin >> id;
count++;
}
void getData(void)
{
cout << "The id of this employee is " << id << " and this is employee number " << count << endl;
}

static void getCount(void){


// cout<<id; // throws an error
cout<<"The value of count is "<<count<<endl;
}
};
int Employee::count; // Default value is 0

int main()
{
Employee ali,javeria,zeeshan;
// ali.id = 1;
// ali.count=1; // cannot do this as id and count are private

ali.setData();
ali.getData();
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 36

Employee::getCount();

javeria.setData();
javeria.getData();
Employee::getCount();

zeeshan.setData();
zeeshan.getData();
Employee::getCount();

return 0;
}

Example Let's create another program to access the static member function using the class' object in the
C++ programming language.

#include <iostream>
using namespace std;
class Note
{
static int num; // declare a static data member

public:
static int func () // create static member function
{
cout << " The value of the num is: " << num << endl;
}
};
// initialize the static data member using the class name and the scope resolution operator
int Note :: num = 15;

int main ()
{
Note n; // create an object of the class Note
n.func(); // access static member function using the object
return 0;
}
Output
The value of the num is: 15

C++ this Pointer


In C++ programming, this is a keyword that refers to the current instance of the class. The this pointer is an
implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to
the invoking object. this pointer can also be used to return its own reference.
Friend functions do not have a this pointer, because friends are not members of a class. Only member
functions have this pointer.
this’ pointer is not available in static member functions as static member functions can be called without
any object (with class name).
Following are the situations where ‘this’ pointer is used:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 37

 When local variable’s name is same as member’s name.


 To return reference to the calling object
 cascade function call

Example When local variable’s name is same as member’s name.


#include<iostream>
using namespace std;

/* local variable is same as a member's name */


class Test
{
private:
int x;
public:
void setX (int x)
{ // The 'this' pointer is used to retrieve the object's x
// hidden by the local variable 'x'
this->x = x;
}
void print() { cout << "x = " << x << endl; }
};

int main()
{
Test obj;
int x = 20;
obj.setX(x);
obj.print();
return 0;
}
Output
x = 20

Example: To return reference to the calling object.


#include<iostream>
using namespace std;
class Max
{
int a;
public:
void getdata()
{
cout<<"Enter the Value :";
cin>>a;
}
Max &greater(Max &x)
{
if(x.a>=a)
return x;
else return *this;
}
void display()
{
cout<<"Maximum No. is : "<<a<<endl;

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 38

}
};
int main()
{
Max one,two,three;
one.getdata();
two.getdata();
three=one.greater(two);
three.display();

return 0;
}
Output
Enter the Value :5
Enter the Value :8
Maximum No. is : 8

Cascaded function call in C++


C++ programming allows calling functions like this, when multiple functions called using a single object name
in a single statement, it is known as cascaded function call in C++.
As we know that this pointer returns the pointer of current object, by using this pointer we can achieve
cascaded function calls.
#include<iostream>
using namespace std;

class Demo
{
public:
Demo FUN1()
{
cout <<"\nFUN1 CALLED"<<endl;

return *this;
}

Demo FUN2()
{
cout <<"\nFUN2 CALLED"<<endl;

return *this;
}

Demo FUN3()
{
cout <<"\nFUN3 CALLED"<<endl;

return *this;
}

};

int main()
{
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 39

Demo ob;

ob.FUN1().FUN2().FUN3();

return 0;
}
Output
FUN1 CALLED

FUN2 CALLED

FUN3 CALLED

Example Cascade Function Call


#include <iostream>
using namespace std;
class Square
{
public:
int side;
Square area()
{
cout << "Area of the square is :" << side*side <<endl;
return *this;
}
Square perimeter()
{
cout << "Perimeter of the square is :" << 4*side <<endl;
return *this;
}
};
int main()
{
Square sq;
sq.side =3;

sq.area().perimeter(); //cascading function calls


return 0;
}
output
Area of the square is :9
Perimeter of the square is :12
we have created a class Square and defined functions area() and perimeter() for it. The
function area() prints the area of the square and the function perimeter() prints the perimeter of the
square. *this pointer specifies that the functions return a reference to the object which makes cascading
possible.

Types of Overloading
There are two types of Overloading as follows:
1. Function Overloading.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 40

2. Operator Overloading.
Operator overloading is a compile-time polymorphism in which the operator is overloaded to provide special
meaning to the user-defined data type. Operator overloading is used to overload or redefine most of the
operators available in C++. It is used to perform the operation on the user-defined data type.
C++ operator overloading is one of the most powerful features of C++ that allows a user to change the way
the operator works. In C++ the meaning of existing operator can be extended to operate on user-defined data
or class data.
Using operator overloading in C++, you can specify more than one meaning for an operator in one scope.
For example: - '+' operator can be overloaded to perform addition on various data types, like for Integer, String
(concatenation) etc.
Other example: - classes where arithmetic operators may be overloaded are Complex Number, Fractional
Number, Big Integer, etc
Why do we need Operator overloading in C++?
Operators in C++ like +, -, *, / can operate in datatypes like int, float, double etc as predefined operational
meanings. But these operators can’t operate in user-defined datatypes like objects without extension or adding
some sort of code to alter their operational meaning.
Such a way of extending the operational functionality of certain operators in C++ is called operator
overloading.

The advantage of operator overloading is that it can perform different operations on the same operand.

For Example:-
Suppose we have created three objects a1, a2 and sum 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 a1 and a2 by writing the following code:

sum = a1 + a2;
instead of something like

sum = a1.addNum(a2);
This makes our code intuitive and easy to understand.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 41

Note: We cannot use operator overloading for fundamental data types like int, float, char and so on.

Syntax for Operator Overloading in C++


To overload an operator, we use a special operator function.
class className {
... .. ...
public
return_type operator symbol (argument(s)) {
... .. ...
}
... .. ...
};
Here, is an explanation for the above syntax:
 return_type is the return type of the function.
 Next, we mention the operator keyword.
 symbol is the operator we want to overload. Like: +, <, -, ++, etc.
 argument(s) can be passed to the operator function in the same way as function.

What is the difference between operator functions and normal functions?


Operator functions are same as normal functions. The only differences are, name of an operator function is
always operator keyword followed by symbol of operator and operator functions are called when the
corresponding operator is used.

Types of Overloading approaches


Operator Overloading can be done by using three approaches, they are
 Overloading unary operator.
 Overloading binary operator.
 Overloading binary operator using a friend function.

Operator Overloading in Unary Operators


Unary operators operate on only one operand. The increment operator ++ and decrement operator -- are
examples of unary operators.

Example: C++ Program to Overload the Unary Operator (++)


#include <iostream>
using namespace std;
class Count {
private:
int num;
public:
Count() : value(2) {} // Constructor to initialize count to 2
void operator ++ () {
num = num + 2;
}
void display() {
cout << "The Count: " << num << endl;
}
};
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 42

int main() {
Count c;
++c; // Call the "void operator ++ ()" function
c.display();
return 0; }
Output

The Count: 4
Note: When we overload operators, we can use it to work in any way we like. For example, we could have
used ++ to increase value by 100.

The above example works only when ++ is used as a prefix. To make ++ work as a postfix we use this syntax.
void operator ++ (int) {
// code
}

Notice the int inside the parentheses. It's the syntax used for using unary operators as postfix; it's not a function
parameter.
Example : C++ Operator Overloading using Unary Operator
// Overload ++ when used as prefix and postfix
#include <iostream>
using namespace std;
class Count {
private:
int value;

public:
Count() : value(5) {} // Constructor to initialize count to 5

void operator ++ () { // Overload ++ when used as prefix


++value;
}

void operator ++ (int) { // Overload ++ when used as postfix


value++;
}

void display() {
cout << "Count: " << value << endl;
}
};

int main() {
Count count1;

count1++; // Call the "void operator ++ (int)" function


count1.display();

++count1; // Call the "void operator ++ ()" function


count1.display();
return 0;
}
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 43

Output
Count: 6
Count: 7

The Example 2 works when ++ is used as both prefix and postfix. However, it doesn't work if we try to do
something like this:
Count count1, result;
// Error
result = ++count1;
This is because the return type of our operator function is void. We can solve this problem by
making Count as the return type of the operator function.
// return Count when ++ used as prefix
Count operator ++ () {
// code
}
// return Count when ++ used as postfix
Count operator ++ (int) {
// code
}

Example: Return Value from Operator Function (++ Operator)


#include <iostream>
using namespace std;

class Count {
private:
int value;
public :
Count() : value(5) {} // Constructor to initialize count to 5

Count operator ++ () { // Overload ++ when used as prefix


Count temp;
temp.value = ++value; // Here, value is the value attribute of the calling object
return temp;
}

Count operator ++ (int) { // Overload ++ when used as postfix


Count temp;
temp.value = value++; // Here, value is the value attribute of the calling object

return temp;
}

void display() {
cout << "Count: " << value << endl;
}
};

int main() {
Count count1, result;
result = ++count1; // Call the "Count operator ++ ()" function
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 44

result.display();

result = count1++; // Call the "Count operator ++ (int)" function


result.display();

return 0;
}

Output
Count: 6
Count: 6

Here, we have used the following code for prefix operator overloading:

// Overload ++ when used as prefix


Count operator ++ () {
Count temp;

// Here, value is the value attribute of the calling object


temp.value = ++value;

return temp;
}
The code for the postfix operator overloading is also similar. Notice that we have created an object temp and
returned its value to the operator function.
Also, notice the code

temp.value = ++value;

The variable value belongs to the count1 object in main() because count1 is calling the function,
while temp.value belongs to the temp object.

Operator Overloading in Binary Operators


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.

Example: C++ Binary Operator Overloading


#include <iostream>
using namespace std;
class A {
int n;
public:
A(){}
A (int s) {
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 45

n = s;
}
void operator + (A);
void display ();
};
void :: operator+ (A a) {
int m = n + a.n;
cout << "The Result of addition of two objects: " << m << endl;
}
int main() {
A a1(5);
A a2(4);

a1 + a2;

return 0;
}
Output
The Result of addition of two objects: 9
Example: C++ Program to overload the binary operator and adds two complex
numbers
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imagine;

public:
// Constructor to initialize real and imagine to 0
Complex() : real(0), imagine(0) {}

void input() {
cout << "Enter real and imaginary Number respectively: ";
cin >> real;
cin >> imagine;
}

// Overload the + operator


Complex operator + (const Complex& obj) {
Complex test;
test.real = real + obj.real;
test.imagine = imagine + obj.imagine;
return test;
}

void output() {
if (imagine < 0)
cout << "Output Complex number: " << real << imagine << "i";
else
cout << "Output Complex number: " << real << "+" << imagine << "i";
}
};

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 46

int main() {
Complex complex1, complex2, result;

cout << "Enter first complex number:\n";


complex1.input();

cout << "Enter second complex number:\n";


complex2.input();

// complex1 calls the operator function


// complex2 is passed as an argument to the function
result = complex1 + complex2;
result.output();

return 0;
}
Output
Enter first complex number:
Enter real and imaginary parts respectively: 6 3
Enter second complex number:
Enter real and imaginary parts respectively: 5 4
Output Complex number: 11+7i
In this program, the operator function is:

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
1. With operator overloading, you can redefine the way an operator works only for the user-defined
types (objects, structures). You cannot use it for built-in types (float, char, int, etc.).
2. 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.
3. Operator overloading cannot change the precedence and associativity of operators. However, if we
want to change the order of evaluation, parentheses should be used.
4. There are 5 operators that cannot be overloaded in C++. They are:
a. :: scope resolution operator
b. ?: ternary operator

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 47

c. . member selector
d. sizeof Operator
e. * member pointer selector

Rules for Operator Overloading


Here are the rules for Operator Overloading:
 For it to work, at least one operand must be a user-defined class object.
 You can only overload existing operators. You can't overload new operators.
 Some operators cannot be overloaded using a friend function. However, such operators can be
overloaded using member function.
C++ Program to Increment ++ and Decrement -- Operator Overloading
increment ++ and decrements -- operator are overloaded in best possible way, i.e., increase the value of a data
member by 1 if ++ operator operates on an object and decrease value of data member by 1 if -- operator is
used.
Example : Program to Prefix ++ Increment Operator Overloading with no return type
#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(0) { }
void operator ++()
{ ++i; }
void Display()
{ cout << "i=" << i << endl; }
};

int main()
{
Check obj;
obj.Display(); // Displays the value of data member i for object obj
++obj; // Invokes operator function void operator ++( )
obj.Display(); // Displays the value of data member i for object obj
return 0;
}
Output
i=0
i=1
Working
Initially when the object obj is declared, the value of data member i for object obj is 0 (constructor
initializes i to 0).

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 48

When ++ operator is operated on obj, operator function void operator++( ) is invoked which increases the
value of data member i to 1.

This program is not complete in the sense that, you cannot used code:

obj1 = ++obj;
It is because the return type of operator function in above program is void. Here is the little modification of
above program so that you can use code obj1 = ++obj.

Example: Program to Prefix Increment ++ operator overloading with return type


#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(0) { }

Check operator ++() // Return type is Check


{
Check temp;
++i;
temp.i = i;
return temp;
}

void Display()
{ cout << "i = " << i << endl; }
};

int main()
{
Check obj, obj1;
obj.Display();
obj1.Display();

obj1 = ++obj;

obj.Display();
obj1.Display();

return 0;
}
Output

i=0
i=0
i=1
i=1

Working

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 49

This program is similar to the one above. The only difference is that, the return type of operator function
is Check in this case which allows to use both codes ++obj; obj1 = ++obj;. It is because, temp returned from
operator function is stored in object obj.

Since, the return type of operator function is Check, you can also assign the value of obj to another object.
Notice that, = (assignment operator) does not need to be overloaded because this operator is already
overloaded in C++ library.
Example: Program to Postfix Increment ++ Operator Overloading
Overloading of increment operator up to this point is only true if it is used in prefix form. This is the
modification of above program to make this work both for prefix form and postfix form.
#include <iostream>
using namespace std;
class Check
{
private:
int i;
public:
Check(): i(0) { }
Check operator ++ ()
{
Check temp;
temp.i = ++i;
return temp;
}
// Notice int inside barcket which indicates postfix increment.
Check operator ++ (int)
{
Check temp;
temp.i = i++;
return temp;
}
void Display()
{ cout << "i = "<< i <<endl; }
};
int main()
{
Check obj, obj1;
obj.Display();
obj1.Display();
// Operator function is called, only then value of obj is assigned to obj1
obj1 = ++obj;
obj.Display();
obj1.Display();
// Assigns value of obj to obj1, only then operator function is called.
obj1 = obj++;
obj.Display();
obj1.Display();
return 0;
}
Output
i=0
i=0
i=1
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 50

i=1
i=2
i=1
Working
When increment operator is overloaded in prefix form; Check operator ++ () is called but, when increment
operator is overloaded in postfix form; Check operator ++ (int) is invoked.
Notice, the int inside bracket. This int gives information to the compiler that it is the postfix version of
operator. Don't confuse this int doesn't indicate integer.

Example : Program to Operator Overloading of Decrement -- Operator


Decrement operator can be overloaded in similar way as increment operator .

#include <iostream>
using namespace std;

class Check
{
private:
int i;
public:
Check(): i(3) { }
Check operator -- ()
{
Check temp;
temp.i = --i;
return temp;
}
// Notice int inside barcket which indicates postfix decrement.
Check operator -- (int)
{
Check temp;
temp.i = i--;
return temp;
}
void Display()
{ cout << "i = "<< i <<endl; }
};

int main()
{
Check obj, obj1;
obj.Display();
obj1.Display();
// Operator function is called, only then value of obj is assigned to obj1
obj1 = --obj;
obj.Display();
obj1.Display();
// Assigns value of obj to obj1, only then operator function is called.
obj1 = obj--;
obj.Display();
obj1.Display();
return 0;
}
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 51

Output

i=3
i=3
i=2
i=2
i=1
i=2

Also, unary operators like: !, ~ etc can be overloaded in similar manner.

Overload binary plus (+) operator using non-member or free function in C++
This type of non-member function will access the private member of class. So the function must be friend type
(friend function).
using namespace std;
#include <iostream>
class Sample
{
//private data members
private:
int value;

public:
//default constructor
Sample()
{ value = 0;}

//Parameterized constructor
Sample(int c)
{ value = c;}

//making operator overloading declaration as


//friend function
friend Sample operator+(Sample &S1, Sample &S2);
void printValue() //printing value
{
cout<<"Value is : "<<value<<endl;
}
};

//overator overloading function definition


Sample operator+(Sample &S1, Sample &S2)
{
Sample S;
S = S1.value+S2.value;
return S;
}
//main program
int main()
{
int i = 0;
Sample S1(100); //object declaration by calling parameterized constructor
Sample S2(200);
Sample S3;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 52

//adding objects (Binary + operator overloading)


S3 = S1 + S2;
cout<<"S1 :"<<endl;
S1.printValue();

cout<<"S2 :"<<endl;
S2.printValue();

cout<<"S3 :"<<endl;
S3.printValue();

return 0;
}
Output

S1 :
Value is : 100
S2 :
Value is : 200
S3 :
Value is : 300
C++ Overload [] array subscript operator
We can overload the [] operator to implement safe array indexing. In C++, it is possible to overrun or underrun
an array boundary at run time without generating a run-time error message.
However, if you create a class that contains the array, and allow access to that array only through the
overloaded [] subscripting operator, then you can intercept an out-of-range index.
For example, the program adds a range check to the array subscripting operator:
// A safe array example.
#include <iostream>
#include <cstdlib>
using namespace std;

const int SIZE = 3;

class My_Class {
int a[SIZE];
public:
My_Class() {
register int i;

for(i=0; i<SIZE; i++) a[i] = i;


}
int &operator[](int i);
};

int &My_Class::operator[](int i) // Provide range checking for My_Class.

{
if(i<0 || i> SIZE-1) {
cout << "\nIndex value of ";
cout << i << " is out-of-bounds.\n";
exit(1);

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 53

}
return a[i];
}

int main()
{
My_Class ob;

cout << ob[2]; // displays 2


cout << " ";

ob[2] = 25; // [] appears on left

cout << ob[2]; // displays 25

ob[3] = 44; // generates runtime error, 3 out-of-range


return 0;
}

output.
2 25
Index value of 3 out of bounds

Inheritance in C++
The process of obtaining the data members and methods from one class to another class is known as inheritance. It is
one of the fundamental features of object-oriented programming.
Important points
 In the inheritance the class which is give data members and methods is known as base or super or
parent class.
 The class which is taking the data members and methods is known as sub or derived or child class.
Syntax

class subclass_name : superclass_name


{
// data members

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 54

// methods
}
Real Life Example of Inheritance in C++

The real life example of inheritance is child and parents, all the properties of father are inherited by his son.

Diagram

In the above diagram data members and methods are represented in broken line are inherited from faculty class and
they are visible in student class logically.

Advantage of inheritance

If we develop any application using this concept than that application have following advantages,

 Application development time is less.

 Application take less memory.

 Application execution time is less.

 Application performance is enhance (improved).

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 55

 Redundancy (repetition) of the code is reduced or minimized so that we get consistence results and
less storage cost.
Inheriting the feature from base class to derived class

In order to inherit the feature of base class into derived class we use the following syntax
Syntax
class classname-2 : classname-1
{
variable declaration;
method declaration;
}
Explanation

 classname-1 and classname-2 represents name of the base and derived classes respectively.

 : is operator which is used for inheriting the features of base class into derived class it improves the

functionality of derived class.

Inheritance implements is-a relationship as shown in the figure.

// Base class
class Vehicle {
public:
string make = "Toyota";
void honk() {
cout << "Poom poom! \n" ;
}
};
// Derived class of Vehicle
class Car: public Vehicle {
public:
string model = "Corolla";
};
int main() {
Car car1;
car1.honk();
cout << car1.make + " " + car1.model;
return 0;
}
Here, the Car class derives from the Vehicle class. Since car derives from Vehicle, the member of Vehicle are accessible
to Car.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 56

One thing you should observe is the use of the keyword public while inheriting Car from Vehicle.

class Car: public Vehicle {


...
};
C++ protected Members

 The access modifier protected is especially relevant when it comes to C++ inheritance.
 Like private members, protected members are inaccessible outside of the class. However, they can be accessed
by derived classes and friend classes/functions.
 We need protected members if we want to hide the data of a class, but still want that data to be inherited by its
derived classes.

Example : C++ Program to demonstrate protected members

#include <iostream>
#include <string>
using namespace std;
// base class
class Animal {
private:
string color;
protected:
string type;
public:
void eat() {
cout << "I can eat!" << endl;
}
void sleep() {
cout << "I can sleep!" << endl;
}
void setColor(string clr) {
color = clr;
}
string getColor() {
return color;
}
};
// derived class
class Cat : public Animal {

public:
void setType(string t) {
type = t;
}

void displayInfo(string c) {
cout << "I am a " << type << endl;
cout << "My color is " << c << endl;
}

void meow() {
cout << "I can meow! meoww meoww!!" << endl;
}
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 57

};
int main() {
// Create object of the Cat class
Cat cat1;
// Calling members of the base class
cat1.eat();
cat1.sleep();
cat1.setColor("white");
// Calling member of the derived class
cat1.meow();
cat1.setType("mammal");
// Using getColor() of cat1 as argument
// getColor() returns string data
cat1.displayInfo(cat1.getColor());
return 0;
}
Output

I can eat!
I can sleep!
I can meow! meoww meoww!!
I am a mammal
My color is white
Here, the variable type is protected and is thus accessible from the derived class Cat. We can see this as we have
initialized type in the Cat class using the function setType().

On the other hand, the private variable color cannot be initialized in Cat.

class Cat : public Animal {

public:
void setColor(string clr) {
// Error: member "Animal::color" is inaccessible
color = clr;
}
};
Also, since the protected keyword hides data, we cannot access type directly from an object of Cat or Animal class.

// Error: member "Animal::type" is inaccessible


cat1.type = "mammal";

C++ Inheritance Access Control

Inheritance Access Control


 When creating a derived class from a base class then, you can use different access specifiers to inherit the data
members of the base class.
 The derived class can access all the non-private members of its base class. And the base class members that are
not accessible to the member functions of derived classes should be declared private in the base class.
 The access specifiers that are used are public, private and protected.
 When deriving a class from a base class, the base class may be inherited through public, private and protected
inheritance

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 58

 In C++ inheritance, we can derive a child class from the base class in different access modes. For example,

class Base {
.... ... ....
};

class Derived : public Base {


.... ... ....
};
 Notice the keyword public in the code

class Derived : public Base


 This means that we have created a derived class from the base class in public mode. Alternatively, we can also
derive classes in protected or private modes.

We have used the public keyword in order to inherit a class from a previously-existing base class. However, we can also
use the private and protected keywords to inherit classes.
For example,
class Animal {
// code
};
class Dog : private Animal {
// code
};
class Cat : protected Animal {
// code
};
The various ways we can derive classes are known as access modes. These access modes have the following effect:
1. Public mode: This is the most used inheritance mode. In this the protected member of super class becomes
protected members of sub class and public becomes public.
2. Protected mode: In protected mode, Then both public member and protected members of the Super class will
become protected in Sub class.
3. Private mode: In private mode, the protected and public members of super class become private members of
Sub class.

Note: private members of the base class are inaccessible to the derived class.

class Base {
public:
int a;
protected:
int b;
private:
int c;
};
class PublicDerived: public Base {
// a is public
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 59

// b is protected
// c is not accessible from PublicDerived
};

class ProtectedDerived: protected Base {


// a is protected
// b is protected
// c is not accessible from ProtectedDerived
};

class PrivateDerived: private Base {


// a is private
// b is private
// c is not accessible from PrivateDerived
}

Example: C++ Program to demonstrate the working of public inheritance


#include <iostream>
using namespace std;

class Base {
private:
int pvt ;

protected:
int prot ;
public:
int pub ;

Base () { pvt=1;prot=2;pub=3 } //constructor


// function to access private member
int getPVT() {
return pvt;
}
};

class PublicDerived : public Base {


public:
// function to access protected member from Base
int getProt() {
return prot;
}
};

int main() {
PublicDerived object1;
Cout<<” Not Accessible “; // cout << "Private = " << object1.getPVT() << endl; //getPVT() is not accessible
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.pub << endl;
return 0;
}
Output

Not Accessible

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 60

Protected = 2
Public = 3
Here, we have derived PublicDerived from Base in public mode.

As a result, in PublicDerived:
 prot is inherited as protected.
 pub and getPVT() are inherited as public.
 pvt is inaccessible since it is private in Base.

Since private and protected members are not accessible, we need to create public functions getPVT() and getProt() to
access them:

// Error: member "Base::pvt" is inaccessible


cout << "Private = " << object1.pvt;

// Error: member "Base::prot" is inaccessible


cout << "Protected = " << object1.prot;

Accessibility in Public Inheritance

Accessibility private members protected members public members

Base Class Yes Yes Yes

Derived Class No Yes Yes

Example: C++ Program to demonstrate the working of protected inheritance


#include <iostream>
#include <string>
using namespace std;
class Base {
private:
int pvt ;
protected:
int prot ;
public:
int pub ;

Base () { pvt=1;prot=2;pub=3 } //constructor


// function to access private member
int getPVT() {
return pvt;
}
};

class ProtectedDerived : protected Base {


public:
// function to access protected member from Base
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 61

int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};

int main() {
ProtectedDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Output

Private cannot be accessed.


Protected = 2
Public = 3
Here, we have derived ProtectedDerived from Base in protected mode.

As a result, in ProtectedDerived:
 prot, pub and getPVT() are inherited as protected.
 pvt is inaccessible since it is private in Base.
As we know, protected members cannot be accessed directly.

As a result, we cannot use getPVT() from ProtectedDerived. That is also why we need to create
the getPub() function in ProtectedDerived in order to access the pub variable.

// Error: member "Base::getPVT()" is inaccessible


cout << "Private = " << object1.getPVT();

// Error: member "Base::pub" is inaccessible


cout << "Public = " << object1.pub;

Accessibility in Protected Inheritance

private protected
Accessibility public members
members members

Base Class Yes Yes Yes

Derived Yes (inherited as protected


No Yes
Class variables)

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 62

Example: C++ Program to demonstrate the working of private inheritance


#include <iostream>
using namespace std;
class Base {
private:
int pvt ;
protected:
int prot ;
public:
int pub;
Base () { pvt=1;prot=2;pub=3 } //constructor
// function to access private member
int getPVT() {
return pvt;
}
};
class PrivateDerived : private Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member
int getPub() {
return pub;
}
};

int main() {
PrivateDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Output
Private cannot be accessed.
Protected = 2
Public = 3
Here, we have derived PrivateDerived from Base in private mode.

As a result, in PrivateDerived:
 prot, pub and getPVT() are inherited as private.
 pvt is inaccessible since it is private in Base.
As we know, private members cannot be accessed directly.

As a result, we cannot use getPVT() from PrivateDerived. That is also why we need to create
the getPub() function in PrivateDerived in order to access the pub variable.

// Error: member "Base::getPVT()" is inaccessible


cout << "Private = " << object1.getPVT();

// Error: member "Base::pub" is inaccessible


[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 63

cout << "Public = " << object1.pub;

Accessibility in Private Inheritance

private
Accessibility protected members public members
members

Base Class Yes Yes Yes

Derived Yes (inherited as private Yes (inherited as private


No
Class variables) variables)

Types of Inheritance
Based on number of ways inheriting the feature of base class into derived class it have five types they are:
 Single inheritance
 Multiple inheritance
 Hierarchical inheritance
 Multiple inheritance
 Hybrid inheritance
Single inheritance

In single inheritance there exists single base class and single derived class.

class A
{
... .. ...
};
class B: public A
{
... .. ...
};
Here, class B is derived from the base class A.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 64

Example: C++ Single Inheritance


#include <iostream>
using namespace std;
class A
{
public:
void display(){
cout<<"Base class A content.";
}
};
// sub class derived from base class
class B : public A
{
};

int main(){
B obj;
obj.display();
return 0;
}
Output
Base class A content.
In this program, class B is derived from class A. The obj object of class B is defined in the main() function.

When the display() function is called, display() in class A is executed. It's because there is no display() function in
class B.

The function also doesn't exist in class B, so the compiler looks for it in class A (as B is derived from A).
Example of Inheritance in C++
#include<iostream.h>
#include<conio.h>
class employee
{
public:
int salary;
};
class developer : public employee
{
employee e;
public:
void salary()
{
cout<<"Enter employee salary: ";
cin>>e.salary; // access base class data member
cout<<"Employee salary: "<<e.salary;
}

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 65

};

void main()
{
clrscr();
developer obj;
obj.salary();
getch();
}
Output

Enter employee salary: 50000


Employee salary: 50000

Multilevel inheritances
In multiple inheritances there exists single base class, single derived class and multiple intermediate base classes.
Single base class + single derived class + multiple intermediate base classes.
Intermediate base classes
An intermediate base class is one in one context with access derived class and in another context same class access base
class.

Hence all the above three inheritance types are supported by both classes and interfaces.

In multilevel inheritance, the derived class inherits property from another derived class.
For example, class B inherits from class A and class C inherits property from class B.

class A
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 66

{
... .. ...
};
class B: public A
{
... .. ...
};
class C: public B
{
... ... ...
};
Here, class B is derived from the base class A and the class C is derived from the derived class B.

Example : C++ Multilevel Inheritance

#include <iostream>
using namespace std;

class Animal
{
public:
Animal()
{
cout<<"This is a Animal.";
}
void display()
{
cout<<”Example of Multilevel inheritance”; }
};

class fourLegs : public Animal


{
public:
fourLegs()
{
cout<<"Objects with 4 legs are Animals.";
}
};

class Cow : public fourLegs


{
public:
Cow()
{
cout<<"Cow has 4 Legs.";
}
};

int main()
{
Cow obj;
obj.display();
return 0;
}

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 67

Output
This is a Animal.
Objects with 4 legs are Animals.
Cow has 4 Legs.
Multiple inheritance
In multiple inheritance there exist multiple classes and single derived class.

For example, as explained below, class Derived inherits property from both Class Base1 and Class Base2.

class A
{
... .. ...
};
class B: public A
{
... .. ...
};
class C: public A, public B
{
... .. ...
};
In C++ programming, a class can be derived from more than one parents. For example: A class Parrot is derived from
base classes Animal and Bird. It makes sense because Parrot is a Animal as well as a Bird.

Example : C++ Multiple Inheritance in C++ Programming


#include <string>
using namespace std;
// First base class
class Animal {
public:
Animal() {
cout << "Animals can Run." << endl;
}
};
// Second base class
class Bird {
public:
Bird() {
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 68

cout << "Birds can Fly." << endl;


} };
// sub class derived from two base classes
class Parrot: public Animal, public Bird {
};
int main(){
// creating object of sub class will invoke the constructor of base classes
Parrot b1;
return 0;
}
Output

Animals can Run.


Birds can Fly.

Ambiguity in Multiple Inheritance


The most obvious problem with multiple inheritance occurs during function overriding. Suppose, two base classes have a
same function which is not overridden in derived class.

If you try to call the function using the object of the derived class, compiler shows error. It's because compiler doesn't
know which function to call. For example,

class base1
{
public:
void someFunction( )
{ .... ... .... }
};
class base2
{
void someFunction( )
{ .... ... .... }
};
class derived : public base1, public base2
{

};

int main()
{
derived obj;

obj.someFunction() // Error!
}
This problem can be solved using scope resolution function to specify which function to class either base1 or base2.

int main()
{
obj.base1::someFunction( ); // Function of base1 class is called
obj.base2::someFunction(); // Function of base2 class is called.
}
Hybrid inheritance
Combination of any inheritance type . In hierarchical inheritance, more than one sub class is inherited from a single base
class. In this, all features that are common in child classes are included in the base class
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 69

For example: Football, Cricket, Badminton are derived from Sports class .

Syntax of Hierarchical Inheritance


class base_class {
... .. ...
}

class first_derived_class: public base_class {


... .. ...
}

class second_derived_class: public base_class {


... .. ...
}

Example: C++ Program to implement Hierarchical Inheritance


#include <iostream>
using namespace std;
// base class
class Animal
{
public:
Animal(){
cout<<"Animals Can Run.";
}
};
// First Sub class
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 70

class Dog : public Animal


{

};
// Second Sub class
class Cat : public Animal
{

};

int main(){
Cat obj1;
Dog obj;2
return 0;
}
Output

Animals Can Run.


Animals Can Run.

What is inherited from the base class?


In principle, a derived class inherits every member of a base class except:
 its constructor and its destructor
 its operator=() members
 its friends
Difference between Inheritance and Friendship in C++:
In C++, friendship is not inherited. If a base class has a friend function, then the function doesn’t become a friend of the
derived class(es).
In C++, the friendship is not inherited. It means that, if one parent class has some friend functions, then the child class will
not get them as friend.
In this example it will generate an error because the display() function is friend of MyBaseClass but not the friend of
MyDerivedClass. The display() can access the private member of MyBaseClass.

Example
#include <iostream>
using namespace std;
class MyBaseClass {
protected:
int x;
public:
MyBaseClass() {
x = 20;
}
friend void display();
};
class MyDerivedClass : public MyBaseClass {
private:
int y;
public:
MyDerivedClass() {
x = 40;
}

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 71

};
void display() {
MyDerivedClass derived;
cout << "The value of private member of Base class is: " << derived.x << endl;
cout << "The value of private member of Derived class is: " << derived.y << endl;
}
main() {
display();
}
Output
[Error] 'int MyDerivedClass::y' is private
[Error] within this context
Virtual base class in C++ OOP
What is the Diamond Problem?
When we inherit more than one base class in the same derived class and all these base classes also inherit another but same
single class (super parent), multiple references of the super parent class become available to the derived class.

So, it becomes unclear to the derived class, which version of the super parent class it should refer to.

What is a Virtual base class?


The virtual base class is very helpful in virtual inheritance. When we use multiple inheritances, then multiple “instances”
of a given class appearing in an inheritance hierarchy. It leads to redundancy. Redundancy is not good in such a scenario.
When we declare a class as a virtual class, then it means that we are helping the compiler that we only required a single
instance.

Why we use a virtual base class?


Virtual base class means that child classes can access the base classes virtually from a long distance in the parent-child
hierarchy.

How to declare a class as a virtual base class?


class A {
public:
int number;
A()
{
int number = 10;
}
};
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C{};
Explanation of Diagrams
Class A: Base Parent Class
Class B: B is child class of class A.
Class C: C is a child class of class A.
Class D: D is a child class of class B and Class C. A is the grandfather of class D.
Step 1:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 72

1. Create class A
2. declare the variable “int number” inside class A.
3. Class C and Class B get the “int number” variable from class A.
4. Class D is getting the “int number” from both class B, and Class C. This is not good to do.

We must avoid this redundancy and never inherit the same member(e.g int number) from multiple parent classes .

The solution to solve the above-mentioned problem is to make the parent base class a virtual class.
Here, Class D is getting the “int number” directly from the parent base virtual class.

C++ Program of Virtual base class


Let us code the above-mentioned scenario with C++.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 73

#include <iostream>
using namespace std;
class A {
public:
int number;
A() // constructor
{
number = 10;
}
};
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C{};
int main()
{
D object; // object is created for class d
cout << "number = " << object.number << endl;
return 0;
}
Output
number=10

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 74

Example 2 with error


#include <iostream>
using namespace std;
class ONE {
public: int n1;
};

Class TWO : public ONE {


public: int n2;
};

class THREE : public ONE {


public: int n3;
};

class FOUR : public TWO, public THREE {


public: int n4;
};
int main() {
FOUR obj;
obj.n1 = 40; //error
obj.n1 = 30; // error
obj.n2 = 60;
obj.n3 = 70;
obj.n4 = 80;
cout<< " Object ONE : "<< obj.n1 // error
cout<< " Object TWO : "<< obj.n2;
cout<< " Object THREE: "<< obj.n3;
cout<< " Object FOUR: "<< obj.n4;
}
Example 2 without error
#include <iostream>
using namespace std;
class ONE {
public: int n1;
};
class TWO : virtual public ONE {
public: int n2;
};

class THREE : virtual public ONE {


public: int n3;
};
class FOUR : public TWO, public THREE {
public: int n4;
};
int main() {
FOUR obj;
obj.n1 = 40;
obj.n1 = 30;
obj.n2 = 60;
obj.n3 = 70;
obj.n4 = 80;
cout<< " Object ONE : "<< obj.n1;
cout<< " Object TWO : "<< obj.n2;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 75

cout<< " Object THREE: "<< obj.n3;


cout<< " Object FOUR: "<< obj.n4;
}
Virtual Destructor in C++
A destructor in C++ is a member function of a class used to free the space occupied by or delete an object of the class
that goes out of scope. A destructor has the same name as the name of the constructor function in a class, but the destructor
uses a tilde (~) sign before its function name.

Virtual Destructor
A virtual destructor is used to free up the memory space allocated by the derived class object or instance while deleting
instances of the derived class using a base class pointer object. A base or parent class destructor use the virtual keyword
that ensures both base class and the derived class destructor will be called at run time, but it called the derived class first
and then base class to release the space occupied by both destructors.

Why we use virtual destructor in C++?


When an object in the class goes out of scope or the execution of the main() function is about to end, a destructor is
automatically called into the program to free up the space occupied by the class' destructor function. When a pointer object
of the base class is deleted that points to the derived class, only the parent class destructor is called due to the early bind by
the compiler. In this way, it skips calling the derived class' destructor, which leads to memory leaks issue in the program.
And when we use virtual keyword preceded by the destructor tilde (~) sign inside the base class, it guarantees that first the
derived class' destructor is called. Then the base class' destructor is called to release the space occupied by both destructors
in the inheritance class.

Example: Write a program to display a class destructor's undefined behaviour without


using a virtual destructor in C ++.
#include<iostream>
using namespace std;
class Base
{
public: /* A public access specifier defines Constructor and Destructor function to call by any object in the class. */
Base() // Constructor function.
{
cout<< "\n Constructor Base class";
}
~Base() // Destructor function
{
cout<< "\n Destructor Base class";
}
};

class Derived: public Base


{
public: /* A public access specifier defines Constructor and Destructor function to call by any object in the class. */
Derived() // Constructor function
{
cout << "\n Constructor Derived class" ;
}
~Derived() // Destructor function
{
cout << "\n Destructor Derived class" ; /* Destructor function is not called to release its space. */
}
};
int main()
{
Base *bptr = new Derived; // Create a base class pointer object
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 76

delete bptr; /* Here pointer object is called to delete the space occupied by the destructor.*/
}

Output:

As we can see in the above output, when the compiler compiles the code, it calls a pointer object in the main function that
refers to the base class. So, it executes the base class' constructor() function and then moves to the derived class'
constructor() function. After that, it deletes the pointer object occupied by the base class' destructor and the derived class'
destructor. The base class pointer only removes the base class's destructor without calling the derived class' destructor in
the program. Hence, it leaks the memory in the program.

Note: If the base class destructor does not use a virtual keyword, only the base class destructor will be called or deleted its
occupied space because the pointer object is pointing to the base class. So it does not call the derived class destructor to
free the memory used by the derived class, which leads to memory leak for the derived class.

Example: Write a program to display a class destructor's behavior using a virtual


destructor in C ++.
#include<iostream>
using namespace std;
class Base
{
public:
Base() // Constructor member function.
{
cout << "\n Constructor Base class"; // It prints first.
}
virtual ~Base() // Define the virtual destructor function to call the Destructor Derived function.
{
cout << "\n Destructor Base class"; /
}
};
// Inheritance concept
class Derived: public Base
{
public:
Derived() // Constructor function.
{
cout << "\n Constructor Derived class" ; /* After print the Constructor Base, now it will prints. */
}
~Derived() // Destructor function
{
cout << "\n Destructor Derived class"; /* The virtual Base Class? Destructor calls it before calling the Base Class Destructor. */
}
};
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 77

int main()
{
Base *bptr = new Derived; // A pointer object reference the Base class.
delete bptr; // Delete the pointer object.
}

Output:

In the above program, we have used a virtual destructor inside the base class that calls the derived class' destructor before
calling the base class' destructor and release the spaces or resolve the memory leak issue in the program.

Inheritance and Static Functions in C++


1. They are inherited into the derived class.
2. If you redefine a static member function in derived class, all the other overloaded functions in base class are
hidden.
3. Static Member functions can never be virtual

Abstraction in C++
Real Life Example of Abstraction in C++
Abstraction is the concept of exposing only the required essential characteristics and behavior with respect to a
context.
Hiding of data is known as data abstraction. In object oriented programming language this is implemented
automatically while writing the code in the form of class and object.

Abstraction is one of the feature of Object Oriented Programming, where you show only relevant details to the user
and hide irrelevant details. You can understand with this example, when you send an email to someone you just click
send and you get the success message, what actually happens when you click send, how data is transmitted over
network to the recipient is hidden from you (because it is irrelevant to you).

1. Real life example of Abstraction in C++


Abstraction shows only important things to the user and hides the internal details for example when we ride a bick, we
only know about how to ride bick but can not know about how it work ? and also we do not know internal functionality
of bick.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 78

2. Real life example of Abstraction in C++


Consider a real life example of a man driving a car. The man only knows that pressing the accelerators will increase
the speed of car or applying brakes will stop the car but he does not know about how on pressing accelerator the speed
is actually increasing, he does not know about the inner mechanism of the car or the implementation of accelerator,
brakes etc in the car.
3. Real life example of Abstraction in C++
Suppose you are operating a mobile phone. You know that the important feature of a phone is the memory card, SIM,
battery life, design and build, and processor power. But, while operating the phone you do not get into the operational
details of the phone such as how the CPU of the phone allocates memory for the various media on your phone or other
intricate architectural details of the phone. All these details aren’t visible to cell-phone users from a non-technical
background.

Example of Abstraction in C++


#include<iostream.h>
#include<conio.h>
class sum
{
// hidden data from outside world
private: int a,b,c;
public:
void add()
{
clrscr();
cout<<"Enter any two numbers: ";
cin>>a>>b;
c=a+b;
cout<<"Sum: "<<c;
}
};

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 79

void main()
{
sum s;
s.add();
getch();
}
Output
Enter any two number:
4
5
Sum: 9

Note: Data abstraction can be used to provide security for the data from the unauthorized methods.
Note: Note: In C++ language data abstraction can be achieved by using class.

Difference between Abstraction and Encapsulation


Abstraction deals with hiding the details and showing the essential things to the user whereas encapsulation bind your
data and code together as a single unit.

Encapsulation is not providing full security because we can access private member of the class using reflection API,
but in case of Abstraction we can't access static, abstract data member of a class.

Advantages of Data Abstraction in C++


Here we discuss some of its benefits in order to acknowledge its significance. The benefits of data abstraction are given
below;

 Data abstraction increases the reusability of the code by avoiding any chances of redundancy.
 It increases the readability of the code as it eliminates the possibility of displaying the complex
working of the code.
 With the implementation of classes and objects, comes enhanced security. Since data abstraction is
a method of implementing classes and objects any denying access to other classes of accessing the
data members and member functions of the base class.
 It helps the user to write a high-level code.
 It separates the entire program into code and implementation making it more comprehensible.
 Helps the user to avoid writing the low level code.
 Avoids code duplication and increases reusability.
 Can change internal implementation of class independently without affecting the user.
 Helps to increase security of an application or program as only important details are provided to the
user.

Implementation of Abstraction
Below we discuss about some way to Implement Abstraction.

Abstraction using Classes: We can implement Abstraction in C++ using classes. Class helps us to group data
members and member functions using available access specifiers. A Class can decide which data member will be
visible to outside world and which is not.
Abstraction in Header files: One more type of abstraction in C++ can be header files. For example, consider the
pow() method present in math.h header file. Whenever we need to calculate power of a number, we simply call the
function pow() present in the math.h header file and pass the numbers as arguments without knowing the underlying
algorithm according to which the function is actually calculating power of numbers.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 80

Abstraction using access specifiers: Access specifiers are the main pillar of implementing abstraction in C++. We
can use access specifiers to enforce restrictions on class members.
For example;
 Members declared as public in a class, can be accessed from anywhere in the program.
 Members declared as private in a class, can be accessed only from within the class. They are not
allowed to be accessed from any part of code outside the class.

Designing Strategy of Abstraction


Abstraction separates code into interface and implementation. So while designing your component, you must keep
interface independent of the implementation so that if you change underlying implementation then interface would
remain intact.

In this case whatever programs are using these interfaces, they would not be impacted and would just need a
recompilation with the latest implementation.

Encapsulation in C++

Real Life Example of Encapsulation in C++


Encapsulation is a process of wrapping of data and methods in a single unit. It is achieved in C++ language by class
concept.
Combining of state and behavior in a single container is known as encapsulation. In C++ language encapsulation can
be achieve using class keyword, state represents declaration of variables on attributes and behavior represents
operations in terms of method.

Syntax of Encapsulation in C++


Syntax of Encapsulation in C++
class class name
{
private:
datatype data;
public:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 81

Member functions;
};

main()
{
classname objectname1,objectname2……………;
}

Real Life Example of Encapsulation in C++

The common example of encapsulation is Capsule. In capsule all medicine are encapsulated in side capsule.

Automatic Cola Vending Machine: Suppose you go to an automatic cola vending machine and request for a cola.

The machine processes your request and gives the cola.

Here automatic cola vending machine is a class. It contains both data i.e. Cola can and operations i.e. service
mechanism and they are wrapped/integrated under a single unit Cola Vending Machine. This is called Encapsulation.

A Washing Machine and It's Power Button: What is the function that power button does? Switches the machine on
(obviously). But did u ever imagined the inside mechanism. Doesn't matter unless it's functioning well. That's
encapsulation. The object is wrapped and inner details are hidden. Only thing is that object can be called and used.
User friendly!
You can't access private date outside the class.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 82

Benefits of encapsulation
 Provides abstraction between an object and its clients.
 Protects an object from unwanted access by clients.
 Example: A bank application forbids a client to change an Account's balance.
Example of Encapsulation in C++
#include<iostream.h>
#include<conio.h>
class sum
{
private: int a,b,c;
public:
void add()
{
clrscr();
cout<<"Enter any two numbers: ";
cin>>a>>b;
c=a+b;
cout<<"Sum: "<<c;
}
};
void main()
{
sum s;
s.add();
getch();
}

Output

Enter any two number:


4
5
Sum: 9

In above example all data and function are bind inside class sum.

Role of Access Specifiers in Encapsulation


Access specifiers play an important role in implementing encapsulation in C++. The process of implementing
encapsulation can be sub-divided into two steps:

 The data members should be labeled as private using the private access specifiers.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 83

 The member function which manipulates the data members should be labeled as public using the
public access specifier.

How Encapsulation is achieved in a class


 Make all the data members private.
 Create public setter and getter functions for each data member in such a way that the set function
set the value of data member and get function get the value of data member.

Advantage of Encapsulation in C++


 The main advantage of using of encapsulation is to secure the data from other methods, when we
make a data private then these data only use within the class, but these data not accessible outside
the class.
 The major benefit of data encapsulation is the security of the data. It protects the data from
unauthorized users that we inferred from the above stated real-real problem.
 We can apply the concept of data encapsulation in the marketing and finance sector where there is a
high demand for security and restricted access of data to various departments.
 Encapsulation helps us in binding the data(instance variables) and the member functions(that work
on the instance variables) of a class.
 Encapsulation is also useful in hiding the data(instance variables) of a class from an illegal direct
access.
 Encapsulation also helps us to make a flexible code which is easy to change and maintain.
Dis-Advantage of Encapsulation in C++
You can't access private date outside the class.
Designing Strategy of Encapsulation in C++
Most of us have learnt to make class members private by default unless we really need to expose them. That's just good
encapsulation. This is applied most frequently to data members, but it applies equally to all members, including virtual
functions.

Association
In object-oriented general software design, the relationship between one object's functionality and another's is known as an
association. Note that an association between two objects is not the same thing as inheritance between two classes.
Association means that one object uses another object or a function/method in that other object. In other words,
association is defined as the relationship between objects when one object has one or more references to other objects.

Below are the core differences between association and inheritance:

 Inheritance implies that two objects are the same type of object. One object just happens to be either a more
generalized or more specific version of the other object. Association occurs between two different objects.
 Inheritance is said to be an IS-A relationship whereas association is known as a HAS-A relationship.
 The modality of inheritance depends on the programming language features. For example, Java does not support
multiple inheritance, but C++ does. On the other hand, any language can have one-to-one, one-to-many, and
many-to-many associations between objects.
There are two types of associations between objects: composition and aggregation.

C++ Composition
C++ Composition- In real-life complex objects are often built from smaller and simpler objects. For example, a car is
built using a metal frame, an engine some tires, a transmission system, a steering wheel, and a large number of other parts.
A personal computer is built from a CPU, a motherboard, memory unit, input and output units, etc. even human beings are

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 84

building from smaller parts such as a head, a body, legs, arms, and so on. This process of building complex objects from
simpler ones is called c++ composition. It is also known as object composition.

So far, all of the classes that we have used had member variables that are built-in data type (e.g. int, float, double, char).
While this is generally sufficient for designing and implementing small, simple classes, but it gradually becomes difficult
to carry out from more complex classes, especially for those built from many sub-parts. In order to facilitate the building
of complex classes from simpler ones, C++ allows us to do object C++ Composition in a very simple way by using classes
as member variables in other classes.
A class can have one or more objects of other classes as members. A class is written in such a way that the object of
another existing class becomes a member of the new class. this relationship between classes is known as C++
Composition. It is also known as containment, part-whole or has-a relationship. A common form of software reusability
is C++ Composition.
In C++ Composition, an object is a part of another object. The object that is a part of another object is known as a sub-
object. When a C++ Composition is destroyed, then all of its sub-objects are destroyed as well.
In other word In this type of relationship, parts of an object are completely dependent on it. This means that the objects
would not have any existence without the object. If we destroy the object, then these parts would immediately get
destroyed too. They make up an object and are vital for it. Here objects depend on each other. This means that the
existence of one is impossible without others
Example Such as when a car is destroyed, then its motor, frame, and other parts are also destroyed with it. It has a do and
die relationship.
Another example of real-life is Our Body and Blood. Blood resides inside a body. This means that blood is a part of the
body. Blood is useless if it is not inside a body. Blood present outside the body as no importance.
Program example: how to use C++ Composition in programming:
#include <iostream>
using namespace std;
class X
{
private:
int d;
public:
void set_value(int k)
{
d=k;
}

void show_sum(int n)
{
cout<<"sum of "<<d<<" and "<<n<<" = "<<d+n<<endl;

} };
class Y
{
public:
X a;
void print_result()
{
a.show_sum(5);

};

int main()
{
Y b;

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 85

b.a.set_value(20);
b.a.show_sum(100);
b.print_result();

Explanation:
In this program, class X has one data member ‘d’ and two member functions ‘set_value()’ and ‘show_sum()’. The
set_value() function is used to assign value to ‘d’. the show_sum() function uses an integer type parameter. It adds the
value of parameter with the value of ‘d’ and displays the result o the screen.
Another class Y is defined after the class x. the class Y has an object of class x that is the C++ Composition relationship
between classes x and y. this class has its own member function print_result().
In the main() function, an object ‘b’ of class y is created. The member function set_value() of object ‘a’ that is the sub-
object of object ‘b’ is called by using two dot operators. One dot operator is used to access the member of the object ‘b’
that is object ‘a’, and second is used to access the member function set_value() of sub-object ‘a’ and ‘d’ is assigned a
value 20.
In the same way, the show_sum() member function is called by using two dot operators. The value 100 is also passed as a
parameter. The member function print_result of object ‘b’ of class Y is also called for execution. In the body of this
function, the show_sum() function of object ‘a’ of class X is called for execution by passing value 5.

C++ Aggregation
Aggregation is a type of association that is used to represent the “HAS-A” relationship between two objects. This is a
subclass for a relation type association. Where the association is loosely coupled that exists between two classes where a
relation exists, but aggregation restricts some situations of associations. This type of relation is like a whole/Part
relationship type where one class owns another class thus one class object is a part of another class object. But the lifetime
of a part class does not depend on the lifetime of the whole class neither whole class can exist without an object of part
class.
For Example – There are two classes Address and Person, Each Person has an address.
Aggregation is a way to represent HAS-A relation between the objects of 2 individual classes.. It is a subtype of
association type of relation but more restrictive.
Class PartClass{
//instance variables
//instance methods
}
class Whole{
PartClass* partclass;
}
Explanation: In the above syntax, the Whole class represents the class that is a container class for other Part class that is
contained in the object of the whole class. Here each object of Whole class holds a reference pointer to the object of the
Part class.

For example – BUS HAS-A Engine. Here Bus is a container class. Part class is a class whose object is contained within
the objects of a container class. An object of the Part class can be referred in more than 1 object of Whole class and also a
lifetime of a contained class object does not depend on the lifetime of the existence of the object of a container class.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 86

How does Aggregation work in C++?


Aggregation is a relation type that helps to represent Has-A relation between objects of 2 individual classes in the
program. It is a sub-form of association relation and is more restrictive as compared to the association. It helps to make our
code more readable and understandable to represent the relation in the programming language, in the same manner, it is
explained in our day to day lives.

Here object of one class is referred to using a pointer variable present in the container class object.

Example: Person has Address is represented using two classes Person and Address. Since as we can see, Address has a
Person is meaningless thus Person is container class and Address is a class whose object is contained within the container
class object.
Here we can also see, the lifetime of an object of address class does not depend on the lifetime of the object of Person
class. Thus objects are not tightly coupled. Also, one address can easily be associated with more than a Person since more
than 1 person can live on the same address. Thus the object of address class can be associated with more than one object of
Person class.
In this way, one can easily establish HAS-A relation between objects of 2 classes.
Example of C++ Aggregation Let us try to illustrate the implementation of the aggregation type of relation
between 2 classes Person and address using a C++ program.
#include <iostream>
#include<string.h>
using namespace std;
class Address {
public:
int houseNo;
string colony,city, province;
Address(inthno, string colony, string city, string province)
{
this->houseNo = hno;
this->colony=colony;
this->city = city;
this->province = province;
}
};
class Person
{
private:
Address* address;
public:
string name;
Person(string name, Address* address)
{
this->name = name;
this->address = address;
}
void display()
{
cout<< name<< " "<< " "<< address->houseNo<<" "<<address-> colony<<" " <<address->city<< " "<<address-
>state<<endl;
}
};
int main(void) {
Address add1= Address(868 ,"housing Colony","Lahore","Punjab");
Person p1 = Person("Ali",&add1);
Person p2 = Person("Seema",&add1);

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 87

p1.display();
p2.display();
return 0;
}

Output:
Ali 868 housing colony Lahore Punjab
seema 868 housing colony Lahore punjab
Explanation: Here Person has instance variable name which tells the name of the person and a pointer variable to
address class object. Address class object has variables such as House, street, city, and province. Here we have 2 persons
Ali and Seema living on the same address thus share the same address object add1.

Advantages of C++ Aggregation

1. Aggregation helps establishing a relation between objects of 2 individual classes where one is Whole class and
the other is a part class. It is used to code ‘HAS-A’ relation between objects of two classes where once object of
the part class can be associated with more than 1 object of Whole class and does not have existence dependency
on it.
2. This type of relation is a special form of relation named as association where objects does not have any
dependency on each other and show bidirectional relation between objects of different classes.
3. Aggregation type of relation represents uni-directional relation between objects of 2 classes like car and garage
where car is a part of garage same car can be parked in any other garage as well. Thus defines its one direction
relation.
4. It also helps to improve the reusability of the code. Once objects have been created, any Whole class object is
capable of holding a reference to the object of any of the Part class.
5. It also helps to improve the readability of the code as the relation between 2 classes can be made more
understandable once it is in the form of HAS-A relation the same we interpret them in our day to day life. such as
Bus HAS-A Engine and Department HAS-A Teacher.

Polymorphism in C++
Real Life Example of Polymorphism in C++
The process of representing one Form in multiple forms is known as Polymorphism. Here one form represent original
form or original method always resides in base class and multiple forms represents overridden method which resides in
derived classes.
Polymorphism is derived from 2 greek words: poly and morphs. The word "poly" means many and morphs means
forms. So polymorphism means many forms.
Polymorphism is an important concept of object-oriented programming. It simply means more than one form. That is,
the same entity (function or operator) behaves differently in different scenarios

Real life example of Polymorphism in C++


Suppose if you are in class room that time you behave like a student, when you are in market at that time you behave
like a customer, when you at your home at that time you behave like a son or daughter, Here one person have different-
different behaviors. So the same person posses different behavior in different situations.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 88

For example:- The + operator in C++ is used to perform two specific functions. When it is used with numbers
(integers and floating-point numbers), it performs addition.

int a = 5;
int b = 6;
int sum = a + b; // sum = 11
And when we use the + operator with strings, it performs string concatenation. For example,

string firstName = "Naeem ";


string lastName = Khalil";

// name = "Naeem Khalil"


string name = firstName + lastName;

Type of polymorphism

 Compile time polymorphism: This type of polymorphism is also referred to as static binding or early
binding. It takes place during compilation. We use function overloading and operator overloading to achieve
compile-time polymorphism.
 Run time polymorphism: Run-time polymorphism takes place when functions are invoked during run
time. It is also known as dynamic binding or late binding. Function overriding and virtual functions are used to
achieve run-time polymorphism.

Method Overloading in C++


Whenever same method name is exiting multiple times in the same class with different number of parameter or
different order of parameters or different types of parameters is known as method overloading. In below example
method "sum()" is present in Addition class with same name but with different signature or arguments.
Example of Method Overloading in C++
#include<iostream.h>
#include<conio.h>

class Addition
{
public:
void sum(int a, int b)
{

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 89

cout<<a+b;
}
void sum(int a, int b, int c)
{
cout<<a+b+c;
}
};
void main()
{
clrscr();
Addition obj;
obj.sum(10, 20);
cout<<endl;
obj.sum(10, 20, 30);
}
Output
30
60
It's a compile-time polymorphism because the compiler knows which function to execute before the program is
compiled. An overloaded function is called based on the number and type of parameters passed. Thus, the compiler picks
the correct function during compilation of the program.

C++ Operator Overloading


In C++, we can overload an operator as long as we are operating on user-defined types like objects or structures. We
cannot use operator overloading for basic types such as int, double, etc.
Operator overloading is basically function overloading, where different operator functions have the same symbol but
different operands. And, depending on the operands, different operator functions are executed.

Example 2: C++ program to overload ++ when used as prefix


#include <string>
using namespace std;
class Count {
private:
int value;

public:
// Constructor to initialize count to 2
Count() : value(2) {}

// Overload ++ when used as prefix


void operator ++() {
value = value + 2;
}
void display() {
cout << "Count: " << value << endl;
}
};

int main() {
Count cnt1;
// Call the "void operator ++()" function
++cnt1;

cnt1.display();
return 0;
}
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 90

Output
Count: 4
It is also a compile-time polymorphism because the compiler knows which function to execute before the program is
compiled

Run Time Polymorphism


Method Overriding in C++
In C++ inheritance, we can have the same function in the base class as well as its derived classes . Define any method in
both base class and derived class with same name, same parameters or signature, this concept is known as method
overriding. in other word, When a member function of a base class is redefined in its derived class with the same
parameters and return type, it is called function overriding in C++.The base class function is said to be overridden. In
below example same method "show()" is present in both base and derived class with same name and signature.

Example of Method Overriding in C++


#include<iostream.h>
#include<conio.h>
class Base
{
public:
void show()
{
cout<<"Base class";
}
};
class Derived:public Base
{
public:
void show()
{
cout<<"Derived Class";
}
}

int mian()
{
Base b; //Base class object
Derived d; //Derived class object
b.show(); //Early Binding Ocuurs
d.show();
getch();
}
Output
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 91

Base class
Derived Class

It's a runtime polymorphism because the function call is not resolved by the compiler, but it is resolved in the runtime

instead.
Virtual Function in C++
A virtual function is a member function of class that is declared within a base class and re-defined in
derived class. The classes that have virtual functions are called polymorphic classes.
When you want to use same function name in both the base and derived class, then the function in base class
is declared as virtual by using the virtual keyword and again re-defined this function in derived class without
using virtual keyword.
o It is used to tell the compiler to perform dynamic linkage or late binding on the function. The compiler
binds virtual function at runtime, hence called runtime polymorphism. Use of virtual function allows
the program to decide at runtime which function is to be called based on the type of the object pointed
by the pointer.
o There is a necessity to use the single pointer to refer to all the objects of the different classes. So, we
create the pointer to the base class that refers to all the derived objects. But, when base class pointer
contains the address of the derived class object, always executes the base class function. This issue
can only be resolved by using the 'virtual' function.
o When the function is made virtual, C++ determines which function is to be invoked at the runtime
based on the type of the object pointed by the base class pointer.

Late binding or Dynamic linkage


In late binding function call is resolved during runtime. Therefore compiler determines the type of object at
runtime, and then binds the function call.
Rules of Virtual Function
 Virtual functions must be members of some class.
 Virtual functions cannot be static members.
 They are accessed through object pointers.
 They can be a friend of another class.
 A virtual function must be defined in the base class, even though it is not used.
 The prototypes of a virtual function of the base class and all the derived classes must be identical. If
the two functions with the same name but different prototypes, C++ will consider them as the
overloaded functions.
 We cannot have a virtual constructor, but we can have a virtual destructor

Consider the situation when we don't use the virtual keyword.


Syntax

virtual return_type function_name()


{
.......
.......
}
Virtual Function Example

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 92

#include<iostream.h>
#include<conio.h>

class A
{
public:
virtual void show()
{
cout<<"Hello base class";
}
};

class B : public A
{
public:
void show()
{
cout<<"Hello derive class";
}
};

void main()
{
Clrscr();
A aobj;
B bobj;
A *bptr;
bptr=&aobj;
bptr->show(); // call base class function

bptr=&bobj;
bptr->show(); // call derive class function
getch();
}
Output
Hello base class
Hello derive class
Why do we need virtual functions?
Virtual functions are needed for many reasons, among them to eliminate ambiguity is one.
Example
#include <iostream>
using namespace std;
class A
{
int ;
public:
A() { x=5; } // constructor
void display()
{
cout << "Value of x is : " << x<<endl;
}
};

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 93

class B: public A
{
int y ;
public:
B() { y=10;}; //constructor
void display()
{
cout << "Value of y is : " <<y<< endl;
}
};
int main()
{
A *a;
B b;
a = &b;
a->display();
return 0;
}
Output:

Value of x is : 5

In the above example, * a is the base class pointer. The pointer can only access the base class members but
not the members of the derived class. Although C++ permits the base pointer to point to any object derived
from the base class, it cannot directly access the members of the derived class. Therefore, there is a need
for virtual function which allows the base pointer to access the members of the derived class.

Let’s make it more clear with this example and know when and why we need to use virtual
functions.

#include <iostream>
using namespace std;

class Animal
{
public:
void my_features()
{
cout << "I am an animal.";
}
};

class Mammal : public Animal


{
public:
void my_features()
{
cout << "\nI am a mammal.";
}
};
class Reptile : public Animal
{
public:
void my_features()

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 94

{
cout << "\nI am a reptile.";
}
};

int main()
{
Animal *obj1 = new Animal;
Mammal *obj2 = new Mammal;
Reptile *obj3 = new Reptile;

obj1->my_features();
obj2->my_features();
obj3->my_features();

return 0;
}
Output
I am an animal.
I am a mammal.
I am a reptile.

We created a three pointer objects *obj1, *obj2 and *obj3. And when we call
function my_features() using these pointer objects, the corresponding functions of the classes are
executed.

Now, what if we created an intermediate function to which we can pass objects of the corresponding class
to invoke functions. This should also do the same.

#include <iostream>
using namespace std;

class Animal
{
public:
void my_features()
{
cout << "I am an animal.";
}
};

class Mammal : public Animal


{
public:
void my_features()
{
cout << "\nI am a mammal.";
}
};
class Reptile : public Animal
{
public:
void my_features()
{
cout << "\nI am a reptile.";
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 95

}
};

//intermediate function
void intermediate_func(Animal *a1)
{
a1->my_features();
}

int main()
{
Animal *obj1 = new Animal;
Mammal *obj2 = new Mammal;
Reptile *obj3 = new Reptile;

intermediate_func(obj1);
intermediate_func(obj2);
intermediate_func(obj3);

return 0;
}
Output
I am an animal.
I am an animal.
I am an animal.
So let’s decode what went wrong and how it went that way. We created an intermediate function
intemediate_func which takes an object as the argument. And depending on the class pointed by that
object it invokes the member function of that class or at least we expected that way.
We supplied objects of Mammal and Reptile class to the intermediate function, which in return should
have invoked obj2->my_features() and obj3->my_features(). But that didn’t happen because of the
ambiguous situation aroused where compiler only invoked base class functions in all three situations.
So to overcome such ambiguity, virtual functions are used in base class. Virtual function dynamically
binds function call at runtime and allows it to be overridden by the member function of the derrived class.
Here is how a virtual function implemented in c++.
#include <iostream>
using namespace std;

class Animal
{
public:
virtual void my_features()
{
cout << "I am an animal.";
}
};

class Mammal : public Animal


{
public:
void my_features()
{
cout << "\nI am a mammal.";
}
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 96

};
class Reptile : public Animal
{
public:
void my_features()
{
cout << "\nI am a reptile.";
}
};

//intermediate function
void intermediate_func(Animal *a1)
{
a1->my_features();
}

int main()
{
Animal *obj1 = new Animal;
Mammal *obj2 = new Mammal;
Reptile *obj3 = new Reptile;

intermediate_func(obj1);
intermediate_func(obj2);
intermediate_func(obj3);

return 0;
}
Output
I am an animal.
I am a mammal.
I am a reptile.
Example of run-time polymorphism using two derived classes
#include <iostream>
using namespace std;
class Polygon {
public:
virtual void show() {
cout<<"Its a polygon"<<endl;
}
};
class Triangle : public Polygon {
public:
void show() {
cout<<"Triangle is 3 sided polygon"<<endl;
}
};
class Rectangle : public Polygon {
public:
void show() {
cout<<"Rectangle is 4 sided polygon"<<endl;
}
};
int main() {
Polygon *p;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 97

Triangle t;
Rectangle r;
p = &t;
p->show();
p = &r;
p->show();
return 0;
}
Output
Triangle is 3 sided polygon
Rectangle is 4 sided polygon
Run-time Polymorphism with Data Members
Run-time polymorphism can also be achieved through data members.
Example of run-time polymorphism with data members

#include <iostream>
#include <string>
using namespace std;
class Animal {
public:
string name = "Animal";
};
class Dog : public Animal {
public:
string name = "Dog";
};
int main() {
Dog d;
cout<<d.name;
return 0;
}
Output
Dog

Why Polymorphism?
Polymorphism allows us to create consistent code. For example,
Suppose we need to calculate the area of a circle and a square. To do so, we can create a Shape class and derive two
classes Circle and Square from it.
In this case, it makes sense to create a function having the same name calculateArea() in both the derived classes rather
than creating functions with different names, thus making our code more consistent

Upcasting and Downcasting in C++


Upcasting and down-casting are an important part of C++. Upcasting and downcasting give a possibility to build
complicated programs with a simple syntax. It can be achieved by using Polymorphism.
C++ allows that a derived class pointer (or reference) to be treated as a base class pointer. This is upcasting.
Downcasting is an opposite process, which consists of converting base class pointer (or reference) to derived class pointer.
C++ Upcasting and Downcasting should not be understood as a simple casting of different data types. It can lead to great
confusion.
In this topic, we will use the following hierarchy of classes:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 98

As you can see, Manager and Clerk are both Employee. They are both Person too. What does it mean? It means that
Manager and Clerk classes inherit properties of Employee class, which inherits properties of Person class.

Both up-casting and down casting do not change the object by itself. When you use up-casting or down-casting you just
“label” an object in different ways.

UPCASTING
Upcasting is a process of creating a pointer or a reference of the derived class object as a base class pointer. You do not
need to upcast manually. You just need to assign derived class pointer (or reference) to base class pointer:
Upcasting is using the Super class's reference or pointer to refer to a Sub class's object. Or we can say that, the act of
converting a Sub class's reference or pointer into its Super class's reference or pointer is called Upcasting.

In other words, upcasting allows us to treat a derived type as though it were its base type. It is always allowed
for public inheritance, without an explicit type cast. This is a result of the is-a relationship between the base and derived
classes.
The derived class can inherit all the base class properties that include data members and the member function to execute
the function using the derived class object, as we do with a base object.

#include <iostream>
using namespace std;
class Base
{

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 99

public:
void disp()
{
cout << " It is the Super function of the Base class ";
}
};

class derive : public Base


{
public:
void disp()
{
cout << "\n It is the derive class function ";
}

};

int main ()
{
// create base class pointer
Base *ptr;

derive obj; // create object of derive class


ptr = &obj; // assign the obj address to ptr variable
// create base class's reference
Base &ref = obj;
// Or
// get disp() function using pointer variable
ptr->disp();
return 0;
}
Output
It is the Super function of the Base class

DOWNCASTING
Downcasting is an opposite process for upcasting. It converts base class pointer to derived class pointer. Downcasting
must be done manually. It means that you have to specify explicit typecast.
The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add
new data members, and the class member functions that used these data members wouldn't apply to the base class.
Downcasting is not as safe as upcasting. You know that a derived class object can be always treated as a base class object.
However, the opposite is not right. For example, a Manager is always a Person; But a Person is not always a Manager. It
could be a Clerk too.

Child *pChild = &parent; // actually this won't compile


/ / error: cannot convert from 'Parent *' to 'Child *'
Example Downcasting
#include <iostream>
using namespace std;
class Parent
{
public:
void base()
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 100

{
cout << " It is the function of the Parent class "<< endl;
}
};

class Child : public Parent


{
public:
void derive()
{
cout << " it is the function of the Child class " <<endl;
}
};

int main ()
{
Parent pobj; // create Parent's object
Child *cobj; // create Child's object

// explicit type cast is required in downcasting


cobj = (Child *) &pobj;
cobj -> derive();

return 0;
}
Output
It is the function of the Child class

Dynamic Casting
The dynamic_cast operator answers the question of whether we can safely assign the address of an object to a pointer
of a particular type.
Here is example to the previous one.
#include <string>

class Parent {
public:
void sleep() {
}
};

class Child: public Parent {


private:
std::string classes[10];
public:
void gotoSchool(){}
};

int main( )
{
Parent *pParent = new Parent;
Parent *pChild = new Child;

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 101

Child *p1 = (Child *) pParent; // #1


Parent *p2 = (Child *) pChild; // #2
return 0;
}
Let look at the lines where we do type cast.

Child *p1 = (Child *) pParent; // #1


Parent *p2 = (Child *) pChild; // #2
Which of the type cast is safe?
The only one guaranteed to be safe is the ones in which the pointer is the same type as the object or else a base type for the
object.

Type cast #1 is not safe because it assigns the address of a base-class object (Parent) to a derived class (Child) pointer.
So, the code would expect the base-class object to have derived class properties such as gotoSchool() method, and that is
false. Also, Child object, for example, has a member classes that a Parent object is lacking.

Type case #2, however, is safe because it assigns the address of a derived-class object to a base-class pointer. In other
words, public derivation promises that a Child object is also a Parent object.
dynamic_cast is an operator that converts safely one type to another type. In the case, the conversation is possible and safe,
it returns the address of the object that is converted. Otherwise, it returns nullptr.

If you want to use a dynamic cast for downcasting, the base class should be polymorphic – it must have at least one virtual
function. Modify base class Person by adding a virtual function:
The dynamic_cast is a runtime cast operator used to perform conversion of one type variable to another only on class
pointers and references. It means it checks the valid casting of the variables at the run time, and if the casting fails, it
returns a NULL value. Dynamic casting is based on RTTI (Runtime Type Identification) mechanism.
Dynamic casting checks consistency at runtime; hence, it is slower than static cast.
Take a look at the function signature of the dynamic cast below:

Program to demonstrate the use of the Dynamic Cast in C++

#include <iostream>
using namespace std;

class parent
{
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 102

public: virtual void print()


{

}
};
class derived: public parent
{

};

int main ()
{
// create an object ptr
parent *ptr = new derived;
// use the dynamic cast to convert class data
derived* d = dynamic_cast <derived*> (ptr);

// check whether the dynamic cast is performed or not


if ( d != NULL)
{
cout << " Dynamic casting is done successfully";
}
else
{
cout << " Dynamic casting is not done successfully";
}
}
Output:
Dynamic casting is done successfully.

Order of Constructor/ Destructor Call in C++


Whenever we create an object of a class, the default constructor of that class is invoked automatically to initialize the
members of the class.
If we inherit a class from another class and create an object of the derived class, it is clear that the default constructor of
the derived class will be invoked but before that the default constructor of all of the base classes will be invoke, i.e the
order of invocation is that the base class’s default constructor will be invoked first and then the derived class’s default
constructor will be invoked.

Why the base class’s constructor is called on creating an object of derived class?
To understand this you will have to recall your knowledge on inheritance. What happens when a class is inherited from
other? The data members and member functions of base class comes automatically in derived class based on the access
specifier but the definition of these members exists in base class only. So when we create an object of derived class, all of
the members of derived class must be initialized but the inherited members in derived class can only be initialized by the
base class’s constructor as the definition of these members exists in base class only. This is why the constructor of base
class is called first to initialize all the inherited members.

#include <iostream>
using namespace std;
// base class
class Parent
{
public:
// base class constructor
Parent()
{
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 103

cout << "Inside base class" << endl;


}
};
// sub class
class Child : public Parent
{
public:
//sub class constructor
Child()
{
cout << "Inside sub class" << endl;
}
};
// main function
int main() {

// creating object of sub class


Child obj;
return 0;
}
Output:
Inside base class
Inside sub class

Order of constructor call for Multiple Inheritance


For multiple inheritance order of constructor call is, the base class’s constructors are called in the order of inheritance
and then the derived class’s constructor.

#include <iostream>
using namespace std;
// first base class
class Parent1
{

public:
// first base class's Constructor
Parent1()
{
cout << "Inside first base class" << endl;
}
};
// second base class
class Parent2
{
public:
// second base class's Constructor
Parent2()
{
cout << "Inside second base class" << endl;
}
};
// child class inherits Parent1 and Parent2
class Child : public Parent1, public Parent2
{
public:

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 104

// child class's Constructor


Child()
{
cout << "Inside child class" << endl;
}
};
// main function
int main() {
// creating object of class Child
Child obj1;
return 0;
}
Output:
Inside first base class
Inside second base class
Inside child class

Order of constructor and Destructor call for a given order of Inheritance

How to call the parameterized constructor of base class in derived class constructor?
To call the parameterized constructor of base class when derived class’s parameterized constructor is called, you have to
explicitly specify the base class’s parameterized constructor in derived class as shown in below program:
#include <iostream>
using namespace std;
// base class
class Parent {
int x;
public:
// base class's parameterized constructor
Parent(int i)
{
x = i;
cout << "Inside base class's parameterized "
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 105

"constructor"
<< endl;
}
};
// sub class
class Child : public Parent {
public:
// sub class's parameterized constructor
Child(int x): Parent(x)
{
cout << "Inside sub class's parameterized "
"constructor"
<< endl;
}
};

int main()
{

// creating object of class Child


Child obj1(10);
return 0;
}
Output:
Inside base class's parameterized constructor
Inside sub class's parameterized constructor

Important Points:
 Whenever the derived class’s default constructor is called, the base class’s default constructor is called automatically.
 To call the parameterized constructor of base class inside the parameterized constructor of sub class, we have to
mention it explicitly.
 The parameterized constructor of base class cannot be called in default constructor of sub class, it should be called in
the parameterized constructor of sub class.

 Destructors in C++ are called in the opposite order of that of Constructors

What are initializer lists in C++?


The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name
and its parameters. The list begins with a colon ( : ) and is followed by the list of variables that are to be initialized – all of
the variables are separated by a comma with their values in curly brackets.

Syntax
Constructorname(datatype value1, datatype value2):datamember(value1),datamember(value2)
{
...
}

Using an initialization list is almost identical to doing direct initialization

#include<iostream>
using namespace std;
class Base

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 106

{
private:
int value;
public:
// default constructor
Base(int v):value(v)
{
cout << "Value is " << value;
}
};

int main()
{
Base myobject(10);
return 0;
}
There are several cases where the use of an initializer list is absolutely necessary, these include:

1. Initializing a reference type data member

An initialization list is used to initialize a data member of reference type. Reference types can only be initialized once

#include<iostream>
using namespace std;

class Base
{
private:
int &ref;
public:
Base(int &passed):ref(passed)
{
cout << "Value is " << ref;
}
};

int main()
{
int ref=10;
Base myobject(ref);
return 0;
}

2. Initializing const data member

const data members can be initialized only once, so they must be initialized in the initialization list.

#include<iostream>
using namespace std;

class Base
{
private:
const int var;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 107

public:
Base(int constant_value):var(constant_value)
{
cout << "Value is " << var;
}
};

int main()
{
Base myobject(10);
}

3. Initializing member objects which do not have a default constructor

If you have a field that has no default constructor (or a parent class with no default constructor), then you must specify
which constructor you wish to use.

#include<iostream>
using namespace std;
class Base_
{
public:
Base_(int x)
{
cout << "Base Class Constructor. Value is: " << x << endl;
}
};

class InitilizerList_:public Base_


{
public:
// default constructor using initializer list
InitilizerList_():Base_(10)
{
cout << "InitilizerList_'s Constructor" << endl;
}
};

int main()
{
InitilizerList_ mylist;
return 0;
}

Difference between static and dynamic binding in C++


Binding generally refers to a mapping of one thing to another. In the context of compiled languages, binding is the link
between a function call and the function definition. When a function is called in C++, the program control binds to the
memory address where that function is defined.

There are two types of binding in C++: static (or early) binding and dynamic (or late) binding. the differences between
static and dynamic binding in C++.

1. the static binding happens at the compile-time, and dynamic binding happens at the runtime. Hence, they are also
called early and late binding, respectively.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 108

2. In static binding, the function definition and the function call are linked during the compile-time, whereas in
dynamic binding, the function calls are not resolved until runtime. So, they are not bound until runtime.
3. Static binding happens when all information needed to call a function is available at the compile-time. Dynamic
binding happens when the compiler cannot determine all information needed for a function call at compile-time.
4. Static binding can be achieved using the normal function calls, function overloading, and operator overloading,
while dynamic binding can be achieved using the virtual functions.
5. Since all information needed to call a function is available before runtime, static binding results in faster
execution of a program. Unlike static binding, a function call is not resolved until runtime for later binding,
resulting in somewhat slower execution of code.
6. The major advantage of dynamic binding is that it is flexible since a single function can handle different types of
objects at runtime. This significantly reduces the size of the codebase and also makes the source code more
readable.

Example of Static Binding in C++:


Consider the following code, where the sum() function is overloaded to accept two and three integer arguments. Even
though there are two functions with the same name inside the ComputeSum class, the function call sum() binds to
the correct function depending on the parameters passed to those functions. This binding is done statically during
compile time
#include <iostream>
using namespace std;

class ComputeSum
{
public:

int sum(int x, int y) {


return x + y;
}

int sum(int x, int y, int z) {


return x + y + z;
}
};

int main()
{
ComputeSum obj;
cout << "Sum is " << obj.sum(10, 20) << endl;
cout << "Sum is " << obj.sum(10, 20, 30) << endl;

return 0;
}
Output:

Sum is 30
Sum is 60

Example of Dynamic Binding in C++:

Consider the following code, where we have a base class B, and a derived class D. Base class B has a virtual function f(),
which is overridden by a function in the derived class D, i.e., D::f() overrides B::f().
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 109

where the decision as to which class’s function will be invoked depends on the dynamic type of the object pointed to
by basePtr. This information can only be available at the runtime, and hence f() is subject to the dynamic binding.
using namespace std;

class B
{
public:
// Virtual function
virtual void f() {
cout << "The base class function is called.\n";
}
};

class D: public B
{
public:
void f() {
cout << "The derived class function is called.\n";
}
};

int main()
{
B base;
D derived;

B *basePtr = &base;
basePtr->f();

basePtr = &derived;
basePtr->f();

return 0;
}
Output:

The base class function is called.


The derived class function is called.
The virtual table

What does dynamic dispatch mean?

In this context, dispatching just refers to the action of finding the right function to call. In the general case, when you
define a method inside a class, the compiler will remember its definition and execute it every time a call to that method is
encountered.

Consider the following example:

#include <iostream>

class A
{
public:
void foo();
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 110

};

void A::foo()
{
std::cout << "Hello this is foo" << std::endl;
}
Here, the compiler will create a routine for foo() and remember its address. This routine will be executed every time the
compiler finds a call to foo() on an instance of A. Keep in mind that only one routine exists per class method, and is shared
by all instances of the class. This process is known as static dispatch or early binding: the compiler knows which routine
to execute during compilation.

So, what do vtables have to do with all this?


Well, there are cases where it is not possible for the compiler to know which routine to execute at compile time. This is the
case, for instance, when we declare virtual functions:

#include <iostream>

class B
{
public:
virtual void bar();
virtual void qux();
};

void B::bar()
{
std::cout << "This is B's implementation of bar" << std::endl;
}

void B::qux()
{
std::cout << "This is B's implementation of qux" << std::endl;
}
The thing about virtual functions is that they can be overriden by subclasses:

class C : public B
{
public:
void bar() override;
};

void C::bar()
{
std::cout << "This is C's implementation of bar" << std::endl;
}
Now consider the following call to bar():

B* b = new C();
b->bar();

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 111

If we use static dispatch as above, the call b->bar() would execute B::bar(), since (from the point of view of the compiler)
b points to an object of type B. This would be horribly wrong, off course, because b actually points to an object of
type C and C::bar() should be called instead.

Hopefully you can see the problem by now: given that virtual functions can be redefined in subclasses, calls via pointers
(or references) to a base type cannot be dispatched at compile time. The compiler has to find the right function definition
(i.e. the most specific one) at runtime. This process is called dynamic dispatch or late method binding.

So, how do we implement dynamic dispatch?

For every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an
entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function
definition callable by the class is stored in the vtable. Entries in the vtable can point to either functions declared in the
class itself (e.g. C::bar()), or virtual functions inherited from a base class (e.g. C::qux()).

In our example, the compiler will create the following virtual tables:

The vtable of class B has two entries, one for each of the two virtual functions declared in B’s scope: bar() and qux().
Additionally, the vtable of B points to the local definition of functions, since they are the most specific (and only)
from B’s point of view.
More interesting is C’s vtable. In this case, the entry for bar() points to own C’s implementation, given that it is more
specific than B::bar(). Since C doesn’t override qux(), its entry in the vtable points to B’s definition (the most specific
definition).

Note that vtables exist at the class level, meaning there exists a single vtable per class, and is shared by all instances.

Vpointers
but how exactly do they solve the problem? When the compiler sees b->bar() in the example above, it will
lookup B’s vtable for bar’s entry and follow the corresponding function pointer, right? We would still be
calling B::bar() and not C::bar()…

vpointers. Every time the compiler creates a vtable for a class, it adds an extra argument to it: a pointer to the
corresponding virtual table, called the vpointer.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 112

Note that the vpointer is just another class member added by the compiler and increases the size of every object that has
a vtable by sizeof(vpointer).

Hopefully you have grasped how dynamic function dispatch can be implemented by using vtables: when a call to a virtual
function on an object is performed, the vpointer of the object is used to find the corresponding vtable of the class. Next,
the function name is used as index to the vtable to find the correct (most specific) routine to be executed. Done!

Pure Virtual Function

A pure virtual function (or abstract function) in C++ is a virtual function for which we don’t have implementation, we only
declare it. A pure virtual function start with virtual keyword and ends with = 0.

o A virtual function is not used for performing any task. It only serves as a placeholder.
o When the function has no definition, such function is known as "do-nothing" function.
o The "do-nothing" function is known as a pure virtual function. A pure virtual function is a function declared
in the base class that has no definition relative to the base class.
o A class containing the pure virtual function cannot be used to declare the objects of its own, such classes are
known as abstract base classes.
o The main objective of the base class is to provide the traits to the derived classes and to create the base pointer
used for achieving the runtime polymorphism.
Pure virtual function can be defined as:

virtual void display() = 0;

When to use Pure virtual Function :


Pure virtual functions are used
 if a function doesn't have any use in the base class
 but the function must be implemented by all its derived classes

Let's take an example, Suppose, we have derived Car, Bike and Cycle classes from the Vehicle class, and we want to
calculate the Speed of all these Vehicles.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 113

In this case, we can create a pure virtual function named calculateSpeed() in the Vehicle. Since it's a pure virtual function,
all derived classes Car, Bike and Cycle must include the calculateSpeed() function with implementation.

A pure virtual function doesn't have the function body and it must end with = 0. For example,

class Vehicle {
public:
// creating a pure virtual function
virtual void calculateSpeed() = 0;
};

Note: The = 0 syntax doesn't mean we are assigning 0 to the function. It's just the way we define pure virtual
functions.

Let's see a simple example:

#include <iostream>
using namespace std;
class Base
{
public:
virtual void show() = 0;
};
class Derived : public Base
{
public:
void show()
{
std::cout << "Derived class is derived from the base class." << std::endl;
}
};
int main()
{
Base *bptr;
//Base b;
Derived d;
bptr = &d;
bptr->show();
return 0;
}
Output:

Derived class is derived from the base class.


In the above example, the base class contains the pure virtual function. Therefore, the base class is an abstract base
class. We cannot create the object of the base class.

Abstract class in C++


We know that every C++ program must start with a concept of class that is without classes concept there is no C++
program perfect.
In C++ programming we have two types of classes they are
 Concrete class
 Abstract class
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 114

Concrete class in C++


A concrete class is one which is containing fully defined methods or implemented method.
Example

class Helloworld
{
void show() {
cout<<"Good Morning"<<endl;
}

Here Helloworld class is containing a defined method and object can be created directly.
Crate an object

Helloworld obj;
obj.display();

Every concrete class have specific feature and these classes are used for specific requirement but not for common
requirement.
If we use concrete classes for fulfill common requirements than such application will get the following limitations.
 Application will take more amount of memory space (main memory).
 Application execution time is more.
 Application performance is decreased.
To overcome above limitation you can use abstract class

Abstract class in C++


A class that is declared with abstract keyword, is known as abstract class. An abstract class is one which is containing
some defined method and some undefined method. In C++ programming undefined methods are known as un-
Implemented or abstract method.
Abstract Class is a class which contains at least one Pure Virtual function in it. Abstract classes are used to provide an
Interface for its sub classes. A class that contains a pure virtual function is known as an abstract class. .
A class without a pure virtual function cannot be termed as an abstract base class in C++. Abstract classes are used as a
framework upon which new subclasses are derived.
In the below example, the class Vehicle is an abstract class.
class Vehicle {
public:
// creating a pure virtual function
virtual void calculateSpeed() = 0;
};

We cannot create objects of an abstract class. However, we can derive classes from them, and use their data members and
member functions (except pure virtual functions).

Characteristics of Abstract Class


1. A class having a pure virtual function cannot be instantiated i.e the object of abstract classes cannot be created.
However, a pointer to the abstract base class or abstract class can be created. They only serve as the foundation
to derive subclasses.
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 115

2. Abstract class can have normal functions and variables along with a pure virtual function.
3. Abstract classes are mainly used for Upcasting, so that its derived classes can use its interface.
4. Classes inheriting an Abstract Class must implement all pure virtual functions, or else they will become Abstract
too.

Example: C++ Abstract Class and Pure Virtual Function


#include <iostream>
using namespace std;
// Abstract class
class Base {
public:
// pure virtual Function
virtual void show() = 0;
};

// Derived class
class Derived : public Base {
public:
void show() {
cout << "Implementation of Abstract class and Pure virtual function.";
}
};

int main() {
Derived obj;
obj.show();
return 0;
}
Output

Implementation of Abstract class and Pure virtual function.

Example 2: C++ Abstract Class and Pure Virtual Function

//#include <iostream>
using namespace std;
// Abstract class
class Shape {
protected:
float dimension;
public:
void getDimension() {
cin >> dimension;
}
// pure virtual Function
virtual float calculateArea() = 0;
};

// Derived class
class Square : public Shape {
public:
float calculateArea() {
return dimension * dimension;
}

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 116

};
// Derived class
class Circle : public Shape {
public:
float calculateArea() {
return 3.14 * dimension * dimension;
}
};

int main() {
Square square;
Circle circle;

cout << "Enter the length of the square: ";


square.getDimension();
cout << "Area of square: " << square.calculateArea() << endl;

cout << "\nEnter radius of the circle: ";


circle.getDimension();
cout << "Area of circle: " << circle.calculateArea() << endl;

return 0;
}
Output

Enter length to calculate the area of a square: 5


Area of square: 25

Enter radius to calculate the area of a circle: 7


Area of circle: 153.86

Important Points about abstract class


 Abstract class of C++ always contains common features.
 Every abstract class participate in inheritance.
 An object of abstract class cannot be created directly but it can be created indirectly.
 All the abstract classes of C++ makes use of polymorphism along with method
overriding for business logic development and makes use of dynamic binding for
execution logic.
Advantage of abstract class
 Less memory space for the application
 Less execution time
 More performance

Difference between Abstract class and Concrete class

Concrete class Abstract class


Concrete class are used for specific Abstract class are used for fulfill common
requirement requirement.
Object of abstract class cannot be create
Object of concrete class can be create directly.
directly (can create indirectly).

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 117

Concrete class containing fully defined methods Abstract class have both undefined method
or implemented method. and defined method.

Abstract class vs Interface in C++


It is often confusing when it comes to interface and abstract class in C++. There are no keyword to define an interface and
abstract classes in C++, as in other programming languages like Java or C#.
Yet, the use of interface and abstract class can be achieved in C++ similar to other languages.
First let us compare the concept of interface and abstract class
1. Interface class does not have any method implementation. It only has method declarations and the class that
implements an interface implement the methods.
2. Interface does not have defined variables. It does exist in java but then the variables are stated as final and static.
3. The class which implements an interface must implement all the methods of the interface.
4. Abstract class can have variable declaration and method implementation/declarations. Moreover one can inherit the
abstract class without implementing the abstract methods.
5. An abstract class cannot be instantiated but rather inherited by another class. Instantiating and abstract class will
give compilation error.
Before looking at how we define abstract and interface, lets understand what is a virtual and a pure virtual method in C++.
A virtual method in C++ is a method which is to be redefined in the derived class, using the virtual keyword tells the
compiler to perform dynamic linkage or late binding on the method.
A pure virtual method in C++ is a virtual method which does not need to be defined but only declared. It is declared by
assigning 0 to a virtual method.
An abstract class in C++

a) must have at least one pure virtual method.


b) can have implemented methods.
c) can have variables declaration.

#include <string>
#include <iostream>
/*Declaring an abstract class*/

class AbstractClass{

public:

AbstractClass(std::string msg): message(msg){}

virtual void method_first() = 0; // a pure virtual method

virtual void method_second(){ // implemented virtual method

std::cout << message << std::endl;

private:

std::string message;
};

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 118

This is how we declare an interface class, in C++ an interface class

a) has all methods declared as pure virtual methods.


b) has no variable declaration.

/*an interface declaration*/

class InterfaceClass{

public:

virtual void method_first() = 0 ; // declaring a pure virtual method by assigning 0

virtual void method_second() = 0;

};

What is Templates in C++?


A template in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can
create a single function or single class to work with different data types using templates.

C++ template is also known as generic functions or classes which is a very powerful feature in C++. A keyword
“template” in c++ is used for the template’s syntax and angled bracket in a parameter (t), which defines the data type
variable. Just quickly review following point

 Template is a blueprint for creating a generic class or a function.

 It is the foundation of generic programming.

 It enables you to define a family of functions or classes that can operate on different types of information.

 The C++ template is based on the ISO/ANSI C++ standard.

 Templates are the better solution than C macros and void pointers and it is mostly useful when working with collections
and smart pointers.

 Using template reduces multiple functions and decreases the code size. The task of writing the program will also be
simple for the programmer.

 Template is used to create a generic functions with the keyword template.

How do templates work in C++?


Templates in c++ works in such a way that it gets expanded at compiler time, just like macros and allows a function or
class to work on different data types without being rewritten.

Types of Templates in C++


There are two types of templates in C++

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 119

 Function template
 Class templates

What is the function template in C++?

 Function template in c++ is a single function template that works with multiple data
types simultaneously, but a standard function works only with one set of data types.
 Function templates are used to create a set of functions that apply the same algorithm
to different data types.
 It works like a function with the only difference that it works on different data types at
once, but different functions are needed to perform identical task on different data
types.
 Function overloading is used to perform identical operations on two or more types of
data, but function template is best approach to perform this task by writing less code
and the code is easier to maintain.
Syntax:
template < class Ttype> return_datatype function_name (argument_lists)
{
//Statements;
}

The class keyword is used to specify a generic type in a template declaration.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 120

Above, Ttype is a placeholder name for the data type that is used by the function. The placeholder will automatically get
replaced with the actual data type by the compiler

Example: Program demonstrating the generic function or template

#include<iostream>
using namespace std;
template <class A> A addition(A x, A y)
{
return ( x + y );
}
int main()
{
cout<<"Addition1 : "<<addition(4,4)<<endl;
cout<<"Addition2 : "<<addition(4.2,3.6)<<endl;
cout<<"Addition3 : "<<addition(4.0,4.7)<<endl;
return 0;
}

Output:

Addition1 : 8
Addition2 : 7.8
Addition3 : 8.7

In the above program


 In first cout statement values are passed as integer.

 In second cout statement, values are passed as float.

 In third cout statement, value 4.0 & 4.7 are passed instead of 4 & 4.7 and it will be integer and float which are different;

while the generic function claims both the parameters to be of same data type.

Difference between function overloading and templates in C++?


Function overloading Function Template

This is used when multiple functions do similar This is used when functions do identical
operations. operations.

Function overloading can take varying numbers Templates cannot take varying numbers
of arguments. of arguments.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 121

Function Templates with Multiple Parameters

You can also use multiple parameters in your function template.

Syntax:-
template<class T1, class T2,.....> return_type functionName (arguments of type T1, T2....) {
// body
}

The above syntax will accept any number of arguments of different types .

Example of Function Template with multiple parameters


#include <iostream>
using namespace std;
template<class A,class B> void func(A x,B y)
{
std::cout << "Value->x: " <<x<< std::endl;
std::cout << "Value->y: " <<y<< std::endl;
}
int main()
{
func(15.2,1.3);
return 0;
}

Output:-
Value->x: 15.2
Value->y: 1.3
Above, we used two generic types such as A and B in the template function

Example: Program demonstrating the Overloading of Function Template

//Overloaded functions using a Template function

#include <iostream>
using namespace std;
template <class A>A addition(A num1, A num2)
{
return num1 + num2;
}
template <class A>A addition(float num1, A num2)
{
return num1 + num2;
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 122

}
template <class A>A addition(char num1, A num3)
{
return(num1 + num3);
}
int main ()
{
cout<<"Addition of Integer Numbers : "<<addition(10,20)<<endl;
cout<<"Addition of Float Numbers : "<<addition(10.0,15.5)<<endl;
cout<<"Addition of Characters : "<<addition('C',5)<<endl;
return 0;
}

Output:
Addition of Integer Numbers : 30
Addition of Float Numbers : 25.5
Addition of Characters : 72

The above program shows the addition of a special case char data type with integer type data.
template <class A>A addition(char num1, A num3)
{
return(num1+num3);
}
cout<<"Addition of Characters : "<<addition('C',5)<<endl;

In the above statement, in cout, addition function passes 'C' and 5 value, where it takes the ASCII value of C that is 67 and
assigns it to the num1 parameter and displays the addition.

Value->z: 2.1

What is class template in c++?


The class template in c++ is like function templates. They are known as generic templates. They define a family of classes
in C++.
In some cases, you will need a class implementation that is the same for all the classes. The only thing is that the data
types that are used are different. Generally, you would have to create a class for each data type. And because of that, your
code will get complex and hard to understand.
To avoid that, you can make use of class templates. Using class templates, you can reuse the same code for all data types.

Syntax of C++ Class Template


template <class T>

class Name_of_the_class
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 123

... .. ...

... .. ...

};

From above, T is a placeholder for the data type used. It is also known as the template argument.

Create a class template object

If you want to create a class template object then you will have to define the data type inside <> during creation.

Name_of_the_class<dataType> class_Object;

Example
Name_of_the_class<int> class_Object;

Name_of_the_class<float> class_Object;

Example
#include <iostream>
using namespace std;
template<class T>
class Add
{
public:
T n1 = 6;
T n2 = 1;
void addition()
{
std::cout << "n1+n2: " << n1+n2<<std::endl;
}
};
int main()
{
Add<int> data;
data.addition();
return 0;
}
Output:-
n1+n2: 7

Above, we created a template for class Add and within the main() function, we created the instance of class Add

C++ Class Template with multiple parameters

You can also use multiple parameters in your class template.


Syntax
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 124

template<class T1, class T2, ......>

class Name_of_the_class

// Body

Example:- Class Template with multiple parameters


#include <iostream>
using namespace std;
template<class T1, class T2>
class Tech
{
T1 x;
T2 y;
public:
Tech(T1 a,T2 b)
{
x = a;
y = b;
}
void print()
{
std::cout << "The values of x and y: " << x<<" and "<<y<<std::endl;
}
};
int main()
{
Tech<int,float> data(5,2.3);
data.print();
return 0;
}
Output:-
The values of x and y: 5 and 2.3

Nontype Template Arguments

The template can contain multiple arguments, and we can also use the non-type arguments In addition to the type T
argument, we can also use other types of arguments such as strings, function names, constant expression and built-in
types. Let' s see the following example:

template<class T, int size>


class array
{
T arr[size]; // automatic array initialization.
};

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 125

In the above case, the nontype template argument is size and therefore, template supplies the size of the array as an
argument.

Arguments are specified when the objects of a class are created:

array<int, 15> t1; // array of 15 integers.


array<float, 10> t2; // array of 10 floats.
array<char, 4> t3; // array of 4 chars.

Let's see a simple example of nontype template arguments.

#include <iostream>
using namespace std;
template<class T, int size>
class A
{
public:
T arr[size];
void insert()
{
int i =1;
for (int j=0;j<size;j++)
{
arr[j] = i;
i++;
}
}

void display()
{
for(int i=0;i<size;i++)
{
std::cout << arr[i] << " ";
}
}
};
int main()
{
A<int,10> t1;
t1.insert();
t1.display();
return 0;
}

Output:
1 2 3 4 5 6 7 8 9 10

In the above example, the class template is created which contains the nontype template argument, i.e., size. It is specified
when the object of class 'A' is created.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 126

Advantages of Using Templates in C++


 Templates are type-safe.
 They are generally considered as an improvement over macros for these purposes.
 Templates avoid some common errors found in code that makes heavy use of function-like macros.
 Both templates and macros are expanded at compile time.
 They are a good way of making generalisations for APIs.

Disadvantages of Using Templates in C++


 Many compilers do not support nesting of templates.
 When templates are used, all codes exposed.
 Some compilers have poor support of templates.
 Approx all compilers produce unhelpful, confusing error messages when errors are
detected in the template code.
 It can make it challenging to develop the template.

Template Specialization
We use templates when we need functions/classes that apply the same algorithm to a several types. So we can use the
same function/class regardless of the types of the argument or result.

In other words, a template is a mechanism that allows a programmer to use types as parameters for a class or a function.
The compiler then generates a specific class or function when we later provide specific types as arguments. In a sense,
templates provide static (compile-time) polymorphism, as opposed to dynamic (run-time) polymorphism. A function/class
defined using template is called a generic function/class, and the ability to use and create generic functions/classes is one
of the key features of C++.

However, sometimes a template cannot (or should not) be applied to a certain types of data.

Function Specialization
In the example below, we have add() function which takes two parameter and returns the same type of data after adding
the two args.

#include <iostream>
using namespace std;

template <typename T>


T add(T x, T y)
{
cout << "Normal template\n";
return x+y;
}

// specialized function
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 127

template<>
char add<char>(char x, char y)
{
cout << "Specialized template\n";
int i = x-'0';
int j = y-'0';
return i+j;
}

int main()
{
int a = 1, b = 2;
cout << add(a, b) << endl;

double c = 3.0, d = 5.5;


cout << add(c,d) << endl;

char e='e', f='f';


cout << add(e,f);

return 0;
}

When we designed the function add(T x, T y), the meaning was clear: add the two numbers. But when the user feeds
characters into the parameter, the meaning is not obvious. So, if the intention of the design is different from the initial one,
we may want to redefine the operation in a separate template. In other words, we do specialize the function.

Class Specialization
##include <iostream>
using namespace std;

template <class T>


class Test
{
// Data memnbers of test
public:
Test()
{
// Initialization of data members
cout << "General template \n";
}
// Other methods of Test
};

template <>
class Test <int>
{
public:
Test()
{
// Initialization of data members
cout << "Specialized template \n";
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 128

}
};

int main()
{
Test<int> a;
Test<char> b;
Test<float> c;
return 0;
Output:

Specialized template
General template
General template

Importance of C++ Templates


There are various ways why you should use templates in C++.

 Less Redundancy:- Suppose, you want to find the area of a rectangle with parameters entered as integer and as well
as floating point values. Then without any difficulty, you can achieve this task with the help of templates. You don’t
have to create different functions for integer and floating point values.

 Programming Effort Reduced:- You can use multiple blocks of code for multiple data types. It will reduce the
programming effort on the user’s end.
 Reusability and Flexibility:- It provides the reusability of codes which you can use again. It also provides you code

flexibility.

 Utility:- You can also combine templates with function overloading and multiple inheritance

Exception Handling in C++


The process of converting system error messages into user friendly error message is known as Exception handling.
This is one of the powerful feature of C++ to handle run time error and maintain normal flow of C++ application.

Exception
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the
program's Instructions.

One of the advantages of C++ over C is Exception Handling. Exception Handling in C++ is a process to handle
runtime errors. We perform exception handling so the normal flow of the application can be maintained even after
runtime errors.

In C++, exception is an event or object which is thrown at runtime. All exceptions are derived from std::exception
class. It is a runtime error which can be handled. If we don't handle the exception, it prints exception message and
terminates the program

There are two types of exceptions:


a) Synchronous
b) Asynchronous (Ex:which are beyond the program’s control, Disc failure etc).

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 129

Handling the Exception


Handling the exception is nothing but converting system error message into user friendly error message. Use Three
keywords for Handling the Exception in C++ Language, they are;

1. try
2. catch
3. throw

Syntax for handling the exception


Example of Exception Handling in C++

try
{
// causes executions code
}

catch( ExceptionName e1 )
{
// catch block
}

catch( ExceptionName e2 )
{
// catch block
}
catch( ExceptionName eN )

{
// catch block

}
Try Block
It is one of the block in which we write the block of statements which causes executions at run time in other words try
block always contains problematic statements.

Catch block
It is one of the block in which we write the block of statements which will generates user friendly error messages in
other words catch block will suppose system error messages.

C++ Standard Exceptions


There are some standard exceptions in C++ under which we can use in our programs. They are arranged in a parent-child
class hierarchy which is depicted below:

 std::exception - Parent class of all the standard C++ exceptions.

 logic_error - Exception happens in the internal logical of a program.


[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 130

o domain_error - Exception due to use of invalid domain.

o invalid argument - Exception due to invalid argument.

o out_of_range - Exception due to out of range i.e. size requirement exceeds allocation.

o length_error - Exception due to length error.

 runtime_error - Exception happens during runtime.

o range_error - Exception due to range errors in internal computations.

o overflow_error - Exception due to arithmetic overflow errors.

o underflow_error - Exception due to arithmetic underflow errors

 bad_alloc - Exception happens when memory allocation with new() fails.

 bad_cast - Exception happens when dynamic cast fails.

 bad_exception - Exception is specially designed to be listed in the dynamic-exception-specifier.

 bad_typeid - Exception thrown by typeid.

Example without Exception Handling


Example
#include<iostream.h>
#include<conio.h>

void main()
{
int a, ans;
a=10;
ans=a/0;
cout<<"Result: "<<ans;
}

Output

Abnormally terminate program

Example of Exception Handling


Example
#include<iostream.h>
#include<conio.h>
void main()
{
int a=10, ans=0;

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 131

try
{
ans=a/0;
}
catch(int i)
{
cout<<"Denominator not be zero";
}
}

Output

Denominator not be zero

Example

#include <iostream>
using namespace std;

int main()
{
int x = -1;

cout << "Before try \n";

try {
cout << "Inside try \n";
if (x < 0) {
throw x;
cout << "After throw (Never executed) \n";
}
}
catch (int x) {
cout << "Exception Caught \n";
}
cout << "After Caught (Will be executed) \n";
return 0;
}
Output

Before try
Inside try
Exception Caught
After catch (Will be executed)

Example

There is a special catch block called ‘catch all’ catch(…) that can be used to catch all types of exceptions. For example, in
the following program, an int is thrown as an exception, but there is no catch block for int, so catch(…) block will be
executed.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 132

#include <iostream>
using namespace std;
int main(){

try {
throw 10;
}

catch (char *excp) {


cout << "Caught " << excp;
}
catch (...) {
cout << "Default Exception \n";
}
return 0;
}
Output

Default Exception

Example

Implicit type conversion doesn’t happen for primitive types. For example, in the following program ‘a’ is not implicitly
converted to int

#include <iostream>
using namespace std;
int main(){

try {
throw 'a';
}

catch (int x) {
cout << "Caught " << x;
}
catch (...) {
cout << "Default Exception \n";
}
return 0;
}
Output

Default Exception

Example
If an exception is thrown and not caught anywhere, the program terminates abnormally. For example, in the following
program, a char is thrown, but there is no catch block to catch a char.
#include <iostream>
using namespace std;
int main(){

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 133

try {
throw 'a';
}

catch (int x) {
cout << "Caught " << x;
}
return 0;
}
Output

terminate called after throwing an instance of 'char'

This application has requested the Runtime to terminate it in an


unusual way. Please contact the application's support team for
more information.

Example
Unlike Java, in C++, all exceptions are unchecked. Compiler doesn’t check whether an exception is caught or not (See
this for details). For example, in C++, it is not necessary to specify all uncaught exceptions in a function declaration.
Although it’s a recommended practice to do so. For example, the following program compiles fine, but ideally signature
of fun() should list unchecked exceptions.

#include <iostream>
using namespace std;
// Here we specify the exceptions that this function throws.
void fun(int *ptr, int x) throw(int *, int){

if (ptr == NULL) {
throw ptr;
}
if (x == 0) {
throw x;
// some functionality.
}
}
int main(){

try {
fun(NULL, 0);
}

catch (...) {
cout << "Caught exception from fun()";
}
return 0;
}

Output

Caught exception from fun()

Example

#include <iostream>
using namespace std;
Class Exam{
public:
Exam() {cout << "Constructor of Exam \n"; }
~ Exam() {cout << "Destructor of Exam \n"; }
[email protected] contact 03354900611
OOPS IN C++ Notes P a g e | 134

};
int main(){

try {
Exam e1;
throw 10;
}
catch (int i) {
cout << "Caught " << i << endl;
}
return 0;
}

Output

Constructor of Test
Destructor of Test
Caught 10

Example
When an exception is thrown, all objects created inside the enclosing try block are destructed before the control is
transferred to catch block.

#include <iostream>
using namespace std;
int main(){

try {
try {
throw 20;
}
catch (int n) {
cout << "Handle Partially ";
throw; // Re-throwing an exception

}
}

catch (int n) {
cout << "Handle remaining ";
}
return 0;
}
Output

Handle Partially Handle remaining

User-Defined Exceptions
The C++ std::exception class allows us to define objects that can be thrown as exceptions. This class has been defined in
the header. The class provides us with a virtual member function named what.

This function returns a null-terminated character sequence of type char *. We can overwrite it in derived classes to have
an exception description.

[email protected] contact 03354900611


OOPS IN C++ Notes P a g e | 135

Example

#include <iostream>
#include <exception>
using namespace std;

Class Excep : public exception{

Virtual const char* what() const throw()


{
return "Excep Occurred";
}
} newex;
int main(){

try {
throw newex;
}
catch (exception ex) {
cout << ex.what() << endl;
}
return 0;
}

Output

Excep Occurred

Why Exception Handling?


Following are main advantages of exception handling over traditional error handling.

1. You will separate your error handling code from your normal code. The code will be more readable and easier to
maintain.

2. Functions can handle the exceptions they choose. Even if a function throws many exceptions, it will only handle some.
The caller will handle the uncaught exceptions.

3. Grouping of Error Types: In C++, both basic types and objects can be thrown as exception. We can create a hierarchy of
exception objects, group exceptions in namespaces or classes, categorize them according to types.

[email protected] contact 03354900611

You might also like