0% found this document useful (0 votes)
7 views

C++ Notes

The document provides an overview of Object Oriented Programming (OOP), highlighting its focus on real-life objects, data encapsulation, and the advantages it offers over traditional programming methods. It discusses key concepts such as objects, classes, inheritance, polymorphism, and dynamic binding, along with the differences between object-oriented and procedure-oriented programming. Additionally, it outlines the benefits of OOP, including improved code reusability, easier maintenance, and its applications in various fields like real-time systems and AI.

Uploaded by

jassarharman771
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)
7 views

C++ Notes

The document provides an overview of Object Oriented Programming (OOP), highlighting its focus on real-life objects, data encapsulation, and the advantages it offers over traditional programming methods. It discusses key concepts such as objects, classes, inheritance, polymorphism, and dynamic binding, along with the differences between object-oriented and procedure-oriented programming. Additionally, it outlines the benefits of OOP, including improved code reusability, easier maintenance, and its applications in various fields like real-time systems and AI.

Uploaded by

jassarharman771
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/ 71

SECTION – A

1. INTRODUCTION TO OBJECT ORIENTED PROGRAMMING

The concept of Object Oriented Programming focuses on real life objects which are very close to reality.
To remove the drawbacks of traditional programming, OOP approach came into existence. In OOP
approach, a new concept of structural programming is used with new as well as power concepts that
emphasize on data and functions so that large and complex programs can be designed and implements
easily. The main idea behind the development of OOP is to secure the data i.e. data should not flow
freely around the systems. OOP ties data to the functions that operate on it and prevent it from accidental
change due to external functions. In OOP data and functions are combined into a single unit so that only
embedded functions can operate on that data and this single unit is called as object. Therefore, OOP is
such a programming approach which allows the programmer to decompose a problem into number of
entities called objects. Data of the object can be accessed and used only by the functions of that object.
Different objects can communicate with one another by sending messages.

Object A Object B
Object A

Data Data

Communication
Functions Functions

Object C
Object A
Data

Functions

Basically, objects can communicate with each other by calling one another’s member functions.
Member functions are known as Methods and Data Items are referred as Instance variables. Calling an
object’s member function is referred to as sending a message to the object.

Some of the striking features of object-oriented programming are:

• Emphasis is on data rather than procedure.


• Programs are divided into what are known as objects.
• Data structures are designed such that they characterize the objects.
• Functions that operate on the data of an object are tied together in the data structure.
• Data is hidden and cannot be accessed by external function.
• Objects may communicate with each other through functions.
• New data and Functions can be easily added whenever necessary.
• Follow bottom-up approach in program design.

1
2. DIFFERENCE BETWEEN OBJECT ORIENTED AND PROCEDURE ORIENTED
PROGRAMMING

Procedure Oriented Programming Object Oriented Programming

1. Program is divided into small parts Program is divided into parts called objects.
called functions.

2. Importance is not given to data but to Importance is given to the data rather than
functions as well as sequence of actions to procedures or functions because it works as
be done. a real world.
3. It follows Top Down approach. It follows Bottom Up approach.

4. The emphasis is on the functions. The emphasis is on the data rather than
functions.

5. This approach does not represent real world This approach represents real-world
modelling modelling.

6. It does not have any access specifier. It has access specifiers named Public,
Private, Protected, etc.

7. Data can move freely from function to Objects can move and communicate with
function in the system. each other through member functions.

8. To add new data and function is not so easy. It provides an easy way to add new data and
function.

9. Most function uses Global data for sharing Data cannot move easily from function to
that can be accessed freely from function to function, it can be kept public or private so
function in the system. we can control the access of data.

10. It does not have any proper way for hiding It provides Data Hiding so provides more
data so it is less secure. security

11. Overloading is not possible Overloading is possible in the form of


Function Overloading and Operator
Overloading

12. Example of POP are : C, VB, FORTRAN, Example of OOP are : C++, JAVA,
Pascal VB.NET, C#.NET.

2
3. CONCEPTS OF OBJECT ORIENTED PROGRAMMING

It is necessary to understand some of the concepts used extensively in object-oriented programming.


These include:
• Objects
• Classes
• Data abstraction and encapsulation
• Inheritance
• Polymorphism
• Dynamic binding
• Message passing

We shall discuss these concepts in some detail in this section.

• Objects : Objects are the basic run time entities in an object-oriented system. They may
represent a person, a place, a bank account, a table of data or any item that the program has to
handle. They may also represent user-defined data such as vectors, time and lists. Programming
problem is analyzed in term of objects and the nature of communication between them. Program
objects should be chosen such that they match closely with the real-world objects. Objects take
up space in the memory and have an associated address like a record in Pascal, or a structure in
C.

When a program is executed, the objects interact by sending messages to one another.
For example, if “customer” and “account” are to object in a program, then the customer object
may send a message to the count object requesting for the bank balance. Each object contain
data, and code to manipulate data. Objects can interact without having to know details of each
other’s data or code. It is a sufficient to know the type of message accepted, and the type of
response returned by the objects. Following figure shows the notation that are popularly used
in object oriented analysis and design.

• Classes: We just mentioned that objects contain data, and code to manipulate that data. The
entire set of data and code of an object can be made a user-defined data type with the help of
class. In fact, objects are variables of the type class. Once a class has been defined, we can
create any number of objects belonging to that class. Each object is associated with the data of
type class with which they are created. A class is thus a collection of objects similar types. For
examples, Mango, Apple and orange members of class fruit. Classes are user-defined that types
and behave like the built-in types of a programming language. The syntax used to create an

3
object is not different then the syntax used to create an integer object in C. If fruit has been
defines as a class, then the statement

fruit mango;

will create an object mango belonging to the class fruit.

• Data Abstraction: Abstraction refers to the act of representing essential features without
including the background details or explanation. Classes use the concept of abstraction and are
defined as a list of abstract attributes such as size, wait, and cost, and function operate on these
attributes. They encapsulate all the essential properties of the object that are to be created. The
attributes are sometime called data members because they hold information. The functions that
operate on these data are sometimes called methods or member function.

• Encapsulation: The wrapping up of data and function into a single unit (called class) is known
as encapsulation. Data and encapsulation is the most striking feature of a class. The data is not
accessible to the outside world, and only those functions which are wrapped in the class can
access it. These functions provide the interface between the object’s data and the program. This
insulation of the data from direct access by the program is called data hiding or information
hiding.

• Inheritance: Inheritance is the process by which objects of one class acquired the properties of
objects of another classes. It supports the concept of hierarchical classification. For example,
the bird, ‘robin’ is a part of class ‘flying bird’ which is again a part of the class ‘bird’. The
principal behind this sort of division is that each derived class shares common characteristics
with the class from which it is derived as illustrated in following figure.

In OOP, the concept of inheritance provides the idea of reusability. This means that we can add
additional features to an existing class without modifying it. This is possible by deriving a new

4
class from the existing one. The new class will have the combined feature of both the classes.
The real appeal and power of the inheritance mechanism is that it allows the programmer to
reuse a class i.e almost, but not exactly, what he wants, and to tailor the class in such a way that
it does not introduced any undesirable side-effects into the rest of classes.

• Polymorphism: Polymorphism is another important OOP concept. Polymorphism, a Greek


term, means the ability to take more than on form. An operation may exhibit different behavior
is different instances. The behavior depends upon the types of data used in the operation. For
example, consider the operation of addition. For two numbers, the operation will generate a
sum. If the operands are strings, then the operation would produce a third string by
concatenation. The process of making an operator to exhibit different behaviors in different
instances is known as operator overloading.

Fig. 1.7 illustrates that a single function name can be used to handle different number and
different types of argument. This is something similar to a particular word having several
different meanings depending upon the context. Using a single function name to perform
different type of task is known as function overloading.

Shape

Draw

Circle Object Box Object Triangle


Object

Draw (Circle) Draw (box) Draw (triangle)

Polymorphism plays an important role in allowing objects having different internal structures
to share the same external interface. This means that a general class of operations may be
accessed in the same manner even though specific action associated with each operation may
differ. Polymorphism is extensively used in implementing inheritance.

• Dynamic Binding: Binding refers to the linking of a procedure call to the code to be executed
in response to the call. Dynamic binding means that the code associated with a given procedure
call is not known until the time of the call at run time. It is associated with polymorphism and
inheritance. A function call associated with a polymorphic reference depends on the dynamic
type of that reference.

Consider the procedure “draw” in figure above by inheritance, every object will have this
procedure. Its algorithm is, however, unique to each object and so the draw procedure will be
redefined in each class that defines the object. At run-time, the code matching the object under
current reference will be called.

• Message Passing: An object-oriented program consists of a set of objects that communicate


with each other. The process of programming in an object-oriented language, involves the
following basic steps:
1. Creating classes that define object and their behavior,
2. Creating objects from class definitions, and

5
3. Establishing communication among objects.

Objects communicate with one another by sending and receiving information much the same
way as people pass messages to one another. The concept of message passing makes it easier
to talk about building systems that directly model or simulate their real world counterparts.

A Message for an object is a request for execution of a procedure, and therefore will invoke a
function (procedure) in the receiving object that generates the desired results. Message passing
involves specifying the name of object, the name of the function (message) and the information
to be sent. Example:

Employee. salary (name);

Object Message Information

Object has a life cycle. They can be created and destroyed. Communication with an object is
feasible as long as it is alive.

4. ADVANTAGES OF OBJECT ORIENTED PROGRAMMING

Object Oriented Programming eliminates various drawbacks of conventional programming approach.


Object Oriented Programming reduces maintenance, improved reliability and flexibility and promises
to implement the real-world problems or complex problems. It also provides low cost software and
improved quality software. Following are the advantages of OOP approach :

• Emphasis on data: OOP give more emphasis on data rather than functions. Data hiding helps
the programmer to build secure programs that cannot be invaded by code in other parts of the
program.

• Eliminate redundant code: Through inheritance one can eliminate the redundant code and
extend the use of existing code.

• Easily upgraded: Object oriented systems can be easily upgraded from small to large systems.

• Simplicity: Software object model real-world objects, this reduces complexity and makes the
program structure very clear.

• Reduces maintenance cost: Due to encapsulation and reusability of code, maintenance cost is
reduced. New functions can be easily incorporated.

• Real world modelling: This real-world modelling is based on objects rather than the data and
procedures. So real-world problems are easily modelled in complete fashion than traditional
method.

• Faster development: Reuse of code enables faster development of program. Code once
development and compiled can be reused in future projects.

6
• Modifiability: It is easy to make changes in the procedure or data representation in an object-
oriented program. If you make any change inside a class, it will not affect any other part of the
program.

• New data type: With the help of object oriented programming user can create new complex
data type as per requirement.

• Design benefit: Large programs are very difficult to write. In Object Oriented Programming
programs are easy to write than non-object oriented ones because better designs are made and
large programs are divided into functions and managed easily.

While it is possible to incorporate all these features in an object-oriented system, their importance
depends on the type of the project and the preference of the programmer. There are a number of issues
that need to be tackled to reap some of the benefits stated above. For instance, object libraries must be
available for reuse. The technology is still developing and current product may be superseded quickly.
Strict controls and protocols need to be developed if reuse is not to be compromised.

5. APPLICATIONS OF OBJECT ORIENTED PROGRAMMING

OOP has become one of the programming buzzwords today. There appears to be a great deal of
excitement and interest among software engineers in using OOP. Applications of OOP are beginning
to gain importance in many areas. The most popular application of object-oriented programming, up to
now, has been in the area of user interface design such as window. Hundreds of windowing systems
have been developed, using the OOP techniques.

Real-business system are often much more complex and contain many more objects with complicated
attributes and method. OOP is useful in these types of application because it can simplify a complex
problem. The promising areas of application of OOP include:

• Real-time system
• Simulation and modeling
• Object-oriented data bases
• Hypertext, Hypermedia, and expertext
• AI and expert systems
• Neural networks and parallel programming
• Decision support and office automation systems
• CIM/CAM/CAD systems
• System Software
• Image Processing System
• Distributed System and Network Management System etc.

The object-oriented paradigm sprang from the language, has matured into design, and has recently
moved into analysis. It is believed that the richness of OOP environment will enable the software
industry to improve not only the quality of software system but also its productivity. Object-oriented
technology is certainly going to change the way the software engineers think, analyze, design and
implement future system.

7
6. SPECIAL OPERATORS

C++ has a rich set of special operators. All C operators are valid in C++. In addition, C++ introduces
some new operators. Following are some special operators used in C++:

• Scope Resolution Operator:

C++ is a block structured language. Blocks and scopes can be used in constructing program. We
know that the same variable name can be used to have different meanings in different blocks. The
scope of the variable extends from the point of its declaration till the end of the block containing
the declaration. A variable declared inside a block is said to be local to that block.

Consider the following segment of a program

. . . .
. . . .
{
int x = 10;
. . . . . .
. . . . . .
}
. . . . .
. . . . .
{
int x = 1;
. . . . .
. . . . .
}

The two declarations of x refer to two different memory locations containing different values.
Statements in the second block cannot refer to the variable x declared in the first block, and vice
versa.

Consider another example of nested blocks:

. . . . .
. . . . .
{
int x = 10;
. . . . .
. . . . .
{
int x = 1;
Block 1
. . . . . Block 2
. . . . .
}
. . . .
}

Block 2 is contained in block 1. Note that a declaration in an inner block hides a declaration of the
same variable in an outer block and, therefore, each declaration of x causes it to refer to a different data
object. Within the inner block, the variable x will refer to the data object declared therein.

8
In C, the global version of a variable cannot be accessed from within the inner block. C++ resolves this
problem by introducing a new operator :: called the scope resolution operator. This can be used to
uncover a hidden variable. It takes the following form:

:: variable-name

Following example shows the concept of scope resolution operator.

Scope Resolution Operator


#include<iostream>
using namespace std;

int m= 10; //global m

int main()
{
int m = 20; //local m
{
int m = 30; //local m
cout<<"Inner Block m = "<<m<<"\n";
cout<<"Global m = "<<::m<<"\n";
}
cout<<"Outer Block m = "<<m<<"\n";
cout<<"Global m = "<<::m<<"\n";

return 0;
}

The output of the above program is

Inner Block m = 30
Global m = 10
Outer Block m = 20
Global m = 10

In the above program, the variable m is declared at three places, namely, outside the main() function,
inside the main( ) function and inside the inner block. It is to be noted that ::m will always to refer to
the global m.

• Memory Management Operators

In C++, two operators new and delete performs the task of allocating and freeing the memory. Since
these operators manipulate memory on the free store, they are also known as free store operators.

An object can be created by using new, and destroyed by using delete. A data object created inside a
block with new, will remain in existence until it is explicitly destroyed by using delete. Thus, the
lifetime of an object is directly under our control and is unrelated to the block structure of the program.

• The new operator : The new operator can be used to create objects of any type. It takes the following
general form:

9
pointer-variable = new data-type;

Here pointer-variable is a pointer of type data-type. The new operator allocates sufficient memory to
hold a data object of type data-type and returns the address of the object. The pointer-variable holds
the address of the memory space allocated

For example:

int *p = new int;


float *q = new float;

where p is a pointer of type int and q is a pointer of type float. Here p and q must have already been
declared as pointers of appropriate types.

Subsequently, the statements

*p = 25;
*q = 7.5;

Assign 25 to the newly created int object and 7.5 to the float object.

new operator can be used to create a memory space for any data type including user-defined types such
as arrays, structures and classes. The general form for a one-dimensional array is:

pointer-variable = new data-type[size];

Here, size specifies the number of elements in the array. For example, the statement

int *p = new int[10];

creates a memory space for an array of 10 integers. p[0] will refer to the first element, p[1] to the second
element and so on.

The delete operator: When a data object is no longer needed, it is destroyed to release the memory
space for reuse. The general form of delete is:

delete pointer-variable;

The pointer-variable is the pointer that points to a data object created with new.

For example

delete p;
delete q;

If we want to free a dynamically allocated array, we must use the following form of delete

delete [size] pointer-variable;

The size specifies the number of elements in the aray to be freed.


Following program shows the concept of new and delete operator

10
new and delete operators

#include<iostream>
using namespace std;

int main()
{
int *arr;
int size;

cout<<"Enter the size of the integere array :";


cin>>size;

cout<<"Creating an array of size "<<size<<" ";


arr=new int[size];

cout<<"\nDynamic allocation of memory for array arr is successful";

delete arr;

return 0;
}

The output of the above program is

Enter the size of the integere array :50


Creating an array of size 50
Dynamic allocation of memory for array arr is successful

___________________________________________________________________________

MANIPULATORS

Manipulators are operators that are used to formal the data display. The most commonly used
manipulators are endl and setw.

* The endl manipulator, when used in an output statement, causes a linefeed to be inserted. It has the
same effect as using the newline character “\n”. For example, the statement:

cout<<”Hello”<<endl;
cout<<”Welcome”<<endl;

would causes two lines of output, one for each word (Hello and Welcome).

* The setw operator sets the width of the variable. Consider the following statements:

cout<<”m = “<<m<<endl;
cout<<”n = “<<n<<endl;
cout<<”p = “<<p<<endl;

If we assume the values of the variables as 3456, 55, 667, the output will appear as follows:

m=2597
n =14
p =667

11
Since the numbers are right justified, the setw manipulator does this job. The following statement

cout<<setw(5)<<m<<endl;
cout<<setw(5)<<n<<endl;
cout<<setw(5)<<p<<endl;

The manipulator setw(5) specifies a field width 5 for printing value of the variables. The value is right
justified within the field as shown below:

m= 2597
n = 14
p = 667

The following program shows the use of endl and setw.

Use of Manipulators

#include<iostream>
using namespace std;

int main()
{
int basic = 1000, allowance = 500, Total = 1500;

cout<<setw(10)<<"Basic "<<setw(10) <<basic <<endl;


cout<<setw(10)<<"Allowance "<<setw(10) <<allowance <<endl;
cout<<setw(10)<<"Total "<<setw(10) <<Total <<endl;

return 0;
}

The output of the above program is

Basic 1000
Allowance 500
Total 1500

TYPE CAST OPERATOR

C++ permits explicit type conversion of variables or expression using the type cast operator. Type
cast operator syntax is:

type-name (expression)

For example

average = sum / float(i);

Type Cast Operator


#include<iostream>
using namespace std;

int main()

12
{
int intvar=25;
float floatvar=35.87;

cout<<"intvar = "<<intvar<<endl;
cout<<"floatvar = "<<floatvar<<endl;
cout<<"float(intvar) = "<<float(intvar)<<endl;
cout<<"int(floatvar) = "<<int(floatvar)<<endl;

return 0;
}

The output of the above program is

intvar = 25
floatvar = 35.87
float(intvar) = 25
int(floatvar) = 35

13
CLASS

A class is a way to bind the data and its associated functions together. It allows the data and the functions
to be hidden. When defining a class, we are creating a new abstract data type that can be treated like
any other built-in data type. Generally a class specification has two parts:

1. Class declaration
2. Class function definitions

The class declaration describes the type and scope of its members. The class function definition describe
how the class functions are implemented.

The general form of class declaration is:

class class-name
{
private:
variable declarations;
function declarations;
public:
variable declarations;
function declarations;
};

The class declaration is similar to struct declaration. The keyword class specifies, that what follows is
an abstract data of type class-name. The body of the class is enclosed within braces and terminated by
a semicolon. The class body contains the declaration of variables and functions. These functions and
variables are collectively called class members.

Private and Public Members:

Class members are usually grouped under two sections namely private and public to denote which of
the members are private and which of these are public. The keywords private and public are known as
visibility labels. These keywords are followed by a colon (:).

The class members that have been declared as private can be accessed only from within the class. On
the other hand, public members can be accessed from outside the class also. The data hiding (using
private declaration) is the key feature of object-oriented programming. The use of the keyword private
is optional. By default, the members of the class are private. If both the labels are missing, then, by
default, all the members are private. Such a class is completely hidden from the outside world and does
not serve any purpose.

The variables declared inside the class are known as data members and the functions are known as
member functions. Only the member functions can have access to the private data members and private
functions. However, the public members (both function and data) can be accessed from outside the
class. This is illustrated in following figure. The binding of data and functions together into a single
class-type variable is known as encapsulation.

14
For example, a typical class declaration would look like:

class item
{
int number; //variable declaration
float cost; //private by default
public:
void getdata(int a, float b); //function declarations
void showdata();
};

We usually give a class some meaningful name, such as item. This name now becomes a new type
identifier that can be used to declare instances of that class type. The class item contains two data
members and two member functions. The data members are private by default while both the functions
are public by declaration. The function getdata( ) can be used to assign values to the member variables
number and cost, and showdata( ) for displaying their values. These functions provide the only access
to the data members from outside the class. This means that the data cannot by accessed by any function
that is not a member of the class item.

Creating Objects:

Once the class has been declared, we can create variables of that type by using the class name. For
example:

item x;

creates a variable x of type item. In C++, the class variables are known as objects. Therefore x is called
an object of type item.

We may also declare more than one object in one statement. For example,

item x, y, z;

The declaration of the object is similar to that of a variable of any basic type.

15
Accessing Class Data Members and Member functions

The private data of a class can be accessed only through the member functions of that class. The main()
cannot contains statements that access number and cost directly. The following is the format of calling
a member function.

object-name function-name(actual-arugments);

For example, the function call statement

x.getdata(100,75.5);

is valid and assigns the value 100 to number and cost of the object x by implementing the getdata( )
function.

Similarly, the statement

x.putdata();

would display the values of data members.

Defining Member Functions

Member function can be defined in two places:

1. Outside the class definition


2. Inside the class definition

1. Function Definition Outside the class definition: Member functions that are declared inside
a class have to be defined separately outside the class. Their definitions are very much like the
normal function. They should have a function header and a function body.

The general form of a member function definition is:

return-type class-name :: function-name (argument list)


{
Function Body
}

The membership label class-name:: tells the compiler that the function function-name belongs
to the class class-name. That is, the scope of the function is restricted to the class-name
specified in the header line. The symbol :: is called the scope resolution operator.

For example, consider the member function getdata( ) and showdata( ). They may be coded
as follows:

void item :: getdata(int a, float b)


{
number = a;
cost = b;
}

void item :: showdata()

16
{
cout<<”Number is :”<<number <<”\n”;
cout<<”Cost is :”<<cost<<”\n”;
}

Following program shows the concept of function definition outside the class:

Function definition outside the class


#include<iostream>
using namespace std;

class item
{
int number;
float cost;
public:
void getdata(int a, float b);
void showdata();
};

void item::getdata(int a, float b)


{
number=a;
cost=b;
}

void item::showdata()
{
cout<<"Number is "<<number<<"\n";
cout<<"Cost is "<<cost<<"\n";
}

int main()
{
item i;
i.getdata(20,45.55);
i.showdata();
return 0;
}

2. Function Definition Inside the Class Definition: Another method of defining a member
function is to replace the function declaration by the actual function definition inside the class.
For example, we could define the item class as follows:

class item
{
int number;
float cost:
public:
void getdata(int a, float b)
{
number=a;
cost=b;
}

void showdata()

17
{
cout<<”Number is “<<number<<”\n”;
cout<<”Cost is “<<cost<<”\n”;
}
}

Function definition inside the class

#include<iostream>
using namespace std;

class item
{
int number;
float cost;
public:
void getdata(int a, float b)
{
number=a;
cost=b;
}

void showdata()
{
cout<<"Number is "<<number<<"\n";
cout<<"Cost is "<<cost<<"\n";
}
};

int main()
{
item i;
i.getdata(10,25.45);
i.showdata();
return 0;
}

18
SECTION – B

1. FRIEND FUNCTION

The private members cannot be accessed from outside the class. That is, a non-member function cannot
have an access to the private data of class. However, there could be a situation where we would like
two classes to share a particular function. In such situations, C++ allows the common function to be
made friendly with both the classes, thereby allowing the function to have access to the private data of
these classes. Such a function need not be a member of any of these classes.

To make an outside function “friendly” to a class, we have to simply declare this function as a friend
of the class as shown below:

class ABC
{
…………………………
…………………………
public:
…………………………
…………………………
friend void xyz(void); // declaration
};

The function declaration should be preceded by the keyword friend. The function is defined elsewhere
in a program like a normal C++ function. The function definition does not use either the keyword friend
or the scope operator (::). A function can be declared as a friend in any number of classes. A friend
function although not a member function and has full access rights to the private members of the class.

Special Characteristics of friend function:

• It can be declared either in public or the private part of a class.


• It is not in the scope of the class to which it has been declared as friend.
• It cannot be called using the object of that class.
• It can be invoked like a normal function without the help of any object.
• Usually it has objects as arguments.
• Unlike member functions, it cannot access the member names directly and has to use an object
name and dot membership operator with each member name (e.g. A.x)

Friend Function with one class

#include<iostream>
using namespace std;
class sample
{
int a,b;
public:
void setvalue()
{
a=25;
b=40;
}

19
friend void mean(sample s)
{
float m=(s.a + s.b)/2.0;
cout<<"Mean value = "<<m;
}
};

int main()
{
sample x;
x.setvalue();
mean(x);
return 0;
}

The output of the above program is 32.5

The friend function accesses the class variables a and b by using the dot operator and the object passed
to it. The function call mean(x) passes the object x by value to the friend function.

A Function Friendly to Two Classes

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

class second;
class first
{
private:
int a;
public:
void get_a()
{
a=50;
}
friend int max(first,second);
};
class second
{
private:
int b;
public:
void get_b()
{
b=40;
}
friend int max(first, second);
};

int max(first f, second s) //definition of friend


{
if(f.a>s.b)
return(f.a);
else
return(s.b);
}

int main()
{
first F;
second S;
F.get_a();
S.get_b();

20
int val =max(F,S);
cout<<"Maximum value = "<<val;
return 0;
}

The output of the above program is 20

The function max() has arguments from both first and second classes. When the function max is
declared as a friend in first for the first time, the compiler will not acknowledge the presence of second
class unless its name is declared in the beginning as

class second;

This is known as forward declaration.

2. INLINE FUNCTION

One of the objectives of using functions in a program is to save some memory space. Every time a
function is called, it takes a lot of extra time in executing a series of instructions for tasks such as:

• Jumping to the function,


• saving registers,
• pushing arguments into the stack,
• and returning to the calling function.
When a function is small, a large percentage of executing time may be spent in such overheads.

To eliminate the cost of calls to small functions, C++ proposes a new feature called inline function. An
inline function is a function that is expanded in line when it is invoked. The inline function is defined
as follows:

inline int cube(int a)


{
return(a*a*a);
}

The above inline function can be invoked by statement like:

c = cube(3);

On the execution of above statement, the value of c will be 27.

It is easy to make a function inline. But we should exercise care before making the function inline. The
speed benefits of inline function reduce as the function grows in size.

Some of the situations where inline expansion may not work are:

• For function returning values, if a loop, a switch or a goto exists.


• For a function not returning values, if a return statement exists.

21
• If function contains static variables.
• If inline functions are recursive.

Program : Inline Functions


#include<iostream>
using namespace std;

inline float mul(float x, float y)


{
return(x*y);
}

int main()
{
float a=12.345;
float b=9.82;
cout<<mul(a,b);
return 0;
}

The output of the above program would be

121.28

3. STATIC DATA MEMBERS

A data member of a class can be qualified as static. A static member variable has certain special
characteristics. These are:
• It is initialized to zero when the first object of its class is created. No other initialization in
permitted.
• Only one copy of that member is created for the entire class and is shared by all the objects of
that class.
• It is visible only within the class, but its lifetime is the entire program.

Static variables are normally used to maintain values common to the entire class. Following program
illustrates the use of a static data member.

Program : Static Data Member


#include<iostream>
using namespace std;
class item
{
static int cnt;
int number;
public:
void getdata(int a)
{
number=a;
cnt ++;
}
void getcount()
{
cout<<"count : "<<cnt<<"\n";
}
};

22
int item :: cnt;

int main()
{
item a,b,c;
a.getcount();
b.getcount();
c.getcount();

a.getdata(100);
b.getdata(200);
c.getdata(300);

a.getcount();
b.getcount();
c.getcount();

return 0;
}
The output of the above program is :

count:0
count:0
count:0

count:3
count:3
count:3

The static variable cnt is initialized to zero when the objects are created. The cnt is incremented
whenever the getdata() function is called. Since the getdata() function is called three times by three
different objects, the count is incremented three times. Because there is only one copy of cnt is shared
by all three objects, all the three output statements cause the value 3 to be displayed. The following
figure shows how a static variable is used by the objects.

Object 1 Object 2 Object 3


number
100 number number
200 300

cnt
3

The type and scope of each static member variable must be defined outside the class definition. This is
necessary because the static data members are stored separately rather than as a part of an object. Since
they are associated with the class itself rather than with any class object, they are known as class
variables.

23
4. STATIC MEMBER FUNCTION

A member function that is declared as static has the following properties:

• A static function can have access to only other static members (functions or variables) declared
in the same class.
• A static member function can be called using the class name (instead of its objects) as follows:
class-name::function-name;

Following program illustrates the implementation of these characteristics.

Static Member Function


#include<iostream>
using namespace std;
class test
{
int code;
static int cnt;
public:
void setcode()
{
code=++cnt;
}
void showcode()
{
cout<<"Object Number :"<<code<<"\n";
}
static void showcount()
{
cout<<"count : "<<cnt<<"\n";
}
};

int test::cnt;

int main()
{
test t1,t2,t3;
t1.setcode();
t2.setcode();

test::showcount(); //accessing static function

t3.setcode();

test::showcount();

t1.showcode();
t2.showcode();
t3.showcode();

return 0;
}

The output of the above program is

count : 2
count : 3
Object Number :1
Object Number :2
Object Number :3

24
5. FUNCTION OVERLOADING

Overloading refers to the use of the same thing for different purposes. C++ permits overloading of
functions. This means that we can use the same function name to create functions that perform a variety
of different tasks.

Using the concept of function overloading, we can design a number of functions with one function name
but with different argument lists. The function would perform different operations depending on the
argument list in the function call. The correct function to be invoked is determined by checking the
number and type of argument. For example, an overloaded add( ) function handles different types of
data as shown below:

//Declarations
int add(int a, int b); //prototype 1
int add(int a, int b, int c); //prototype 2
double add(double x, double y); //prototype 3
double add(int p, double q); //prototype 4
double add(double p, int q); //prototype 5

//Function calls
cout << add(5,10); //uses prototype 1
cout << add(15, 10.0); //uses prototype 4
cout << add(12.5, 7.5); //uses prototype 3
cout << add(5, 10, 15); //uses prototype 2
cout << add(0.75, 5); //uses prototype 5

A function call first matches the prototype having the same number and type of arguments and then
calls the appropriate function for execution.

Function Overloading

#include<iostream>
#include<conio.h>
using namespace std;
int area(int, int);
int area(int);
float area(float);
int main()
{

int l,b,s, ar_rec, ar_sq;


float r, ar_cir;
cout<<"Enter the length and breadth of rectangle :";
cin>>l>>b;
ar_rec=area(l,b);
cout<<"Area of rectangle is : "<<ar_rec<<endl;
cout<<"Enter the side of square :";
cin>>s;
ar_sq=area(s);
cout<<"Area of square is : "<<ar_sq<<endl;
cout<<"Enter the radius of circle :";
cin>>r;
ar_cir=area(r);
cout<<"Area of circle is : "<<ar_cir<<endl;
return 0;
}

int area(int length, int breadth)


{
return (length*breadth);

25
}

int area(int side)


{
return (side*side);
}

float area(float radius)


{
return(3.1416*radius*radius);
}

The output of the above program is :

Enter the length and breadth of rectangle : 2 4


Area of rectangle is : 8
Enter the side of square : 4
Area of square is : 16
Enter the radius of circle : 2
Area of circle is : 12.5664

6. ARRAY OF OBJECTS

We know that an array can be of any data type. Similarly, we can also have array of type class. Such
variables are called array of objects. Consider the following example:

class employee
{
char name[20];
int age;
public:
void getdata();
void showdata();
};

The identifier employee is a user-defined data type and can be used to create objects that relate to
different employees. For Example:

employee emp[3];

The array emp contains five objects namely emp[0], emp[1], and emp[2]. Since an array of objects
behaves like any other array, we can use the usual array-accessing methods to access individual
elements, and then the dot membership operator to access the member functions. For example, the
statement

for(int i=0;i<3;i++)
{
emp[i].getdata();
}

will enter the data of 3 employees of the array emp.

26
name
emp[0]
age

name
emp[1]
age
name
emp[2]
age

Array of Objects

#include<iostream>
using namespace std;
class employee
{
char name[20];
int age;
public:
void getdata()
{
cout<<"Enter name :";
cin>>name;
cout<<"Enter age :";
cin>>age;
}
void putdata()
{
cout<<"Name : "<<name<<"\n";
cout<<"Age : "<<age<<"\n";
}
};

int main()
{
employee emp[3];
cout<<"Enter the details of Employees :"<<"\n";
for(int i=0;i<3;i++)
{
emp[i].getdata();
}
cout<<"The detail of employees are :"<<"\n";
for(int i=0;i<3;i++)
{
emp[i].putdata();
}
return 0;
}
The output of the above program is:

Enter the details of employees :


Enter name : amit
Enter age : 34
Enter name : Rohan
Enter age : 44
Enter name : Suman

27
Enter age : 33

The detail of employees are :


Name : amit
Age : 34
Name : Rohan
Age : 44
Name : Suman
Age : 33

7. OBJECTS AS FUNCTION ARGUMENTS

As variables of type int, char, float, double and the like can be passed to function as arguments, in the
similar way objects of a class can also be passed as argument to the function. The objects can be passed
in two ways:

1. Pass by value: In pass by value method, copy of actual object is passed to the function as an
argument. Actual object and its copy, both are stored in different memory locations. Thus, any
changes made to the copy of object don’t reflect in the actual object. By default, in a function,
an object of a class is passed as argument by using pass by value method.

Objects as Function Arguments using pass by value method


#include<iostream>
#include<conio.h>
using namespace std;
class time
{
private:
int hours, minutes;
public:
void gettime();
void showtime();
void sum(time,time);
};

void time::gettime()
{
cout<<"Enter the hours and minutes :";
cin>>hours>>minutes;
}
void time::showtime()
{
cout<<"hours = "<<hours<<" minutes = "<<minutes<<endl;
}

void time::sum(time t1, time t2)


{
minutes = t1.minutes + t2.minutes;
hours = minutes/60;
minutes = minutes%60;
hours = hours + t1.hours + t2.hours;
}

int main()
{
time T1,T2,T3;
T1.gettime();
T2.gettime();
T3.sum(T1,T2);
T1.showtime();
T2.showtime();

28
T3.showtime();
return 0;
}

The output of the above program is:

Enter the hours and minutes : 2 42


Enter the hours and minutes : 4 34
hours = 2 minutes = 42
hours = 4 minutes = 34
hours = 7 minutes = 16

2. Pass by Reference: Objects can also be passed to functions as an argument by using pass by
reference. In this method, alias of the passed object is created in the called function and not
the copy of the object. Thus any modifications performed to the reference object in the called
function are automatically updated in actual object passed also.

Objects as Function Arguments using pass by reference method

#include<iostream>
#include<conio.h>
using namespace std;
class time
{
private:
int hours, minutes;
public:
void gettime();
void showtime();
void sum(time,time);
};

void time::gettime()
{
cout<<"Enter the hours and minutes :";
cin>>hours>>minutes;
}
void time::showtime()
{
cout<<"hours = "<<hours<<" minutes = "<<minutes<<endl;
}

void time::sum(time &t1, time &t2)


{
minutes = t1.minutes + t2.minutes;
hours = minutes/60;
minutes = minutes%60;
hours = hours + t1.hours + t2.hours;
}

int main()
{
time T1,T2,T3;
T1.gettime();
T2.gettime();
T3.sum(T1,T2);
T1.showtime();
T2.showtime();
T3.showtime();
return 0;
}

29
PASS BY VALUE

Pass by value
#include<iostream>
using namespace std;
void swap(int, int);
int main()
{
int a,b;
cout<<"Enter values of a and b :";
cin>>a>>b;
swap(a,b);
cout<<"In main value of a is "<<a<<endl;
cout<<"In main value of b is "<<b<<endl;
return 0;
}
void swap(int a, int b)
{
int t;
t=a;
a=b;
b=t;
cout<<"In swap the value of a is "<<a<<endl;
cout<<"In swap the value of b is "<<b<<endl;
}

Enter values of a and b : 4 5

In swap the value of a is 5


In swap the value of b is 4

In main value of a is 4
In main value of b is 5

PASS BY REFERENCE

Pass by Reference
#include<iostream>
using namespace std;
void swap(int &, int &);
int main()
{
int a,b;
cout<<"Enter values of a and b :";
cin>>a>>b;
swap(a,b);
cout<<"In main value of a is "<<a<<endl;
cout<<"In main value of b is "<<b<<endl;
return 0;
}
void swap(int &a, int &b) //values pass by reference
{
int t;
t=a;
a=b;
b=t;
cout<<"In swap the value of a is "<<a<<endl;
cout<<"In swap the value of b is "<<b<<endl;
}

30
The output of the above program is:

Enter values of a and b : 4 5

In swap the value of a is 5


In swap the value of b is 4

In main value of a is 5
In main value of b is 4

POINTERS TO OBJECT

Pointers can point to objects as well as to simple data types and arrays. We’ve seen many examples of
objects defined and given a name, in statements like

Distance dist;

where an object called dist is defined to be of the Distance class.

Sometimes, however, we don’t know, at the time that we write the program, how many objects we want
to create. When this is the case we can use new to create objects while the program is running. As we’ve
seen, new returns a pointer to an unnamed object. Let’s look at a short example program, that compares
the two approaches to creating objects.

Pointers to Objects
#include <iostream>
using namespace std;

class Distance
{
private:
int feet;
float inches;
public:
void getdist()
{
cout << “\nEnter feet: “;
cin >> feet;
cout << “Enter inches: “;
cin >> inches;
}
void showdist()
{
cout << feet << “ feet ” << inches << “ inches”;
}
};

int main()
{
Distance dist;
dist.getdist();
dist.showdist(); //with dot operator

Distance* distptr; //pointer to Distance


distptr = new Distance; //points to new Distance object
distptr->getdist(); //access object members
distptr->showdist(); // with -> operator

return 0;
}

31
CONSTRUCTOR

A constructor is a special member function whose task is to initialize the objects of its class. It is special
because its name is same as the class name. A constructor is invoked whenever the object of its
associated class is created. It is called constructor because it constructs the values of data members of
the class.

Example:

class integer
{
int m,n;
public:
integer() //constructor
{
m=0;
n=0;
}
}

When a class contains a constructor, an object created by the class will be initialized automatically. For
example:

integer i1;

The above instruction will create the object i1 as well as initializes its data members m and n to zero.
There is no need to write any statement to invoke the constructor function.

SPECIAL CHARACTERISTICS OF CONSTRUCTOR FUNCTIONS

The constructor functions have some special characteristics. These are:

• They should be declared in the public section.


• They are invoked automatically when the objects are created.
• They do not have return types, not even void.
• They cannot be inherited.
• They can have default arguments.
• Constructors cannot be virtual.
• We cannot refer to their addresses.
• An object with a constructor cannot be used as a member of a union.

TYPES OF CONSTRUCTORS

• Default Constructor: A constructor that accepts no parameters is called the default constructor.

32
• Parameterized Constructor: A constructor that can take arguments is called parameterized
constructor.

For example,

class integer
{
int m,n;
public:
integer(int x, int y) //parameterized constructor
{
m=x;
n=y;
}
}

When a constructor has been parameterized, we must pass the initial values as arguments to the
constructor function when an object is declared. We can pass the arguments in two ways:

• By calling the constructor implicitly.


• By calling the constructor explicitly.
The following statement call the parameterized constructor implicitly.
integer i1(10,100);

The following statement call the parameterized constructor explicitly.


integer i1 = integer(10,100);

Program : Class with parameterized constructor


#include<iostream>
using namespace std;
class integer
{
int m,n;
public:
integer(int x, int y)
{
m=x;
n=y;
}
void display()
{
cout<<"m = "<<m<<"\n";
cout<<"n = "<<n<<"\n";
}
};
int main()
{
integer i1(10,100); //constructor called implicitly
integer i2 = integer(25,75); //constructor called explicitly
cout<<"\nOBJECT 1"<<"\n";
i1.display();
cout<<"\nOBJECT 2"<<"\n";
i2.display();
return 0;
}

33
The output of the Program would be
OBJECT 1
m = 10
n = 100

OBJECT 2
m = 25
n = 75

COPY CONSTRUCTOR

A copy constructor is used to declare and initialize an object from another object. For example

integer i2(i1);

would define the object i2 and initialize it to the values of i1. Another form of this statement is:

integer i2 = i1;

A process of initializing through a copy constructor is known as copy initialization. A copy constructor
takes a reference to an object of the same class as itself as an argument.

Copy Constructor
#include<iostream>
using namespace std;
class code
{
int id;
public:
code(int a)
{
id = a;
}
code(code & a)
{
id = a.id;
}
void display()
{
cout<<id<<"\n";
}
};

int main()
{
code A(100);
code B(A); //copy constructor called
code C=A; //copy constructor called again
A.display();
B.display();
C.display();
}

The output of the above program is :


100
100
100

34
MULTIPLE CONSTRUCTORS IN A CLASS

We can use more than one constructor in a class. This concept is also known as constructor overloading.
Consider the following code:

class integer
{
int m,n;
public:
integer() //constructor 1
{
m=0;
n=0;
}

integer(int a, int b) //constructor 2


{
m=a;
n=b;
}

integer(integer & i) //constructor 3


{
m=i.m;
n=i.n;
}
};

This declares three constructors for an integer object. The first constructor receives no arguments, the
second receives two integer arguments and the third receives one integer object as an argument. For
example, the declaration

integer i1;

would automatically invoke the first constructor and set both m and n of i1 to zero.

The statement

integer i2(20,40);

would call the second constructor which will initialize the data members m and n of i2 to 20 and 40
respectively.

Finally the statement

integer i3(i2);

would invoke the third constructor which copies the values of i2 to i3. In other words, it sets the value
of every data element of i3 to the value of the corresponding data element of i2.

35
Multiple Constructors in a Class (Constructor Overloading)
#include<iostream>
using namespace std;
class integer
{
int m,n;
public:
integer() //constructor 1
{
m=0;
n=0;
}

integer(int a, int b) //constructor 2


{
m=a;
n=b;
}

integer(integer & i) //constructor 3


{
m=i.m;
n=i.n;
}

void display()
{
cout<<"m = "<<m<<"\n";
cout<<"n = "<<n<<"\n";
}
};

int main()
{
integer i1;
integer i2(20,40);
integer i3(i2);
cout<<"Constructor 1 :"<<"\n";
i1.display();
cout<<"Constructor 2 :"<<"\n";
i2.display();
cout<<"Constructor 3 :"<<"\n";
i3.display();
}

The output of the above program is

Constructor 1 :
m = 0
n = 0
Constructor 2 :
m = 20
n = 40
Constructor 3 :
m = 20
n = 40

36
DESTRUCTOR

A destructor as the name implies, is used to destroy the objects that have been created by a constructor.
Like a constructor, a destructor is a member function whose name is the same as the class name but is
preceded by a tilde (~). For example, the destructor of a class integer can be defined as shown below:

~integer( )
{ }

A destructor never takes any argument nor does it returns any value. It will be invoked implicitly by the
compiler upon exit from the program to clean up the storage that is no longer accessible.

Characteristics of Destructor
1. Destructor has the same name as that of the class it belongs and preceded by ~ (tilde) sign.
2. Destructor invoked automatically when the object go out of the scope.
3. Destructor should be declared in public section.
4. Like Constructor, it cannot be declared as static and const.
5. Destructor cannot be overloaded as there can be only one destructor in the class.
6. Destructor has no return type, not even void.
7. Destructor cannot be inherited.
8. Destructor do not have any arguments or parameters.
9. Destructor can be virtual.

The following program shows the concept of destructor.

Destructor
#include<iostream>
using namespace std;

int cnt=0;

class test
{
public:
test()
{
cnt++;
cout<<"Object created "<<cnt<<"\n";
}
~test()
{
cout<<"Object destroyed "<<cnt<<"\n";
cnt--;
}
};
int main()
{
test t1,t2,t3;
return 0;
}

The output of the above program is:


Object created 1
Object created 2
Object created 3
Object destroyed 3
Object destroyed 2
Object destroyed 1

37
OPERATOR OVERLOADING

Operator overloading provides a flexible option for the creation of new definitions for most of the C++
operators. It is the main feature of C++. It is an important technique that enhanced the power of
extensibility of C++. We can overload all the C++ operators excepts the following:

• Class member access operators(. , .*).


• Scope resolution operator (::).
• Size operator (sizeof).
• Conditional operator (?:).

Defining Operator Overloading

To define an additional task to an operator, we must specify what is means in relation to the class to
which the operator is applied. This is done with the help of special function, called operator function,
which describes the task. The general form of an operator function is

return-type classname :: operator op(argument list)


{
Function body
}

where return-type is the type of value returned by the specified operation and op is the operator being
overloaded. operator op is the function name, where operator is a keyword.

Overloading Unary Operators

Consider the unary minus operator. A minus operator when used as unary, takes just one operand. We
know that this operator change the sign of an operand when applied to a basic data item. By using
operator overloading it can be applied to an object as same way as it is applied to an int or float variable.
The unary minus when applied to an object should change the sign of its data items.

Following program shows how the unary minus operator is overloaded.

Overloading Unary (-) Operator


#include<iostream>
using namespace std;
class space
{
int x,y,z;
public:
void getdata()
{
x=10;
y=-20;
z=30;
}
void display()
{
cout<<"x = "<<x<<"\n";
cout<<"y = "<<y<<"\n";
cout<<"z = "<<z<<"\n";
}
void operator-() //overlaod unary minus
{
x=-x;
y=-y;

38
z=-z;
}
};

int main()
{
space s;
s.getdata();
cout<<"Before Operator Overload :"<<"\n";
s.display();

-s; //activate operator-() function

cout<<"After Operator Overload:"<<"\n";


s.display();
}

The output of the above program is:

Before Operator Overload :


x = 10
y = -20
z = 30
After Operator Overload:
x = -10
y = 20
z = -30

Overloading Binary Operator

Binary operators can also be overloaded like unary operators. Binary operators work on two operands.
Only single parameter is passed to operator function.

Overloading Binary (+) Operator


#include<iostream>
using namespace std;

class complex
{
float x,y;
public:
complex()
{}
complex(float real, float imag)
{
x=real;
y=imag;
}
complex operator+(complex c)
{
complex temp;
temp.x = x + c.x;
temp.y = y + c.y;
return(temp);
}
void display()
{
cout<<x<<" + j"<<y<<"\n";
}
};

int main()
{

39
complex c1,c2,c3;
c1=complex(2.5, 3.5);
c2=complex(1.6, 2.7);
c3=c1+c2;
cout<<"c1 = ";
c1.display();
cout<<"c2 = ";
c2.display();
cout<<"c3 = ";
c3.display();

return 0;
}

The output of the above program is

c1 = 2.5 + j3.5
c2 = 1.6 + j2.7
c3 = 4.1 + j6.2

The operator+ function is expected to add two complex values and return a complex value as the
results but receives only one value as argument.

Consider the following statement:

C3 = C1 + C2; // invokes operator+( ) function

We know that the member function can be invoked only by an object of the same class. Here, the object
C1 takes the responsibility of invoking the function and C2 plays the role of an argument that is passed
to the function. The above invocation statement is equivalent to

C3 = C1.operator+(C2); //usual function call syntax

Therefore, in the operator+( ) function, the data members of C1 are accessed directly and the data
members of C2 (that is passed to an argument) are accessed using the dot operator. Thus, both the
objects are available for the function. For example, in the statement

temp.x = x + c.x;

c.x refers to the object C2 and x refers to the object C1.temp.x is the real part of temp that has been
created specially to hold the results of addition of C1 and C2. The function returns the complex temp
to be assigned to C3.

40
TYPE CONSVERSIONS

Type conversion is required when an expression consists of different types of variables and constants.
Same type of variables does not require any conversion. For implicit data types, compiler automatically
performs conversion known as implicit conversion. To perform explicit type conversion, cast operator
is used by programmer to direct the compiler to convert of one basic type to another. These conversions
are easily understood by the compiler. But the compiler has no idea about the user-defined data types
and their conversion from one type to another, therefore to perform this type of conversion, the
programmer needs to write the separate function that convert basic type to user-defined type or vice
versa.

Three types of situations might arise in the data conversion between incompatible types:
1. Conversion from basic type to class type
2. Conversion from class type to basic type.
3. Conversion from one class type to another class type.

1. Conversion from basic type to class type:

The conversion from basic type to class type is easy to accomplish. It may be performed with the
help of constructor with one parameter. These should be the member functions of the class and
receive parameter of basic type. The constructor receives parameter of basic type and converts that
into user-defined type. This is accomplished by following statement:

time t = minutes;

i.e. left hand side operand of = sign must be of class type and right hand operand must be of basic
type.

To understand the conversion from basic from user-defined type, let us consider the following
program

Conversion from basic type to class type


#include<iostream>
using namespace std;

class rupee
{
int r, p;
public:
rupee(int m)
{
r=m/100;
p=m%100;
}

void display()
{
cout<<"Rupees is "<<r<<" and paise "<<p;
}
};

int main()
{
int paise=1550;
rupee r1 = paise; //type conversion from basic to user-defined
r1.display();

41
return 0;
}

The output of the above program is :

Rupees is 15 and paise 50

2. Conversion from class type to basic type

To perform this type of conversion, member function is written by the programmer. Member
function consists of number of instructions which convert user-defined data into basic type of data.
This is also known as Overloading of Typecast operator. To overload the cast operator function
specify the keyword operator followed by the data-type to which you convert data in its declaration.
This function must be a class member function.

The general form of an overloaded casting operator function, usually referred to as a conversion
function, is

operator typename()
{
. . . . .
Function statements
. . . . .
}

Here typename is any of the basic datatype and this function does not have any return type not even
void.

When call for this function is made, compiler will first search from main( ) for the keyword operator
followed by data-type and conversion function will execute. It does not take any parameter. It is
necessary that left hand side operand must be of basic type and right hand side operand must be of
user defined data-type.

The following program shows the concept of class to basic type conversion:

Conversion from class type to basic type


#include<iostream>
using namespace std;

class rupee
{
int r, p, paise;
public:
rupee(int rs, int ps)
{
r=rs;
p=ps;
}

operator int()
{
paise=(100*r)+p;
}

};

42
int main()
{
int pa;
rupee r1(20,50);
pa=r1;
cout<<"Money in paise is:"<<pa<<”paise”;
return 0;
}

The output of the above program is

Money in paise is : 2010 paise

3. Conversion from one classtype to another class type

We can also convert objects of one class type to another class type. Consider the following statement:

objX = objY; //objects of different types

objX is an object of class X and objY is an object of class Y. The class Y type data is converted to Class
X type data and the converted value is assigned to the objX. Since the conversion takes place from class
Y to class X, Y is known as the source class and X is known as the destination class.

Such conversions between objects of different classes can be carried out in two ways:

1. by using constructor or
2. a conversion function.

The compiler treats them the same way.

The following program shows this concept

Conversion from one class type to another class type


#include<iostream>
using namespace std;

class celsius
{
float c;
public:
celsius(float cs)
{
c=cs;
}
celsius()
{
c=0.0;
}
void display()
{
cout<<"Temperature in Celsius is :"<<c;
}

};

class farenheit
{
float cel, f;
public:

43
farenheit(float fn)
{
f=fn;
}

operator celsius()
{
cel=(f-32.0)*(5.0/9.0);
return(cel);
}
};

int main()
{
farenheit f(90);
celsius c;
c=f;
c.display();
return 0;
}

The output of the above program is :

Temperature in Celsius is :32.2222

44
SECTION - C

INHERITANCE

Reusability is an important feature of Object Oriented Programming. C++ strongly supports the concept
of reusability. This is basically done by creating a new class, reusing the properties of the existing ones.
The mechanism of deriving a new class from an old one is called inheritance. The old class is referred
to as the base class and the new one is called the derived class.

TYPES OF INHERITANCE

There are five types of inheritance:

1. Single Inheritance: A derived class with only one base class is called single inheritance.

2. Multiple Inheritance: A derived class with several base classes is called multiple inheritance.

3. Hierarchical Inheritance: A base class with several derived classes is called hierarchical
inheritance.

4. Multiple Inheritance: The mechanism of deriving a class from other derived class is called
multiple inheritance.

5. Hybrid Inheritance: The combination of more than one type of inheritance is called hybrid
inheritance.

DEFINING DERIVED CLASS

A derived class can be defined by specifying its relationship with the base class in addition to its own
details. The general form of defining a derived class is:

class derived-class-name : visibility-mode base-class-name


{
………………………………………
Members of derived class
………………………………………
}

45
The colon (:) indicates that the derived-class-name is derived from the base-class-name. The visibility
mode is optional and if given, it may be either private or public. The default visibility mode is private.

- When the base class is privately inherited by a derived class, public members of the base class
become private members of the derived class and therefore the public members of the base class
can only be accessed by the member functions of the derived class. They are inaccessible to the
objects of the derived class.

- When the base class is publicly inherited by the derived class, public members of the base class
become public members of the derived class and therefore they are accessible to the objects of
the derived class.

- In both cases, the private members of the base class are not inherited, therefore the private
members of the base class will never become the members of its derived class.

SINGLE INHERITANCE

• Single Inheritance (Public): Following program shows the concept of single inheritance with
public visibility mode.
Program : Single Inheritance by Public derivation
#include<iostream>
using namespace std;
class student
{
int roll_no;
char name[20];
public:
void getdata()
{
cout<<"Enter the roll number and name of student :";
cin>>roll_no>>name;
}
void showdata()
{
cout<<"Roll Number is "<<roll_no<<"\n";
cout<<"Name is "<<name<<"\n";
}
};

class marks : public student //public derivation


{
int m1,m2;
public:
void getmarks()
{
cout<<"Enter the marks in two subjects :";
cin>>m1>>m2;
}
void showmarks()
{
cout<<"Marks of Subject 1 is "<<m1<<"\n";
cout<<"Marks of Subject 2 is "<<m2<<"\n";
}
};

int main()
{
marks m;

46
m.getdata();
m.showdata();
m.getmarks();
m.showmarks();
return 0;
}

The output of the above program would be


Enter the roll number and name of student : 34 rohit
Roll number is 34
Name is rohit
Enter the marks in two subjects : 55 66
Marks of Subject 1 is 55
Marks of Subject 2 is 66

The class marks is a public derivation of the base class student. Therefore, marks inherit all the public
members of class student. Thus the public members of the base class student is also a public members
of the derived class marks. The private members of student class cannot be inherited by the class
marks.

• Single Inheritance (Private): The following program shows the concept of single inheritance
with private derivation.
Program : Single Inheritance by Private derivation
#include<iostream>
using namespace std;
class student
{
int roll_no;
char name[20];
public:
void getdata()
{
cout<<"Enter the roll number and name of student :";
cin>>roll_no>>name;
}
void showdata()
{
cout<<"Roll Number is "<<roll_no<<"\n";
cout<<"Name is "<<name<<"\n";
}
};

class marks : private student //public derivation


{
int m1,m2;
public:
void getmarks()
{
getdata(); //private function calling
cout<<"Enter the marks in two subjects :";
cin>>m1>>m2;
}
void showmarks()
{
showdata(); //private function calling
cout<<"Marks of Subject 1 is "<<m1<<"\n";
cout<<"Marks of Subject 2 is "<<m2<<"\n";
}
};

47
int main()
{
marks m;
m.getmarks();
m.showmarks();
return 0;
}

The output of the program is same as the previous one.

Enter the roll number and name of student : 34 rohit


Roll number is 34
Name is rohit
Enter the marks in two subjects : 55 66
Marks of Subject 1 is 55
Marks of Subject 2 is 66

MULTILEVEL INHERITANCE

The mechanism of deriving a class from another derived class is known as multilevel inheritance. This
means in multilevel inheritance; a derived class becomes base class of another derived class and so on.
Each derived class must have a kind of relationship with its immediate base class. To implement this
kind of inheritance at least three classes are required.

A Base Class

B Intermediate Base Class

C Derived Class

The class A serves as a base class for the derived class B, which in turn serves as a base class for the
derived class C. The B is known as intermediate base class since it provides a link for the inheritance
between A and C. The chain A-B-C is known as inheritance path.

Following program shows the concept of Multilevel Inheritance.

MULTILEVEL INHERITANCE
#include<iostream>
using namespace std;
class student
{
int roll_no;
char name[20];
public:
void getdata()
{
cout<<"Enter the roll number and name of student :";
cin>>roll_no>>name;
}
void showdata()
{
cout<<"Roll Number is "<<roll_no<<"\n";

48
cout<<"Name is "<<name<<"\n";
}
};

class marks : public student


{
public:
int m1,m2;
void getmarks()
{
cout<<"Enter the marks in two subjects :";
cin>>m1>>m2;
}
void showmarks()
{
cout<<"Marks of Subject 1 is "<<m1<<"\n";
cout<<"Marks of Subject 2 is "<<m2<<"\n";
}
};

class result : public marks


{
private:
int total;
public:
void display()
{
total = m1 + m2;
cout<<"The result is "<<total;
}
};
int main()
{
result r;
r.getdata();
r.showdata();
r.getmarks();
r.showmarks();
r.display();
return 0;
}

The output of the above program is

Enter the roll number and name of student : 34 rohit


Roll number is 34
Name is rohit
Enter the marks in two subjects : 55 66
Marks of Subject 1 is 55
Marks of Subject 2 is 66
The Result is 121

MULTIPLE INHERITANE

It is a process of deriving a new class from multiple base classes. A class can inherit the attribute of two
or more classes. Multiple inheritance allows us to combine the features of several existing classes for
defining new classes. In this derived class must have a kind of relationship with its base class. In the
figure, there are two base classes base1 and base2 and a derived class derived.

49
Base1 Base2

Derived

The syntax of a derived class with multiple base classes is as follows:

class Derived : visibility Base1, visibility Base2


{
. . . . .
. . . . .
}

where visibility may be either public or private. The base classes are separated by commas.

Example:

class P : public M, public N


{
public:
void display();
};

where M and N are base classes and P is derived class.

The following program shows the concept of Multiple Inheritane

Multiple Inheritance
#include<iostream>
using namespace std;

class M
{
protected:
int m;
public:
void get_m()
{
m=20;
}
};

class N
{
protected:
int n;
public:
void get_n()
{
n=10;
}
};

class P : public M, public N


{
int total;

50
public:
void display()
{
total=m+n;
cout<<"m + n = "<<total;
}
};

int main()
{
P obj;
obj.get_m();
obj.get_n();
obj.display();
return 0;

AMBIGUITY IN MULTIPLE INHERITANCE

Occasionally, we may face a problem in using the multiple inheritance, when a function with the same
name appears in more than one base class, Consider the following two classes:

class A
{
public:
void display()
{
cout<<”display() in class A”;
}
};

class B
{
public:
void display()
{
Cout<<”display() in class B”;
}
};

class C : public A, public B


{
public:
void display()
{
cout<<”display() in derived class “;
}
};

which display( ) function is used by derived class when we inherit these two classes? We can solve this
problem by defining a named instance using the class resolution operator with the function as shown
below:
int main()
{
C obj; //derived class object
obj.display(); //invokes display() in derived class C
obj.A::display(); //invokes display() in base class A
obj.B::display(); //invokes display() in base class B
return 0;
}

51
Following program shows how to resolve ambiguity in multiple inheritance

Ambiguity in Multiple Inheritance


#include<iostream>
using namespace std;
class A
{
public:
void display()
{
cout<<"Display function of class A "<<"\n";
}
};

class B
{
public:
void display()
{
cout<<"Display function of class B "<<"\n";
}
};

class C : public A, public B


{
public:
void display()
{
cout<<"Display function of class C "<<"\n";
}
};

int main()
{
C obj;
obj.display();
obj.A::display();
obj.B::display();
return 0;
}

HIERARCHICAL INHERITANCE

The properties of one class may be inherited by more than one class. This process is known as
hierarchical inheritance. In this type of inheritance base class has all the properties and methods that are
common to the inherited classes.

Hierarchical inheritance follows one-to-many relationship in which multiple classes can be derived.

Base

Derived 1 Derived 2 Derived n

52
Following program shows the concept of hierarchical inheritance

Hierarchical Inheritance
#include<iostream>
using namespace std;
class person
{
char name[20];
long int contact_no;

public:
void getdata()
{
cout<<"Enter the name :";
cin>>name;
cout<<"Enter the contact number :";
cin>>contact_no;
}
void showdata()
{
cout<<"Name is "<<name<<"\n";
cout<<"Contact No. is "<<contact_no<<"\n";
}
};

class student:public person


{
int rollno;
char course[10];
public:
void get_stdinfo()
{
getdata(); //use getdata() function of person class
cout<<"Enter the roll number :";
cin>>rollno;
cout<<"Enter the course name :";
cin>>course;
}
void show_stdinfo()
{
showdata(); //use showdata() function of person class
cout<<"Roll No. is "<<rollno<<"\n";
cout<<"Course is "<<course<<"\n";
}
};

class employee:public person


{
int empid;
char designation[20];
public:
void get_empinfo()
{
getdata();
cout<<"Enter the employee id :";
cin>>empid;
cout<<"Enter the designation :";
cin>>designation;
}
void show_empinfo()
{
showdata();
cout<<"Employee id is "<<empid<<"\n";
cout<<"Designation is "<<designation<<"\n";
}
};

53
int main()
{
student s;
employee e;
cout<<"Enter the student details :"<<"\n";
s.get_stdinfo();
cout<<"\nThe student details are :"<<"\n";
s.show_stdinfo();
cout<<"\nEnter the employee details :"<<"\n";
e.get_empinfo();
cout<<"\nThe employee details are :"<<"\n";
e.show_empinfo();
}

The output of the above program is:

Enter the student details :

Enter the name :Rajvir


Enter the contact number :112234455
Enter the roll number :23
Enter the course name :BCA

The student details are :

Name is Rajvir
Contact No. is 112234455
Roll No. is 23
Course is BCA

Enter the employee details :

Enter the name :sonu


Enter the contact number :33333333
Enter the employee id :321
Enter the designation :teacher

The employee details are :

Name is sonu
Contact No. is 33333333
Employee id is 321
Designation is teacher

HYBRID INHERITANCE

Hybrid inheritance means to implement more than one form of inheritance like multiple, multilevel etc.
This form of inheritance is used when we want to use features of different classes in some other classes.
Hybrid inheritance allows us to derive a class from another derived class using multiple base classes.

The following diagram shows the concept of hybrid inheritance. It shows the combination of multilevel
and multiple inheritance

54
student

marks practical

result

The following program shows the implementation of hybrid inheritance

Hybrid Inheritance
#include<iostream>
using namespace std;
class student
{
int roll_no;
char name[20];
public:
void getdata()
{
cout<<"Enter the roll number and name of student :";
cin>>roll_no>>name;
}
void showdata()
{
cout<<"Roll Number is "<<roll_no<<"\n";
cout<<"Name is "<<name<<"\n";
}
};

class marks : public student


{
public:
int m1,m2;
void getmarks()
{
cout<<"Enter the marks in two subjects :";
cin>>m1>>m2;
}
void showmarks()
{
cout<<"Marks of Subject 1 is "<<m1<<"\n";
cout<<"Marks of Subject 2 is "<<m2<<"\n";
}
};

class sports
{
public:
int sp_marks;
void getspmarks()
{
cout<<"Enter the marks in sports :";
cin>>sp_marks;
}
void showspmarks()
{
cout<<"The marks in sports is "<<sp_marks<<"\n";

55
}
};

class result : public marks, public sports


{
private:
int total;
public:
void display()
{
total = m1 + m2 + sp_marks;
cout<<"The result is "<<total<<"\n";
}
};
int main()
{
result r;
r.getdata();
r.showdata();
r.getmarks();
r.showmarks();
r.getspmarks();
r.showspmarks();
r.display();
return 0;
}

The output of the above program would be:

Enter the roll number and name of student : 34 rohit


Roll number is 34
Name is rohit
Enter the marks in two subjects : 55 66
Marks of Subject 1 is 55
Marks of Subject 2 is 66
Enter the marks in sports : 66
The marks in sports is 66
The Result is 187

VIRTUAL BASE CLASS

Consider the following multipath inheritance:

student

theory practical

student

Inheritance by the ‘result’ class as shown in figure might pose some problems. All the public and
protected members of student class are inherited into ‘result’ twice, first via ‘theory’ class and again via
‘practical’ class. This means that ‘result’ would have duplicate sets of the members inherited from
‘student’. This introduces ambiguity and should be avoided.

56
The duplication of inherited members due to these multiple paths can be avoided by making the
common base class as a virtual base class. When a class is made a virtual base class, only one copy
that class is inherited, regardless of how many inheritance paths exist between the virtual base class
and a derived class.

Virtual Base Class


#include<iostream>
using namespace std;
class student
{
protected:
int roll_no;
public:
void getdata()
{
cout<<"Enter the Roll Number :";
cin>>roll_no;
}
void showdata()
{
cout<<"Roll Number is "<<roll_no<<"\n";
}
};

class theory : virtual public student


{
protected:
int m1, m2;
public:
void getmarks()
{
cout<<"Enter the marks in two subjects :";
cin>>m1>>m2;
}
void showmarks()
{
cout<<"Marks in Subject 1 is "<<m1<<"\n";
cout<<"Marks in Subject 2 is "<<m2<<"\n";
}
};

class practical : virtual public student


{
protected:
int p;
public:
void getpractical()
{
cout<<"Enter the practical marks :";
cin>>p;
}
void showpractical()
{
cout<<"Marks in Practical is "<<p<<"\n";
}
};

class result : public theory, public practical


{
int total;
public:
void display()
{
total=m1+m2+p;
cout<<"Result is "<<total<<"\n";

57
}
} ;

int main()
{
result r;
r.getdata();
r.getmarks();
r.getpractical();
r.showdata();
r.showmarks();
r.showpractical();
r.display();
return 0;
}

The output of the above program is:

Enter the Roll Number : 45


Enter the marks in two subjects : 44 77
Enter the practical marks : 55
Roll Number is 45
Marks in Subject 1 is 44
Marks in Subject 2 is 77
Marks in Practical is 55
Result is 176

58
POLYMORPHISM

Polymorphism is one of the important feature of OOP. It simply means ‘one name, multiple forms’.
The concept of polymorphism is implemented using the overloaded functions and operators. The
overloaded member functions are selected for invoking by matching arguments, both type and number.
This information is known to the compiler at the compile time and therefore compiler is able to select
the appropriate function for a particular call at the compile time itself. This is called early binding or
static binding. It is also known as compile time polymorphism.

Now, consider the following situation where the function name and prototype is the same in both the
base and derived classes. For example, consider the following class definition:

class A
{
int x;
public:
void show()
{
. . . .
}
};

class B
{
int y;
public:
void show()
{
. . . .
}
};

How do we use the member function show() to print the values of objects of both the classes A and B?
Since the prototype of show() is the same in both the places, the function is not overloaded and therefore
static binding does not apply.

It would be nice if the appropriate function could be selected while the program in running. This is
known as run time polymorphism. C++ supports a mechanism known as virtual function to achieve
run time polymorphism.

At run time, when it is known what class objects are under consideration, the appropriate version of the
function is invoked. Since the function is linked with a particular class much later after the compilation,

59
this process is termed as late binding. It is also known as dynamic binding because the selection of the
appropriate function is done dynamically at run time.

Dynamic Binding is one of the powerful feature of C++. This requires the use of pointers to objects.

Pointer is one of the key aspects of C++. It is a derived data type that refers to another data variable by
storing the variable’s memory address rather than data. A pointer variable defines where to get the value
of a specific data variable instead of defining actual data.

Declaring and Initializing Pointers:

The declaration of a pointer variable takes the following form:

data-type *pointer-variable

Here pointer-variable is the name of the pointer, and the data-type refers to one of the valid C++ data
types, such as int, char, and so on. The data-type is followed by an asterisk (*) symbol, which
distinguishes a pointer variable from other variables to the compiler.

POINTERS TO OBJECTS

A pointer can point to an object created by a class. Consider the following statement:

item x;

where item is a class and x is an object defined to be of type item. Similarly we can define a pointer
it_ptr of type item as follows:

item *it_ptr;

Object pointers are useful in creating objects at run time. We can also use an object pointer to access
the public members of an object.

Consider the following code:

class item
{
int code;
float price;
public:
void getdata(int a, float b)
{
code=a;
price=b;
}

void show()
{
cout<<”code is :”<<code<<endl;
cout<<”Price is :”<<price;
}
};

Let us declare an item variable x and a pointer ptr to x as follows:

60
item x;
item *prt = &x;

The pointer ptr is initialized with the address of x.

We can refer to the member function of item in two ways:

• One by using the dot operator and the object


• Another by using the arrow operator and the object pointer.

The following statements

x.getdata(100,75.50);
x.show()

are equivalent to

ptr->getdata(10075.50);
ptr->show();

We can also create objects using pointers and new operator as follows:

item *ptr = new item;

This statement allocates enough memory for the data members in the object structure and assigns the
address of the memory space to ptr. Then ptr can be used to refer to the members as shown below.

ptr->show();

We can also create an array of objects using pointers. For example, the statement

item *ptr = new item[10];

creates memory space for an array of 10 objects of item.

Pointer to Objects
#include<iostream>
using namespace std;

class item
{
int code;
float price;
public:
void getdata(int a, float b)
{
code=a;
price=b;
}

void show()
{
cout<<"Code is :"<<code;
cout<<"Price is :"<<price;
}
};

61
int main()
{
item *p = new item;

int x;
float y;

cout<<"enter the code and price for item :";


cin>>x>>y;
p->getdata(x,y);

cout<<"The code and price of item is :\n";


p->show();

return 0;
}

The output of the above program would be

Enter the code and price for item :444 56


The code and price of item is :
Code is :444
Price is :56

VIRTUAL FUNCTIONS

When we use the same function name in both the base and derived classes, the function in base class is
declared as virtual using the keyword virtual preceding its normal declaration. When a function is made
virtual, C++ determines which function to use at run time based on the type of object pointed to by the
base pointer, rather than the type of the pointer. Thus, by making the base pointer to point to different
objects, we can execute different version of the virtual function.

Following program shown the concept of virtual functions

Virtual Functions
#include<iostream>
using namespace std;

class Base
{
public:
void display()
{
cout<<"\n Display base ";
}

virtual void show()


{
cout<<"\n Show base ";
}
};

class Derived : public Base


{
public:
void display()
{
cout<<"\n Display Derived ";

62
}
virtual void show()
{
cout<<"\n Show Derived ";
}
};

int main()
{
Base B;
Derived D;

Base *bptr;

cout<<"\n bptr points to Base \n";


bptr=&B;
bptr->display();
bptr->show();

cout<<"\n bptr points to Derived \n";


bptr=&D;
bptr->display();
bptr->show();

return 0;
}

The output of the above program would be

bptr points to Base

Display base
Show base

bptr points to Derived

Display base
Show Derived

Rules for virtual functions:

• The virtual functions must be members of some class.


• They cannot be static members;
• They are accessed by using object pointers.
• A virtual function can be a friend of another class.
• A virtual function in a base class must be defined, even though it may not be used.
• The prototypes of the base class version of a virtual function and all the derived class must be
identical. If two functions with the same name have different prototypes, C++ considers them
as overloaded functions, and the virtual function mechanism is ignored.
• We cannot have virtual constructors, but we can have virtual destructor.

63
PURE VIRTUAL FUNCTION

It is normal practice to declare a function virtual inside the base class and redefine it in the derived
classes. The function inside the base class is rarely used for performing any task. It only serves as a
placeoholder. Such functions are called do-nothing functions.

A “do-nothing” function may be defined as follows:

Such functions are called pure virtual functions. A pure virtual function is a function declared in a base
class that has no definition relative to the base class. In such cases, the compiler requires each derived
class to either define the function or redeclare it as a pure virtual function. A class containing pure
virtual functions cannot be used to declare any objects of its own. Such classes are called abstract base
classes.

Following program shows the concept of Pure Virtual Functions.

Pure Virtual Function


#include<iostream>

using namespace std;

class Base //Abstract base class


{
public:
virtual void show() = 0; //Pure Virtual Function
};

class Derived:public Base


{
public:
void show()
{
cout << "Implementation of Virtual Function in Derived class";
}
};

int main()
{

Base *b;
Derived d;
b = &d;
b->show();
}

The output of the above program would be

Implementation of virtual function in Derived class

64
SECTION – D

EXCEPTION HANDLING

The two most common type of errors in C++ programs are logic errors and syntactic errors. The logic
error occurs due to poor understanding of the problem and solution procedure. The syntactic errors arise
due to poor understanding of the language itself.

Exceptions are the run time anomalies or unusual conditions that a program may encounter while
executing. These anomalies might include conditions such as division by zero, access to an array
outside to its bounds or running out of memory or disk space. When a program encounters an
exceptional condition, it is important that it is identified and dealt with effectively.

The purpose of the exception handling mechanism is to provide means to detect and report an
“exceptional circumstance” so that appropriate action can be taken. The mechanism suggests a separate
error handling code that performs the following tasks:

1. Find the problem (Hit the Exception).


2. Inform that an error has occurred (Throw the Exception).
3. Receive the error information (Catch the Exception).
4. Take corrective action (Handle the Exception).

ERROR HANDLING MECHANISM

C++ exception handling mechanism is basically built upon three keywords namely try, throw and catch.

The keyword try is used to preface a block of statements surrounded by braces which may generate
exceptions. This block of statements is known as try block.

When an exception is detected, it is thrown using a throw statement in the try block.

A catch block defined by the keyword catch. It catches the exception thrown by the throw statement in
the try block, and handles it appropriately.

The relationship is shown in following figure.

65
When the try block throws an exception, the program control leaves the try block and enters the catch
statement of the catch block. The exceptions are objects used to transit information about a problem. If
the type of object thrown matches the arg type in the catch statement, then catch block is executed for
handling the exception. If they do not match, the program is aborted with the help of the abort()
function, which is invoked by default. When no exception is detected and thrown, the control goes to
the statement immediately after the catch block. That is, the catch block is skipped.

THROWING MECHANISM

When an exception that is desired to be handled to be detected, it is thrown using throw statement in
one of the following forms:

throw(exception);
throw exception;
throw;

The object exception may be of any type, including constants. It is also possible to throw objects not
intended for error handling.

When an exception is thrown, t will be caught by the catch statement associated with the try block.
That is the control exits the current try block, and is transferred to the catch block after the try block.

CATCHING MECHANISM

The code for handling exceptions is included in catch blocks. A catch block looks like a function
definition and is of the form

catch (type arg)


{
//statements for managing exceptions
}

The type indicates the type of exception that catch block handles. The parameter arg is an optional
parameter name. The exception-handling code is placed between two braces. The catch statement
catches an exception whose type matches with the type of catch argument.

SIMPLE TRY-CATCH MECHANISM

The following program shows the simple try-catch mechanism.

Simple try-catch mechanism


#include<iostream>
using namespace std;

int main()
{
int a,b,div;
cout<<"Enter the values of a and b :";
cin>>a>>b;

try
{
if(b==0)
throw (b);

66
else
cout<<"Division is : "<<a/b;
}

catch(int i)
{
cout<<"Division by zero is not allowed ";
}
return 0;

The output of the above program is:

First Run

Enter the values of a and b : 20 5


Division is 4

Second Run

Enter the values of a and b : 10 0


Division by zero is not allowed

Program detects and catches a division-by-zero problem. The output of the first run shows a successful
execution. When no exception is thrown, the catch block skipped. In the second run, the denominator b
becomes zero, and therefore a division-by-zero situation occurs. The exception is thrown using the
object b. Since the exception object is and int type, the catch statement containing int type argument
catches the exception and displays necessary message.

MULTIPLE CATCH STATEMENTS

It is possible that a program segment has more than one condition to throw an exception. In such cases
we can associate more than one catch statement with a try as shown below:

try
{
//try block
}

catch(type1 arg)
{
// catch block 1
}

catch(type2 arg)
{
// catch block 2
}

. . . . . .
. . . . . .

67
catch(typeN arg)
{
//catch block N
}

When an exception is thrown, the exception handlers are searched in-order for an appropriate match.
After finding a match, the control goes to the concerned catch block. When no match is found, the
program is terminated.

Following program shows the concept of multiple catch statements

Multiple Catch Statements


#include<iostream>
using namespace std;

void test(int x)
{
try
{
if(x==1)
throw x; //int
else if(x==0)
throw 'x'; //char
else if(x==-1)
throw 1.0; //double
}

catch(char c)
{
cout<<"Caught a character \n";
}

catch(int m)
{
cout<<"Caught an integer \n";
}

catch(double d)
{
cout<<"Caught a double \n";
}
cout<<"End of try-catch statement \n\n";
}

int main()
{
cout<<"Testing multiple catches :\n";
cout<<"x==1\n";
test(1);
cout<<"x==0\n";
test(0);
cout<<"x==-1\n";
test(-1);
cout<<"x==2\n";
test(2);

return 0;
}

68
The output of the above program is:

Testing multiple catches :


x==1
Caught an integer
End of try-catch statement

x==0
Caught a character
End of try-catch statement

x==-1
Caught a double
End of try-catch statement

x==2
End of try-catch statement

The program when executed, invokes the function test( ) with x=1 and therefore throws x an int
exception. This matches the type of the parameter m in catch2 and therefore catch2 handler is executed.
Immediately after the execution, the function test( ) is again invoked with x=0. This time the function
throws ‘x’, a character type exception and therefore the first handler is executed. Finally the handler
catch3 is executed when a double type exception is thrown.

When the try block does not throw any exceptions and it completes normal execution,

CATCH ALL EXCEPTIONS

In some situations, we may not be able to predict all possible types of exceptions and therefore may not
be able to design independent each catch handlers to catch them. In such circumstances, we can force
a catch statement to catch all exceptions instead of a certain type. This could be achieved by defining
the catch statement using ellipses as follows:

catch(...)
{
//statements for processing all exceptions
}

The following program shows the concept of catch all exceptions

Catch all Exceptions


#include<iostream>
using namespace std;

void test(int x)
{
try
{
if(x==0)
throw x; //int
if(x==-1)
throw 'x'; //char
if(x==1)
throw 1.0; //float

69
}

catch(...)
{
cout<<"Caught an exception \n";
}
}

int main()
{
cout<<"Testing Generic Catch \n";
test(-1);
test(0);
test(1);

return 0;
}

The output of the above program is:

Testing Generic Catch


Caught an exception
Caught an exception
Caught an exception

RETHROWING AN EXCEPTION

A handler may decide to rethrow the exception caught without processing it. In such situations, we may
simply invoke throw without any arguments as shown below:

throw;

This causes the current exception to be thrown to the next enclosing try/catch sequence and is caught
by a catch statement listed after that enclosing try block.

Following program shows the concept of rethrown and caught.

Rethrown an Exception
#include<iostream>

using namespace std;

void divide(double x, double y)


{
cout<<"Inside function \n";
try
{
if(y==0.0)
throw y;
else
cout<<"Division = "<<x/y<<"\n";
}

catch(double)
{
cout<<"Caught double inside function \n";

70
throw;
}

cout<<"End of function \n\n";


}

int main()
{
cout<<"Inside main \n";
try
{
divide(10.5,2.0);
divide(20.0,0.0);
}
catch(double)
{
cout<<"Caught double inside main \n";
}
cout<<"End of main \n";
return 0;
}

The output of the above program is

Inside main
Inside function
Division = 5.25
End of function

Inside function
Caught double inside function
Caught double inside main
End of main

When an exception is rethrown, it will not be caught by the same catch statement or any other catch in
that group. Rather, it will be caught by an appropriate catch in the outer try/catch sequence only.

A catch handler itself may detect and throw an exception. Here again, the exception thrown will not be
caught by any catch statements in that group. It will be passed on to the next outer try/catch sequence
for processing.

71

You might also like