Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
23 views

Object Oriented Programming - C++ (DCA1203)

1. The document discusses object-oriented programming concepts, including the evolution of programming methodologies from machine-level languages to modern OOP languages like C++. 2. It compares procedural programming in C to object-oriented programming in C++, noting major differences like C++'s inclusion of objects, classes, inheritance, and other OOP features. 3. The core concepts of OOP like objects, classes, inheritance, polymorphism and encapsulation are introduced as the basic features supported by OOP languages.

Uploaded by

Atul Anil
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Object Oriented Programming - C++ (DCA1203)

1. The document discusses object-oriented programming concepts, including the evolution of programming methodologies from machine-level languages to modern OOP languages like C++. 2. It compares procedural programming in C to object-oriented programming in C++, noting major differences like C++'s inclusion of objects, classes, inheritance, and other OOP features. 3. The core concepts of OOP like objects, classes, inheritance, polymorphism and encapsulation are introduced as the basic features supported by OOP languages.

Uploaded by

Atul Anil
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 345

Object Oriented Programming – C++ Unit 1

Unit 1 Overview of OOP Concepts


Structure:
1.1 Introduction
Objectives
1.2 Evolution of Programming Methodologies
1.3 Difference between C and C++
1.4 Introduction to OOP and its basic features
1.5 Basic components of a C++ program and program structure
Data types
Variables: declaration & definition
Tokens of C++: Identifiers, Keywords, Constants, Operators
Identifiers
Keywords
Constants
Operators
Operators: expressions
C++ I/O Methods: cin, cout
Structure of C++ programs
1.6 Compiling and Executing C++ Program
Simple C++ program
1.7 Summary
1.8 Terminal Questions
1.9 Answers

1.1 Introduction
C++ is a general-purpose Object Oriented Programming (OOP) language.
C++ includes features of object-oriented programming as well as
conventional procedural programming. The major aim of developing object-
oriented programming language is to remove some of the flaws
encountered in programming a language of procedural approach. Object-
Oriented Programming enables one to put data and functions in one
container. This container is referred to as an object. An object enables you
to model your application as closely as possible to the real world.
In this unit, we will discuss the basic features of object-oriented
programming. In this unit, we also discuss the evolution of programming

Manipal University Jaipur B2114 Page No.: 1


Object Oriented Programming – C++ Unit 1

methodologies, difference between C and C++, basic components of C++


programming. Finally, we discuss the process of compilation and execution
of C++ programs.
Objectives:
After studying this unit, you should be able to:
 describe the role of object oriented programming approach over
procedural languages
 discuss the basic features supported by OOP languages
 describe the data types of a C++ program
 define the terms ‘keyword’, ‘constant’, ‘identifiers’ and ‘operators’
 explain the process of compilation and execution

1.2 Evolution of Programming Methodologies


Computer performs a variety of tasks with the help of programming
languages. The first version of a programming language was the machine-
level language. During the1940s, the machine-level language, which used
the binary codes of 0s and 1s to represent computer instructions, was
developed. Machine-level language is also known as low-level programing
language. Writing programs in machine language is symbolic, and had to be
error prone (which is impractical). So, assembly languages were developed
in the early 1950s. Assembly languages use mnemonics to write the
instruction of a program.
First high level programming language known as FORTRAN was developed
in the year 1957. During the 1960s, many high level languages were
developed to support the needs of various disciplines like science and
engineering, and business. The period between 1970 and 1980 was actually
the golden era for the development of high-level programming languages.
During 1970, a procedural programming language named PASCAL was
developed. The C programming language was developed by Dennis Ritchie
at the Bell Labs during the year 1973. In 1980, Bjarne Stroustrup, from the
Bell labs, began the development of the C++ language.
The idea of object-oriented programming gained momentum in the 1970s
and in the early 1980s. Bjorn Stroustrup integrated the object-oriented
programming into the C language. C++ is a superset of C. Several features
are similar in C and C++. At this time, many new features like object, class,

Manipal University Jaipur B2114 Page No.: 2


Object Oriented Programming – C++ Unit 1

inheritance, virtual functions and function overloading were added.


Therefore, there is a ‘++’ symbol in C++. The ++ operator in the C++ means
many new features were added around this time. The most notable features
are - object, class, inheritance, virtual functions and function overloading.
Limitations of procedural languages:
Procedural languages focused on organizing program statements into
procedures or functions. Larger programs were either broken into functions
or modules which had defined purpose and interface to other functions.
Procedural approach for programming had several problems as the size of
the software grew larger and larger. One of the main problems was that of
the data being completely forgotten. The emphasis was on the action and
the data was only used in the entire process. Data in the program was
created by variables, and if more than one function had to access data, then
global variables were used. The concept of global variables itself is a
problem as it may be accidentally modified by an undesired function. This
also leads to difficulty in debugging and modifying the program when
several functions access a particular data.
The object Oriented approach overcomes this problem by modeling data
and functions together, thereby allowing only certain functions to access the
required data.
The procedural languages had limitations of extensibility as there was
limited support for creating user-defined data types and defining how these
datatypes are to be handled. For example, it would be difficult if the
programmer had to define his own version of string, and define how this
new datatypes will be manipulated. The Object Oriented Programming
provides this flexibility through the concept of class.
Another limitation of the procedural languages is that the program model is
not closer to real world objects. For example, if you want to develop a
gaming application of car race, what data you would use and what functions
you would require are difficult questions to answer in the procedural
approach. The object oriented approach solves this further by
conceptualizing the problem as group of objects which have their own
specific data and functionality. In the car game, for example we would
create several objects such as player, car, and traffic signal and so on.

Manipal University Jaipur B2114 Page No.: 3


Object Oriented Programming – C++ Unit 1

Some of the languages that use object oriented programming approach are
C++, Java, Csharp, Smalltalk etc. We will be learning C++ in this Self
Learning Material (SLM) to understand the object oriented programming.

1.3 Difference between C and C++


C is a general purpose programming language. C has a flexible and
compact structure. Programs written in C tend to consist of many small
functions. C++ is derived from C Language. C++ is a procedural programing
language with object-oriented extensions. That means, you can design and
code programs using procedural approach.
The main difference between C and C++ is, that C++ is an object oriented
programming language while C supports only procedure-oriented
programming language. The main benefit of object oriented programming
paradigm is that it focuses on writing programs that are more readable and
maintainable. It also helps the reuse of code by packaging a group of similar
objects, or using the concept of component programming model. The
limitations of the procedural language are discussed in section 1.2.
The major difference between C and C++ are listed below:
 C has a top-down approach whereas c++ has a bottom-up approach.
 In C, a character constant is automatically elevated to an integer
whereas in C++ this is not the case.
 In C++, identifiers are not allowed to contain two or more consecutive
underscores in any position. C identifiers cannot start with two or more
consecutive underscores, but may contain them in other positions.
 For an int main () in C++ we may not write a return statement but the
return is mandatory in C if we are using an int main ().
 C input/output is based on library files, and the processes are carried
out by including functions. The input and ouput (I/O) command is made
through console commands ‘cin’ and ‘cout’ in C++.
 In C++, undeclared functions are not allowed. The function has to have
a prototype defined before the main () before use in C++ although in C
the functions can be declared at the point of use.
 C structures have a different behavior compared to C++ structures.
 After declaring structures and enumerators in C, we cannot declare the
variable for the structure right after the end of the structure as in C++.

Manipal University Jaipur B2114 Page No.: 4


Object Oriented Programming – C++ Unit 1

Self Assessment Questions


1. Who developed C++ language?
a. Dennis Ritchie b. Bjorn Stroustrup
c. James Gosling d. Charles Babbage
2. Assembly languages use ___________ to write the instruction of a
program.
3. In C, a character constant is automatically elevated to an ________
datatype, whereas in c++ this is not the case.

1.4 Introduction to OOP and its Basic Features


Objected Oriented Programming (OOP) is considered as important as the
development of high level languages. As discussed earlier, one of the basic
concepts in Object Oriented Programming is that it enables you to put data
and functions in one unit, referred to as an object. The functions of a
particular object can only access the data in the object providing high level
of security for the data. The functions in the object are known as member
functions or sometimes called ‘methods’.
The basic features of OOP language are:
i) Objects
ii) Classes
iii) Inheritance
iv) Polymorphism
v) Encapsulation
i) Objects
An Object is the programming representation of the real world entity.
According to Pressman, the Objects can be any one of the following:
a) External entities
b) Things
c) Occurrences or events
d) Roles
e) Organisational units
f) Places
g) Data Structures
Objects can have both attributes (data) and behaviours (functions or
methods). Attributes describe the object with respect to certain parameters

Manipal University Jaipur B2114 Page No.: 5


Object Oriented Programming – C++ Unit 1

and behavior or functions to describe the functionality of the object. Table


1.1 shows some examples of objects.
Table 1.1: Examples of Objects

Polygon Object Bank Account


Attributes Behaviour Attributes Behaviour
Position Move Account number Deduct Funds
Fill Color Erase Balance Transfer funds
Border color Change color Deposit Funds
Show balance

ii) Classes
Class is a group of objects that have the same properties and common
behavior. A class is a category of things. An object is a specific item that
belongs to a class called ‘instance of class’.
A class defines the characteristics of its objects and the methods that can
be applied to its objects. Objects with the same data structure and behavior
are grouped together as class. Classes are templates that provide definition
to the objects of similar type. Objects are like variables created whenever
necessary in the program. For example, student may be a class and John,
James, Peter are objects of the class ‘student’. It is similar to the creation of
variables of a default datatype such as integer- you can create any number
of objects of a class.
iii) Inheritance
Inheritance is a technique through which one object acquires the properties
of another. The technique also supports hierarchical classification. It is a
powerful feature of OOP. It is a mechanism of deriving a new class from an
old class, and of inheriting all the characteristics and behaviours of the old
class.
The main advantage of Inheritance is "code reusability". The ability to reuse
components of a program is an important feature for any programming
language.
iv) Polymorphism
Polymorphism is the ability to present the same interface in different forms.
Polymorphism means “many forms of a single object”. Operator overloading
Manipal University Jaipur B2114 Page No.: 6
Object Oriented Programming – C++ Unit 1

is a kind of polymorphism. An operation may exhibit different behaviors in


different instances. The behavior depends on the data types used in the
operation.
The purpose of polymorphism is to implement a style of programming called
‘message-passing’. When objects want to communicate with each other,
they do so in terms of messages. Message passing is a method by which an
object sends data to another object, or requests the other object to invoke a
method.
v) Encapsulation
Encapsulation is used to bind code and data together. Wrapping of data and
methods into a single unit is called ‘encapsulation’. The result of
encapsulation is data-hiding. It contains hiding information about an object.
Ex: Private variable can be accessed only within the class. Encapsulation is
also known as ‘data hiding’.
OOP approach offers several advantages to programmers in these ways:
 The main advantage of an OOP is that it enables to model complex
systems of real world into manageable software solutions.
 Object-oriented programming language can create extended and
reusable parts of programs.
 OOP is easy to maintain and modify a code.
 OOP provides a good framework for code libraries.
Self Assessment Questions
4. A _________ defines the characteristics of its objects, and the
methods that can be applied to its objects.
5. ________ is a technique in which one object acquires the properties of
another object.
6. Encapsulation is also known as _________.
7. _______ is a method by which an object sends data to another object,
or requests the other object to invoke method.

1.5 Basic Components of a C++ Program and Program Structure


We have already learnt that C++ is a superset of C. At the basic level, the
programs look similar in both C and C++. Every statement in C++ ends with
a semicolon (;). All the reserved words have to be written in the small case,
and the C++ compiler is case sensitive.
Manipal University Jaipur B2114 Page No.: 7
Object Oriented Programming – C++ Unit 1

1.5.1 Data types


A data type in a programming language is a set of data with values having
predefined characteristics. Like C language, C++ also supports different
data types. C++ language supports the following data types: char, int, float,
double. The basic datatypes have various modifiers preceding them. The list
of modifiers are: signed, unsigned, long and short. The datatypes supported
in C++ are listed below:
Table 1.2: Basic Datatypes in c++

Data Type Size (in bytes) Values that can be taken


Signed int 2 -32768 to 32767
unsigned int 2 0 to 65535
Signed Char 1 -128 to 127
unsigned char 1 0 to 255
-38 38
Float 4 3.4 X 10 to 3.4 X 10 (Precision 7)
-308 308
Double 8 1.7 X 10 to 1.7 X 10 (Precision 15)
-4932 4932
long double 10 3.4 X 10 to 1.1 X 10 (Precision 19)
long int 4 -2147483648 to 2147483647
short int 2 -31768 to 32767

1.5.2 Variables
Variable is a container of data i.e. Variables are names used to refer to
some memory location. Variables can be named according to the following
rules:
 Variable name must begin with a letter.
 Variable name contains letters, numbers and underscore.
 Variable names are case sensitive.
 Reserve words of C++ cannot be used
Declaration and definition of variables:
Variables have to be declared before being used in the program. Variable
declaration tells the compiler the name and datatype of the concerned
variable. General syntax of declaration of variable is
Datatype variablename;
Example: int p;

Manipal University Jaipur B2114 Page No.: 8


Object Oriented Programming – C++ Unit 1

The above declaration declares an integer variable named p. you can


declare multiple variables of the same type in a single statement by
separating them with commas. The Datatype of a variable optionally
initializes the variable to a specific value. Values can be assigned to the
variable during declarations, or can be initialized separately using the
assignment operator equal (=).
Example: int P=4, Q=8;
Or
int P, Q;
P=4; Q=8
1.5.3 Token of C++: Identifiers, Keywords, Constants, Operators
A programmer uses C++ tokens to write a program. C++ supports the
following types of tokens: identifiers, keywords, constants and operators.
1.5.3.1 Identifiers
Identifiers are used to define a name. They are mostly used to name
variables (ex: array, structure), functions, class etc. Every language uses its
own rules for naming the identifiers. In C++, identifiers can be named
according to the following rules:
 Only alphabets, digits, characters and underscores are permitted.
 A name cannot start with a digit.
 An identifier cannot start with a symbol.
 Keywords cannot be used as an identifier.
Some examples for valid identifiers are:
Name, first_name, last_name
1.5.3.2 Keywords
Keywords are also known as ‘reserve words’. Many keywords are common
to C as well C++. All Keywords have a specific meaning and purpose.
Some of the C++ keywords are: auto, break, catch, class, delete, do, for,
new, int, long, mutual, public, protected, return, size of, signed, void, while.
1.5.3.3 Constants
The constants in C++ can be a numeric, a character or string constants. The
value of a constant does not change during the program. You should
initialize a constant value when you create it.
Example: const int data=10;

Manipal University Jaipur B2114 Page No.: 9


Object Oriented Programming – C++ Unit 1

Here ‘const’ allows you to create constants. The value of data is fixed during
the entire program.
1.5.3.4 Operators
C++ has a rich set of operators. C++ supports all C operators. In C++,
operators are used to perform a specific operation on a set of operands in
an expression. Operators supported in C++ are listed below.
1. Arithmetic operators (+,-, *,/, %, ++,- -)
2. Relational operators (>,<, >=, <=, ==, !=)
3. Logical Operators (&&, ||, !)
4. Bit-wise operators (&, |. ^, ~ )
There are a few other operators supported by C++ language: sizeof, the
conditional operator and the cast operator. In later units, we will discuss in
detail these additional operators.
1.5.4 Operators: expressions
An expression is a sequence of operators and operands, used for
computation. Expression evaluation may produce a result (example:
evaluation of 2+2 produces the result 4).
i. Arithmetic operators: C++ provides five simple arithmetic operators for
creating arithmetic expressions. Table 1.3 below illustrates these arithmetic
operators with example. If the value of X=6 and Y=3, results for the
arithmetic operations are shown in Table 1.3.
Table 1.3: Arithmetic operators in C++

Operator Description Example


+ Used to add two operands X+Y will give result 9
- Used to subtract second operand X-Y will give result 3
from the first
* Used to multiply both operands X *Y will give result 18
/ Used to perform division operation X/ Y will give result 2
% Module operator, it gives reminder of X%Y will give result 0
integer Division
++ Increment operator, increase integer X++ will give value 7
value by one
-- Decrement operator, decreases X- - will give value 5
integer value by one

Manipal University Jaipur B2114 Page No.: 10


Object Oriented Programming – C++ Unit 1

ii. Relational operators:


Relational operators are binary operators. Relational operators test data
values against one other, and return the value as either 1 (true) or 0 (false).
The Table 1.4 illustrates relational operators with example. In example
consider X=10 and Y=20.

Table 1.4: Relational operators in C++

Operator Description Example


> Verifies whether the value of the left (X>Y) is not true
operand is greater than the value of the
right operand; if yes, then the condition
become true.
< Verifies whether the value of the left (X<Y )is true
operand is less than the value of the right
operand; if yes, then the condition
becomes true.
>= Verifies whether the value of the left (X>=Y) is not true
operand is greater than or equal to the
value of the right operand; if yes, then the
condition result is true.
<= Verifies whether the value of the left (X<=Y) is not true
operand is less than or equal to the value
of the right operand; if yes, then the
condition result is true.
== Verifies whether the values of two (X==Y) is not true
operands are equal or not; if equal, then
condition result is true.
!= Verifies whether the values of two (X!=Y) is true
operands are equal or not; if not equal,
then condition result is true.

iii. Logical Operators:


Logical operators are used to combine multiple conditions, or to compare
boolean expressions. The Table 1.5 illustrates logical operators with
example. In the example given below, assume that variable X holds binary
one (1) and variable Y holds binary zero (0).

Manipal University Jaipur B2114 Page No.: 11


Object Oriented Programming – C++ Unit 1

Table 1.5: Logical operators in C++

Operator Description Example


&& Logical AND operator. If both the operands are (X && Y)
non-zero, Result is False
Then condition becomes true.
|| Logical OR operator. If any of the two operands (X || Y)
are non-zero, then the condition becomes true. Result is True
! Logical NOT operator: used to reverse the (! X)
logical states i.e. Result is False
If the condition is true, then logical NOT
operator will make it false.
If the condition is false, then logical NOT
operator will make it true.

iv) Bitwise operators:


Bitwise operators modify variables considering the bit patterns that
represent the values.
Bitwise AND (&) and bitwise OR (|) work similarly to their logical AND and
logical OR counterparts. However, rather than evaluating a single boolean
value, they are applied to each bit. Of all the bitwise operators, the bitwise
NOT operator (~) is perhaps the easiest to understand. It simply flips each
bit from a 0 to a 1, or vice versa. Bitwise exclusive-or (^) performs the
exclusive-or operation on each pair of bits. Exclusive-or is commonly
abbreviated as XOR. The exclusive-or operation takes two inputs and
returns a 1 if either of the inputs is a 1, but not if both are. That is, if both
inputs are 1 or both inputs are 0, it returns 0.
The Table 1.6 illustrates Bitwise logical operators with example. Let us
assume that variable X holds binary value 5 (101) and variable Y holds
binary 6 (110), then the result in the example column would be as given in
table 1.6.

Manipal University Jaipur B2114 Page No.: 12


Object Oriented Programming – C++ Unit 1

Table 1.6: Bitwise logical operators in c++

Operator Description Example


& When evaluating bitwise AND, if all bits in a (X & Y)
column are 1, the result for that column is 1. Result is 100
| When evaluating bitwise OR, if any bit in a column (X | Y)
is 1, the result for that column is 1. Result is 111
^ When evaluating bitwise XOR, if there is an odd (X ^ Y)
number of 1 bits in a column, the result for that Result is 011
column is 1.
~ When evaluating bitwise NOT, it toggles each bit (~ X)
from 0 to a 1, or vice versa Result is 010

1.5.5 C++ I/O Methods: cin, cout


In every C++ program, it is compulsory to include “iostream.h” header file.
The header file “iostream.h” defines the cin, cout, objects, which correspond
to the standard input stream and the standard output stream respectively.
The cin statement is used for standard input or for input from keyboard, and
the cout is used for standard output or for output- to- display screen.
The cin and cout are actually predefined objects in C++. Iostream.h file
contains the declarations for the cin and cout statements.
cout (pronounced as C out) uses << or insertion operator to push data to the
output stream.
cin (pronounced as c in statement) uses >> or extraction operator to feed
the data to the input stream.
There are several such header files which have to be included, depending
on the functions you are using. We will come across many such header files
as we progress.
1.5.6 Structure of C++ programs
Every programming language consists of different sections. Some of the
sections are optional and some are mandatory. The structure of C++
program supports different sections as shown in figure 1.1.

Manipal University Jaipur B2114 Page No.: 13


Object Oriented Programming – C++ Unit 1

Documentation section
Header file section
Class declaration or definition section
Class function definition section
Main () function section
Figure 1.1: Basic Structure of C ++ program

1. First section, the documentation section, is optional, and is used to put


comments for the program. Comment statements can be included in the
program by prefixing the statement with “//” for single-line comments.
Comments add clarity to the program. Multiple line comments can be
added by enclosing the statements between /* and */.
2. Second section includes various header files required by C++ program.
3. Class declaration section: in this section declaration of class is done.
User can declare class before or after main () section, but it is a good
practice to declare it before main () function.
4. Class function definition: Class function definition can be done either
inside or outside the class. When function is large, it is a good practice
to define it outside the class.
5. Every C++ program starts with function main (). Program without main ()
function won’t be executed; it is a compulsory section.
Like C, C++ too allows you to create your own functions in the program.
However, the program execution always begins with the master function
main (). Parentheses are used to group statements belonging to one
function or program statement. Every opening parenthesis ({ ) should have
a matching closing parenthesis ( }).
We will discuss in detail class declaration and class function definition
sections in unit 4.
Self Assessment Questions
8. All the reserved words have to be written in small case and the C++
compiler is case sensitive. (True/False)
9. Keywords are also known as _________.
10. __________ are used to combine multiple conditions or to compare
boolean expressions.

Manipal University Jaipur B2114 Page No.: 14


Object Oriented Programming – C++ Unit 1

11. The header file ___________ defines the cin, cout, and objects.
12. ______________ Statement is used for standard output or for output-
to- display screen.
13. Documentation section is optional, and is used to put ________ for the
program.
14. ___________ are used to group statements belonging to one function
or program statement.

1.6 Compiling and Executing C++ Program


There are three stages in executing a C++ program. They are: Compiling,
Linking and Running the program.
Compiling:
Compiling is a process of converting source code to machine code.
Each .cpp file is a program file which is also known as source file, and when
it is compiled, you get an object file with extension .obj.
The c++ programs have to be typed in computer. Your program file is saved
with an extension .cpp. This is known as ‘source code’. The C++ compiler
takes source code as its input and if there are no errors, it produces a
machine code of your program, which is saved in a disk file with the same
name, but with extension .obj. Compilation process translates program file
in to object file, which is a machine-readable code.
C++ programs can be implemented on different Operating systems (ex:
Windows, UNIX, DOS, etc.). In market, various types of compilers are
available. Some of them are: GNU C++, Borland C++, Zortech C++, NDP
C++, etc.
Linking:
Linking is an essential process when executing the program. The role of a
linker is to link the files and functions required and used by programs. The
object codes of these programs and the library files are linked to create a
single executable file. For example, if the programmer uses clrscr (), then
the object code of the function should be brought from “conio.h” header file.
When the linking process is completed, the program code generates
executable file.

Manipal University Jaipur B2114 Page No.: 15


Object Oriented Programming – C++ Unit 1

Running the program:


Third and the last stage is running the executable file, where the statements
in the program will be executed one by one.
Fig. 1.2 shows the entire process. When you execute the program, the
compiler displays the output of the program and comes back to the program
editor. To view the output, wait for the user to press any key to return to the
editor and type getch() as the last statement in the program. Getch() is an
inbuilt predefined library function which inputs a character from the user
through standard input. However, you should include another header file
named conio.h to use this function. Conio.h contains the necessary
declarations for using this function. The include statement will be similar to
iostream.h.

Figure 1.2: Execution process of C++ program

During compilation, if there are any errors, they will be listed by the compiler.
The errors may be any one of the following:
1. Syntax error
Syntax error is an error in the structure or spelling of a statement. It
occurs when the program code breaks the basic syntax rules of C++
statement, as, for instance, in the wrong use of reserved words,
improper variable names, variables without declaration etc. Further
examples of syntax errors are- missing semi colon or parenthesis, type
integer for int datatype etc. Often, syntax error message indicates the

Manipal University Jaipur B2114 Page No.: 16


Object Oriented Programming – C++ Unit 1

approximate location of error; and the statement number is displayed to


help the programmer. You can see the statement, make correction/s to
the program file, save and recompile it.
2. Logical error
This error occurs due to some flaw in the logic. Logical error occurs
when you use a statement that is syntactically correct, but doesn’t do
what you need. The compiler doesn't identify when any logical error
happens in the program. When compared to syntax error, finding a
logical error is time-consuming for the programmer. However, it can be
traced using the debug tool in the editor.
3. Linker error
Linker error occurs when the files go missing during linking. Linker error
implies that the linker is unable to build an executable program from the
object code you provided. The following can be an example for a linker
error-supposing you have used a function print, if the linker cannot find
the function in any libraries that you have declared, then it is a linker
error.
4. Runtime error
Runtime error occurs during the execution of a program. If the program
performs invalid operation during execution of the program, then runtime
errors are detected (ex: division by zero, accessing a null pointer etc.)
1.6.1 Simple C++ program
In this section, you will learn how to write a program in the C++
programming language. To write and execute C++ programs, you need to
have any text editor and C++ compiler. When a programmer writes a
program for the first time, he or she must make sure that the flow of the
program is followed by proper documentation. Example program is given
below, where the description would help you to understand compilation and
execution of programs. Only thing you need to do is just follow the steps in
the given order.
//First simple C++ program
#include <iostream.h>
void main()
{
cout<< " Welcome to the programming language C++";
}
Manipal University Jaipur B2114 Page No.: 17
Object Oriented Programming – C++ Unit 1

In the program shown above, #include<iostream.h> helps to stream


programming features.
The statement cout displays the output enclosed between quotations. After
finishing the writing of program, you have to compile and execute the
program in order to get output. If you are compiling using UNIX
environment, the program can be written in any text editor, and then you
should save the program with extension .cpp (ex: first.cpp). Once you have
saved the program, the next step is compilation. Compiler converts C++
program (first.cpp) to object code (first.obj). The General syntax of compiling
the program in UNIX environment is:
g++ first.cpp –o first
where first.cpp is the name of source file.
To execute the program, type ‘./first.’ Where first is the name of the
program. It will prompt the screen to command prompt and display the
output.
Let’s go through the general steps followed to compile and execute the
program:
Step 1: Download and install the C++ compilers.
Step 2: Type your C++ program and save your program (first.cpp)
Step 3: Next you need to compile your program.
Command to compile the program
g++ -c first.cpp
This will create an object file. To create an executable file type in:
g++ -o first.cpp
Step 4: To run the program, use the command below:
./first
SelfAssessment Questions
15. ________ is a process of converting source code to machine code.
16. _________ is an error in the structure or spelling of statement.
17. Runtime error occurs during the _______ of program.
18. After finishing writing the program, in order to get output you have to
_____ and then execute the program.
19. Each .cpp file that you compile produces an ________ file.

Manipal University Jaipur B2114 Page No.: 18


Object Oriented Programming – C++ Unit 1

1.7 Summary
Let us recapitulate the important points discussed in this unit:
 Computer performs a variety of tasks with the help of programming
languages. In 1980, Bjarne Stroustrup, from Bell labs, began the
development of the C++ language.
 C++ is a superset of C. Several features are similar in C and C++.
Object-oriented Programming (OOP) is considered as important as the
development of high level languages. The basic features of OOP
language are: Objects, Classes, Inheritance. Polymorphism,
Encapsulation.
 Object-oriented Programming enables storing of data and functions
together, which in turn enables hiding of data from unnecessary
exposure.
 A class defines the characteristics of its objects and the methods that
can be applied to its objects. The main advantage of Inheritance is
"code reusability".
 C++ language supports following data types: char, int, float, double. A
programmer uses C++ tokens to write a program.
 C++ supports the following types of tokens: identifiers, keywords,
constants and operators. An expression is a sequence of operators and
operands, used for computation.
 The header file “iostream.h” defines the cin, cout, objects, which
correspond to the standard input stream and the standard output stream
respectively.
 To write and execute C++ programs, you need to have a text editor and
C++ compiler. In market various types of compilers are available: GNU
C++, Borland C++, Zortech C++, NDP C++, etc.

1.8 Terminal Questions


1. Explain the following features of Object-oriented Programming.
a. Encapsulation b. Inheritance c. Polymorphism
2. What do you understand by constant, keyword and identifier?
3. Describe the various datatypes available in C++?

Manipal University Jaipur B2114 Page No.: 19


Object Oriented Programming – C++ Unit 1

4. List and explain any two types of operators available in C++


programming language.
5. Describe with example the basic structure of C++ program.
6. Write a program that accepts two numbers from the user and swaps
the two numbers without using a temporary variable.
7. Write a program that accepts two numbers a and b, divides a by b, and
displays the quotient and the remainder.

1.9 Answers
Self Assessment Questions
1. Bjarne Stroustrup
2. mnemonics
3. integer
4. class
5. Inheritance
6. data hiding
7. Message passing
8. False
9. reserve words
10. Logical operators
11. iostream.h
12. cout
13. comments
14. Parenthesis
15. Compiling
16. Syntax error
17. execution
18. compile
19. .obj
Terminal Questions
1. a. Encapsulation: Encapsulation used to bind code and data together.
Wrapping of data and methods into a single unit is called
‘encapsulation’.
b. Inheritance: Inheritance is a technique by which one object acquires
the properties of another object. The technique also supports a
hierarchical classification.

Manipal University Jaipur B2114 Page No.: 20


Object Oriented Programming – C++ Unit 1

c. Polymorphism is the ability to present the same interface in different


forms. Polymorphism means "many forms of a single object.
“Operator Overloading” is a kind of polymorphism.
For more details, refer to section 1.4
2. Keywords are also known as reserve words. Many of C++ keywords are
common with C. Keywords have a specific meaning and purpose. Some
of the C++ keywords are: auto, break, catch, class, delete, do, for, new,
int, long, mutual, public, protected, return, size of, signed, void, while.
The constants in C++ can be numeric, character or string constants. The
value of a constant does not change during the program.
Identifiers are used to define a name. These are mostly used to name
variables (ex: array, structure), function, class etc. Every language uses
its own rules for naming the identifiers. For more details, refer to section
1.5.3.
3. A data type in a programming language is a set of data with values
having predefined characteristics. Like C language, C++ also supports
different data types. C++ language supports the following data types:
char, int, float, double. The basic datatypes have various modifiers
preceding them. The list of modifiers are: signed, unsigned, long and
short. For more details, refer to section 1.5.1.
4. Arithmetic operators: C++ provides five simple arithmetic operators for
creating arithmetic expression.
Relational operators are binary operators. Relational operators test data
values against one another, and return the value either 1 (true) or 0
(false).
For more details, refer to section 1.5.4.
5. Every programming language consists of different sections. Some of the
sections are optional and some are mandatory. Structure of C++
program contains the following sections: documentation section, header
file section, class declaration, class function definition section and main
function section. For more details, refer to section 1.5.5
6. Program to swap two numbers without using a temporary variable is-
# include<iostream.h>
void main()
{
Manipal University Jaipur B2114 Page No.: 21
Object Oriented Programming – C++ Unit 1

int num1,num2;
cout <<” enter two numbers”;
cin>> num1>>num2;
Num1=num1+num2;
Num2=num1-num2;
Num1=num1-num2;
cout<< “numbers after swapping are ”<<num1<<num2;
}
7. Program to divide a and b and display quotient and remainder
# include<iostream.h>
void main()
{ int a,b, q, rem;
cout <<” enter two numbers”;
cin>> a>>b;
q=a/b;
r =a%b;
cout<< “Quotient = ”<<q<<endl;
cout<<”remainder=”<<r;
}

References:
 Object-Oriented Programming Using C++, By B. Chandra, CRC Press.
 Starting Out with C++: From Control Structures Through Objects, Global
Edition, by Tony Gaddis, Pearson Education.

Manipal University Jaipur B2114 Page No.: 22


Object Oriented Programming – C++ Unit 2

Unit 2 Control Statements, Arrays and Pointers


Structure:
2.1 Introduction
Objectives
2.2 Control statements
Conditional control statements
2.3 Iteration statements
2.4 Introduction to arrays
Declaration and definition of arrays
Initialization of array
2.5 Multidimensional arrays
Two-dimensional arrays
N-dimensional arrays
2.6 Pointer
Declaration and initialization of pointers
2.7 Summary
2.8 Terminal Questions
2.9 Answers

2.1 Introduction
In the previous unit, you studied about the basic concepts of object- oriented
programming, the important components of programing language and the
process of compilation and execution of a program. Programs are usually
executed sequentially. In this unit, we will discuss the execution of programs
based on control and iterative statement. Control statements execute
program statements sequentially, based on certain conditions. Iteration
statements cause block of statements to execute repeatedly. In this unit, we
will also discuss arrays, multi-dimensional arrays and pointers.
Objectives:
After studying this unit, you should be able to:
 describe the conditional and unconditional statements
 discuss iteration statements
 define an array and explain how to declare different types of arrays
 explain the use of multidimensional arrays
 create a pointer and initialize values to the pointer

Manipal University Jaipur B2114 Page No.: 23


Object Oriented Programming – C++ Unit 2

2.2 Control Statements


There are basically two types of control statements in C++ which allow the
programmer to modify the regular sequential execution of statements. They
are- conditional and unconditional control statements.
2.2.1 Conditional control statements
The conditional control statements allow the user to choose a set of
statements for execution, depending on a condition. If statement and switch
statements are the examples of conditional controls statements which
executes based on the given condition. One more conditional control
statement is the conditional operator. Now let us discuss the three
conditional control statements one by one.
If, nested If statements
‘if statement’ is the simple conditional control statement. It controls the
sequential flow of executable statements based on certain conditions.
‘if’ is the keyword used to specify the condition. ‘if’ statement is followed by
executable statements that are enclosed in the curly braces. Curly braces
are optional in case of single executable statement
The syntax of if statement is given as:
Syntax:
if (expression or condition) {
Statement1;
Statement 2;
}
The expression or if condition inside the brackets returns the Boolean value,
i.e. true or false. If the condition or expression is true, then execution will
continue through statement1 and statement 2. If the condition is false, then
the program will skip both the statements (i.e. statement1 and statement2).
If –else statement;
Another type of if statement is if-else statement. it is useful to execute series
of statements. If the condition is true, then it executes if block statements. If
the condition is false then it executes else block statements.

Manipal University Jaipur B2114 Page No.: 24


Object Oriented Programming – C++ Unit 2

Syntax:
if (expression or condition)
{
Statement (s)
}
else
{
Statement (s);
}
The example program given below accepts a number from the user, and
displays whether given number is even or odd number.
# include <iostream. h>
void main(){
int x;
cout <<"enter the value of x\n'\";
cin>>x;
if(x%2 == 0)
cout <<" print even number";
else
cout<< " print odd number";
getch();
}

Nested-If statement
If-else statement is useful only if condition has to satisfy two possible
alternatives. If there is a need to check multiple alternatives, then use a
nested-if statement, i.e. an “if statement” in an “if statement” (one if
statement having another if statement, and so on is known as ‘nesting’). The
syntax of nested-if statement is specified as:
Syntax:
if (condition1)
{
if (condition 2)
{
Statement1;

Manipal University Jaipur B2114 Page No.: 25


Object Oriented Programming – C++ Unit 2

Statement2;
}
else if (condition3)
{
Statement3;
}
else
Statement 4 ;
}
Next statements after if statement;
The flowchart for the nested-if statement is shown in figure 2.1.

Figure 2.1: Nested- if statement

Note that && is the AND operator whereas || is the OR operator.


Multiple conditions can be checked using logical && operator (AND) and ||
operator (OR). For example:
if ((condition1) && (condition2))
statement1;
else
statement2;

Manipal University Jaipur B2114 Page No.: 26


Object Oriented Programming – C++ Unit 2

In the example given above, statement1 will be executed if both condition1


and condition2 are true. Otherwise, statement2 will be executed.
if ((condition1 || (condition2))
statement1;
else
statement2;
In the example given above, statement1 will be executed if either condition1
OR condition2 is true, and even if both are true. Statement2 will be
executed if both the conditions are false.
Example: The program below demonstrates the use of nested-if statement.
#include <iostream.h>
void main ()
{
int studentmarks = 80;
if( studentmarks >= 70) {
cout << "student passed with A grade";
}
else {
if( studentmarks >= 50) {
cout << "student passed with B grade";
}
else {
if( marks >= 40) {
cout << " student passed with C grade!";
}
else {
cout << " Better Luck next time";
}
}
}
}

Manipal University Jaipur B2114 Page No.: 27


Object Oriented Programming – C++ Unit 2

The above program number reads student marks, and displays the grade
obtained by the student. Here nested-if conditions are used to check the
grade of a student. Once the condition is true, it displays corresponding
message, i.e. the grade of the student.
Switch statement
If you are using more if- else statements i.e. nested-if statements in a
program, then it looks a bit confusing. One alternative to nested-if is the
switch statement. Switch statement helps you to check the different values
of the same variable and execute the statements accordingly. The syntax of
the switch statement is given below:
Syntax:
switch (variablename)
{
case constant1: statement1;
break;
case constant2: statement2;
break;
case constant3: statement3;
break;
default: statement4;
}
If the variable in the switch statement is equal to constant1 then statement1
is executed, but if it is equal to constant2 then statement 2 is executed. If it
is constant 3, then statement 3 is executed. If the variable value is not in
any of the cases listed, then the default case statement i.e. statement 4 is
executed. The default case specification is optional; however, keeping it is a
good practice.
Every case should have a break statement as the last statement. Break
statement takes the control out of the switch statement. Absence of the
break statement can cause execution of statements in the next case. No
break is necessary for the last case. In the above syntax, the default case
does not contain a break statement.

Manipal University Jaipur B2114 Page No.: 28


Object Oriented Programming – C++ Unit 2

The flowchart for the switch statement is shown in Figure 2.2.

Figure 2.2: Switch Statement

Manipal University Jaipur B2114 Page No.: 29


Object Oriented Programming – C++ Unit 2

Example: The following program implements the switch statement


# include<iostream.h>
void main(){
char x;
float num1,num2;
cout<<"Select an operator either + or - or * or / \n";
cin>>x;
cout<<"Enter two operands: ";
cin>>num1>>num2;
switch(x) {
case '+':
cout<<num1<<" + "<<num2<<" = "<<num1+num2;
break;
case '-':
cout<<num1<<" - "<<num2<<" = "<<num1-num2;
break;
case '*':
cout<<num1<<" * "<<num2<<" = "<<num1*num2;
break;
case '/':
cout<<num1<<" / "<<num2<<" = "<<num1/num2;
break;
default:
cout<<" select any of the operator among + or - or * or / ";
}
}
The example of switch statement given above is used to perform addition or
subtraction or multiplication or division of two numbers. It reads operator
values as character, and if the character value matches with any of the
switch case values, then it executes a corresponding operation; otherwise it
displays the default statement message.
Conditional Operator (?)
Conditional operator is also called ‘ternary operator’. The way a Conditional
operator works is similar to that of if-else statements. The general syntax of
conditional operator is:

Manipal University Jaipur B2114 Page No.: 30


Object Oriented Programming – C++ Unit 2

(Condition)? True statement; False statement;


Here ‘?’ is called ‘ternary operator’; if the condition is true, it executes a true
statement, otherwise it executes a false statement.
The statement given below compares two variables and assigns small value
to c.
c= (a<b)? a; b;
This can also be rewritten as:
(a<b)? c =a; c=b;

Unconditional control statements


In order to stop the flow of execution unconditionally, C++ supports three
types of unconditional control statements. They are: break, continue and
exit statements.
Break, continue and exit statements
Break
When a break is encountered inside any conditional block or loop, a
conditional block or loop is terminated, and control passes to the statement
outside the conditional block. In the switch statement, a break statement is
used in every case statement to terminate the switch statement, and this
passes the control out of the switch block.
The following program demonstrates the use of break statement.
#include<iostream.h>
void main ()
{
int i=1,total=0;
if(i<10)
{
total= total+ i;
i++
if(i== 5)
break;
}
cout<<"total";
}

Manipal University Jaipur B2114 Page No.: 31


Object Oriented Programming – C++ Unit 2

In the above program, the user reads two variables, i.e. i=1 and total=0. To
find the sum of numbers, add i value to the total and increment the ‘i’ value
by 1(represented with i++). Here, inside an if loop one more if loop is used.
The first if loop checks whether the ‘i' is less than 10 or not. The second if
loop verifies the condition whether i is equal to 5 or not. When i value
becomes 5, then it executes the break statement that will terminate the loop,
and then the control passes out of the if block.
Continue statement is used to take the control to the next iteration of the
loop. It is used if the control has to be transferred to the next iteration of the
loop based on a condition, skipping all the other statements in the loop. The
following program shows the use of a continue statement.
Example
# include<iostream.h>
void main()
{
int i=1, n;
cout< “enter the number” ;
cin>>n;
if(i<=n)
{
i++;
if(i%2==0)
cout<< i<<"\is even number \n";
else
continue;
}
}
The above program enables you to use a continue statement. A Program
reads the value of variable n and displays even number values up to n.
There are two if conditions in a program: the first if condition checks whether
i value is less than or equal to n, and the second if condition checks whether
i value is an even number or not. If i value is even, it displays that value, or
else the control of execution is passed to the continue statement. Here the
continue statement, first of all, passes the control to if condition and helps to
repeat the loop up to i value equal to n. Once i value becomes greater than

Manipal University Jaipur B2114 Page No.: 32


Object Oriented Programming – C++ Unit 2

n, then the first if condition becomes false, and the control is passed out of
loop.
Exit
Sometimes you need to end your program (or a sub section of a program)
earlier than the normal termination. C++ supports exit statement to exit
programs and returns an exit code. Exit is an inbuilt library function. To use
exit program the header file process.h has to be included in the program.
The syntax of an exit program is specified as :
Exit (integer)
Here the integer value return to operating system (OS) while terminating
program.
Exit (0) means - no error i.e. successful termination.
Exit (nonzero value) means– error while exiting the program.

#include<iostream>
#include<process.h>
int main()
{
cout<" example program for exit';
Exit(0); // this statement terminates the program and returns 0 to OS
cout <<' this statement will never executed";
}
The example shown above shows termination of the program before
reaching the end of the program. Exit code 0 indicates a normal program
termination.
Self Assessment Questions
1. Conditional operator is an alternative to __________ statement.
2. Each case in switch statement should end with _________ statement.
3. __________ statement is used to take the control to the next iteration
of the loop.
4. __________ header file should be included to use exit function.
5. __________ Statement takes the control to the beginning of the loop.

Manipal University Jaipur B2114 Page No.: 33


Object Oriented Programming – C++ Unit 2

2.3 Iteration statements


Loops or the iteration statements cause block of statements to execute
repeatedly. There are three types of iterative statements: while, do while
and for.
While loop
While statement starts with a condition and repeats block of statements as
long as the condition is true. The syntax of while loop is:
Syntax:
while (condition)
{
//Body of the while loop
Statement1;
Statement 2;
} Next statements after while loop;
In the syntax shown above, if the while condition is true, then it executes
body of the while statement i.e. statement1 and statement2 are executed.
After execution, the condition is checked again. If the condition is true, the
statements inside the while loop are executed again. This continues until the
loop condition becomes false.
The flowchart for the While statement is shown in Fig. 2.3.

Figure 2.3: While Statement

Manipal University Jaipur B2114 Page No.: 34


Object Oriented Programming – C++ Unit 2

The following program implements the while loop


#include<iostream.h>
void main () {
int n, i = 1, factorial = 1;
cout<< "Enter a positive integer: ";
cin >> n;

while ( i <= n) {
factorial = factorial* i;
i++;
}
cout<<"Factorial of "<<n<<" = "<<factorial;
}

The program number accepts positive integer number n from the user and
finds the factorial of that number. In the program shown above, the variables
i and factorial are initialized to one. The variable i is incremented every time
while loop becomes true. Calculate factorial value by multiplying i value with
the factorial variable. Once i value becomes greater than n, while condition
becomes false, and the control passes out of the loop and displays output
i.e. factorial of a given number.
Do... while loop
Do-while is similar to while loop, except that a do--while loop body
statement executes at least once before the condition is tested.
When the condition is true, the control statement jumps back to do
statement, and the body of statements in loop executes again. This process
repeats until condition becomes false.
In do-while loop, the condition is checked at the end of loop and so it is
called exit-control statement, whereas while loop is called entry -control
statement.
Syntax:
do
{
// do-while loop body of statements

Manipal University Jaipur B2114 Page No.: 35


Object Oriented Programming – C++ Unit 2

Statement1;
Statement2
} while (condition expression);
Next statements after do-while condition;
In the syntax given above, statement1 and statement2 are executed, and
the condition is checked. In other words, the do-while loop body statement
executes before the condition. If the condition is true, then the statements
are executed again, and if the condition is false, then the control is
transferred to the next statement after the do-while statement.
The flowchart for the do... while statement is shown in Figure 2.4.

Figure 2.4: Do... while Statement

Please note that there is no semicolon after do, but there is a semicolon
after the condition expression in while part.
The following program implements the do-while loop
#include<iostream.h>
int main() {

Manipal University Jaipur B2114 Page No.: 36


Object Oriented Programming – C++ Unit 2

int n, i = 1, factorial = 1;
cout<< "Enter a positive integer: ";
cin >> n;

do{
factorial = factorial* i;
i++;
} while ( i <= n);
cout<<"Factorial of "<<n<<" = "<<factorial;
}
The decision on whether to use while or do.. while statement depends on
whether the statements inside the loop have to be executed atleast once or
not. If it has to be executed atleast once, then the do.. while statement
should be used.
For loop
The for loops are the most useful type of loops. The syntax of the for loop is
shown below. The loop condition contains three parts. They are: loop
initialization, loop termination condition and statement for the next iteration,
and these three parts are separated with semi-colons.
Syntax:
for(initialization statement; loop termination condition; statement to
increment/decrement the loop variable)
{
//body of for loop;
Statement1;
Statement2;
}
In the example given above, initiation statement is executed first, and then
the termination is checked. If the condition is true, body of the for loop is
executed i.e. statement1 and statement2 are executed. Then the third
statement in for loop is executed, which modifies the loop control variable.
The flowchart for the statement is shown in Figure 2.5.

Manipal University Jaipur B2114 Page No.: 37


Object Oriented Programming – C++ Unit 2

Figure 2.5: For Statement

The following program implements the factorial of a number using for loop
#include<iostream.h>
int main() {
int n, i , factorial = 1;
cout<< "Enter a positive integer: ";
cin >> n;

for( i=1; i<=n; i++)


{
factorial = factorial* i;

Manipal University Jaipur B2114 Page No.: 38


Object Oriented Programming – C++ Unit 2

}
cout<<"Factorial of "<<n<<" = "<<factorial;
}

The for statement can also have multiple initialization and decrement and
increment statements as shown in the following expression
for(i=0,j=0;i<=n;j++,i++)
{
Statements;
}
Please note that in the case of multiple statements, each statement should
be separated by a comma.
Selection of the various types of loop to be used in the program depends on
the programmer style. However, you should use for loop if you know in
advance how many times the loop has to be executed. If the loop has to be
executed at-least once, irrespective of whether the condition is true or false,
then do-while loop should be used.
Self Assessment Questions
6. Which of the following is true for do-while loop?
a. Entry control statement
b. Exit control statement
c. Temporary statement
d. Conditional operator statement
7. Do-while loop will be executed at least once, even if the condition is
____________.
8. The for statement can also have multiple initialization, and decrement
and increment statements. (True/ False)

2.4 Introduction to Arrays


An Array is defined as a collection of elements of the same type. Till now
you used variable to store single value In the case of an array, you can
store multiple values of the same datatype in a single variable. The values
of an array are called ‘array elements’. Supposing you stored four integer
values in a single array, the array stores the values in a linear form. Each

Manipal University Jaipur B2114 Page No.: 39


Object Oriented Programming – C++ Unit 2

element of the array can be accessed separately in any order. The size of
the array matches with the number of values it contains.
2.4.1 Declaration and definition of arrays
Like variable declaration, arrays are also declared along with the data type.
Array declaration reserves space for a number of elements. The declaration
of array contains the name of the array along with square brackets. Inside
the square brackets specify size of the array.
Int x[10];
An integer array x is declared with the size 10. The size is used to indicate
the number of elements an array can store. The elements of an array can
be accessed using the array name followed by index number within square
brackets, i.e. x[0], x[1] to till x[9]. The index of an array starts with 0 and the
last index number of an array is size-1.
2.4.2 Initialization of array
To specify values to an array, we should explicitly initialize specific values.
You can specify declaration and initialization of the array in a single
statement. Initialization of an array can be defined in the following form:
int a[5]= { 3, 6, 9,12,15}
The number of values between braces { } are not more than the size of the
array. Declaration and initialization of the array can be done in a single
statement. Then the above example can also be declared and initialized as
follows:
Int a[]= { 3, 6, 9,12,15}
Supposing you declare the array and initialize values to it using the same
statement, you can omit the size of the array.
The following program shows how you can add values of array to find the
sum of elements of the array.
#include<iostream.h>
void main()

{
int i, sum = 0;
int a[10] = {1, 2, 3,4,6,9,2,8,5,10}; // array with size 10

Manipal University Jaipur B2114 Page No.: 40


Object Oriented Programming – C++ Unit 2

for (i=0; i<10; i++)

{
sum = sum + a[i];
}

// display the result...

cout<<"\n Sum of values of an array is = "<<sum;

Another interesting aspect of the array is that all the elements in the arrays
are allotted consecutive spaces in the memory by the operating system.
The following program sorts an array. Here nested for loops are used to
enable this.
# include<iostream.h>
void main()
{
int a[10],temp;
for (int i=0; i<10;i++)
{
cin>>a[i];
}
cout<<"Array after sorting is ";
for(int j=0; j<9;j++)
for(i=0;i<9;i++)
{ if (a[i]>a[i+1])
{temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
for (i=0; i<10;i++)
{
cout<<a[i]<<endl;
Manipal University Jaipur B2114 Page No.: 41
Object Oriented Programming – C++ Unit 2

}
}
All the elements in the array should be initialized. Every data should be
separated by a comma and all the elements enclosed within flower brackets
are as shown below:
int data[5] = {3,5,7,4,9};
In the above initialization, data[0] is initialized to 3, and data[1] is initialized
to 5 and so on..

3 data[0]
5 data[1]
7 data[2]
4 data[3]
9 data[4]

Self Assessment Questions


9. Arrays group the data of __________ type.
10. An array declared as int a[10] can store __________ integers.
11. In C++, the declaration a[5] represents the _________ integer in the
array.
12. Array elements are accessed through _______________.
13. When initializing values to an array, the number of values between
braces { } are not more than the size of the array. (True/False)

2.5 Multidimensional Arrays


Multidimensional arrays can be described as “arrays of arrays”. The size of
an array can be represented using a subscript. If an array has two
subscripts we can call it a two dimensional array. If an array has more than
one subscript, we can call it a multi-dimensional array. Multi-dimensional
arrays contain as many indices as required, if it is not limited to two indices
(i.e., two dimensions).
2.5.1 Two- Dimensional arrays
The simplest form of the multidimensional array is the two-dimensional array.
For example, a two dimensional array can be created to store data of about

Manipal University Jaipur B2114 Page No.: 42


Object Oriented Programming – C++ Unit 2

a matrix. A 3x4 matrix that has 12 data elements can be created using the
following declaration
int A[3][4];
The array A[3][4] has three rows and four columns. The elements in the
array can be accessed by two indices. To refer to an element in the first row
and second column, A[0][1] has to be used since the index starts from zero.
The following program accepts two, 2x3 matrices from the user and adds
the two matrices.
//matrix.cpp
# include <iostream.h>
void main()
{
int a[2][3], b[2][3], c[2][3];
int i,j;
cout<<”Enter the elements for the first 2x3 matrix”;
for (i=0;i<2;i++)
for (j=0;j<3;j++)
{ cin>>a[i][j];}
cout<<”Enter the elements for the second 2x3 matrix”;
for (i=0;i<2;i++)
for (j=0;j<3;j++)
{
cin>>b[i][j];
c[i][j]=a[i][j]+b[i][j];
}
cout<<”The resultant matrix is”;
for ( i=0;i<2;i++)
{
for ( j=0;j<3;j++)
{
cout<<c[i][j]<<” “;
}
cout<< endl;
}
}

Manipal University Jaipur B2114 Page No.: 43


Object Oriented Programming – C++ Unit 2

Multi-dimensional arrays can also be initialized by specifying row by row


values. Every row elements are initialized by enclosing them in separate
flower brackets.
int a[2][2] = {{ 3,4},{ 2, 7}}
In the example given above, elements 3 and 4 will be initialized to a[0][0]
and a[0][1] respectively.
2.5.2 N- Dimensional arrays
Multi-dimensional arrays contain more than one index. If an array has ‘n’
indices, then it is called an ‘n-dimensional array’. The general syntax of an
n-dimensional array is:
Datatype name [Size1] [Size2]... [SizeN];
Example: if an array has 3 indices then it is called a 3-dimensional array.
Int P[2][3][4]
Self Assessment Questions
14. An array with the declaration int x[4][5] can store ________ numbers.
15. The array x[4][5] the number in the third row and fourth column can be
accessed by ____________.
16. int a[ ] [ ] is a valid declaration. (True/False)

2.6 Pointers
Pointers are a very powerful feature of the language with many uses in
programming. Pointer is a variable that stores the address of another
variable.
Some of the programing tasks are performed more easily with pointers such
as dynamic memory allocation (i.e. obtaining memory at runtime from the
system).
As you know, every variable created in a program is stored in the memory.
The location of memory in a system can be accessed through the address.
The address of a variable can be accessed using ampersand (&) operator.
If there is an integer variable named P in the program, and if you have
statement cout<<&P, the program will display the address of the variable P,
which will be a hexadecimal number.

Manipal University Jaipur B2114 Page No.: 44


Object Oriented Programming – C++ Unit 2

2.6.1 Declaration and Initialization of pointers


Pointers are variables that store address values of other variables. They are
defined by prefixing “*” (asterisk) to the variable name. The data type of the
pointer variable can be any of the basic or user-defined data type, or even
void. If a pointer is defined as a particular data type, then it can store
addresses of variables of that data type alone. However, if the pointer is
defined as void, then it can store addresses of variables of any data type.
The following statements create a pointer ptr and assign the address of the
integer variable P. The declaration of pointer variable is the same as any
other variable, except that you add an asterisk before the name of the
pointer variable,
int *ptr;
int P=5;
ptr=&P;
The variable P can be accessed by two ways now: one, through the name P
and the other, through the pointer.
The following statement displays the contents of P through the pointer ptr.
cout<<*ptr;
Here, * is known as the indirection operator or value of the variable pointed
to by the pointer.
If you use cout<<ptr; statement in the program, it will simply display the
address of the P or the contents stored in the ptr variable.
One of the important uses of pointers is getting memory during runtime.
Pointer can be used with arrays. Both are related to each other. Arrays work
similar to pointer to their first element. So, an array can always be implicitly
converted to the pointer of the proper type.
Example: Let us declare two variables one is pointer type and another one
is array type.

int * A;
int B [10];

Manipal University Jaipur B2114 Page No.: 45


Object Oriented Programming – C++ Unit 2

As we have already studied with regard to the array, brackets ([]) are used
to specify the size of an array. We can assign pointer variable to an array.
So, the following assignment statement is valid.
A = B;
Pointers and arrays support the same set of operations, with the same
meaning for both. The main difference is that the pointers can be assigned
new addresses, while the arrays cannot.
Following example illustrates the use of pointers and arrays
# include< iostream.h>
void main ()
{
int A[5];
int * p;
p = A; *p = 10;
p++; *p = 20; p = &A[1];
p++; *p = 30; p = &A[2];
for (int n=0; n<3; n++)
cout << A[n] << ", ";
}
In the program given above, the statement p=A assigns values of an array
to a pointer.
When Pointer p increments, address of pointer will move to the next
address location. Here value of the array is assigned to the pointer. Using
for loop, the program displays array values.
If we know the size of an array, we can easily assign values to the array
using index without wastage of memory. When there is no idea about the
size of an array in advance, array can be declared using pointer.
Pointer uses “New” operator to allocate memory to array during runtime and
returns the memory location of the first element in the array. Using new
operator, we can create (allocate) and delete (destroy) the objects
dynamically.
The syntax of the new operator is:
Pointervariable = new data type [size];

Manipal University Jaipur B2114 Page No.: 46


Object Oriented Programming – C++ Unit 2

where data type can be any basic or user-defined and the size is any
integer value.
Delete operator is used to return the memory to the system. The syntax of
delete operator is:
delete pointervariable;
where pointervariable is the pointer containing address returned by the
system.
The following program creates a dynamic array, and finds the sum of array
elements:
#include<iostream.h>
void main()
{
int n, sum=0;
int* ptr;
cout<<"enter the size of the array"<<endl;
cin>>n;
ptr=new int[n];
cout<<"enter"<<n<<"numbers";
for(int i=0;i<n;i++)
{cin>>ptr[i];
sum=sum+ ptr[i];}
}
cout<<"sum ="<<sum;
delete ptr;
getch();
}
In the program given above, the statement ptr=new int[n]; asks the system
to allocate memory of size n. It store integer values and stores the address
of the memory allotted in the pointer variable ptr.
Self Assessment questions
17. Pointers are variables that store ____________.
18. ____________ Operator can be used to request memory from the
system during runtime.

Manipal University Jaipur B2114 Page No.: 47


Object Oriented Programming – C++ Unit 2

2.7 Summary
Let us recapitulate the important points discussed in this unit.
 This unit discusses the various conditional control statements and
iteration statements, arrays and pointers that are supported by C++.
 If statement and switch statement are the conditional control statements
that are executed based on given condition.
 In the switch statement, the break statement is used in every case
statement to terminate the switch statement and to pass the control out
of the switch block.
 Continue statement is used to take the control to the next iteration of the
loop.
 Iteration statements used to execute the block of statements for
repeated number of times. There are three types of iterative statements:
while, do while and for.
 Arrays are used to store large volumes of similar data together. The
array elements can be accessed by specifying array name followed by
the number which indicates the position of the element in the array.
 Arrays of basic datatypes such as integers, characters etc., and user-
defined datatypes such as structures, objects can be defined. Arrays
can be multidimensional, helping to store data that are related.
 Pointers are a very powerful feature of the language that has many uses
in programming. Pointers are variables that store address values of
other variables. They are defined by prefixing an * to the variable name.
 Pointer can be used with arrays. Both are related to each other. Pointer
uses “New” operator to allocate memory to array during runtime, and
returns the array of the memory location of the first element in the array.

2.8 Terminal Questions


1. Explain the following control statements:
a. if-else b. conditional operator
2. What is the difference between the do-while and the while statements?
Explain with syntaxes.
3. Define ‘array’. Discuss different types of array?
4. Write a program that stores 100 numbers in the array. The user should
be able to find a particular number in the array.

Manipal University Jaipur B2114 Page No.: 48


Object Oriented Programming – C++ Unit 2

5. Write a program that accepts a 3x3 matrix from the user and finds the
transpose of it.
6. Explain the pointer operator “New” with an example program.

2.9 Answers
Self Assessment Questions
1. if –else statement
2. Break statement
3. Continue
4. process.h
5. break
6. B. Exit control statement
7. False
8. True
9. same
10. ten
11. sixth
12. array name followed by index number in square brackets
13. True
14. 20
15. a[2][3]
16. False
17. address values of other variables
18. New

Terminal Questions
1. If-else: Another type of if statement is if-else statement. If the condition
is true, then it executes ‘if block’ statements. If the condition is false,
then it executes ‘else block’ statements.
Conditional operator: Conditional operator is also called ‘ternary
operator’. Conditional operator works similar to if-else statements. For
more details, refer section 2.2.1.
2. In do-while loop the condition is checked at the end of the loop. So it is
called an ‘exit-control’ statement, whereas while loop is called ‘entry-
control’ statement. For more details refer section 2.3

Manipal University Jaipur B2114 Page No.: 49


Object Oriented Programming – C++ Unit 2

3. Array is defined as a collection of elements of the same type. If an array


has two subscripts, we can call it a two-dimensional array.
Multidimensional arrays contain as many indices as required. It is not
limited to two indices (i.e., two dimensions). For more details refer
section 2.4.
4. //seqsearch.cpp
# include<iostream.h>
void main()
{ int a[100], num;
int i, flag=0;
cout<<”please enter the numbers for the array”;
for( i=0;i<100;i++)
{ cin>>a[i];
}
cout<<”Enter the number to be searched”;
cin>>num;
for(i=0;i<100;i++)
{
if (a[i]==num)
{ cout<<num<<” is found”;
flag=1;
break;
}
}
if (flag==0)
cout<<num <<” not found”;
}
5. // program to read 3*3 matrix and transpose it.
# # include<iostream.h>
void main()
{
int a[3][3], at[3][3];
int i,j;
cout<<”Enter the elements for the 3x3 matrix”;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
Manipal University Jaipur B2114 Page No.: 50
Object Oriented Programming – C++ Unit 2

{
cin>>a[i][j];
at[j][i]=a[i][j];
}
cout<<”The transpose is”;
for ( i=0;i<3;i++)
{
for ( j=0;j<3;j++)
{
cout<<at[i][j]<<” “;
}
cout<< endl;
}
}
6. A Pointer uses the “New” operator to allocate memory to the array
during runtime, and returns the array of the memory location of the first
element in the array. For more details refer section 2.6.1.

References:
 Learning C++ Programming Concepts by Tickoo Sham, Pearson
Education India.
 C++ for Programmers by Paul Deitel, Harvey M. Deitel, Pearson
Education.
 C++ Primer Plus by Stephen Prata, Addison-Wesley Professional.
 Object-oriented Programming with C++ - Sixth Edition by
E. Balagurusamy. Tata McGraw-Hill Education.

Manipal University Jaipur B2114 Page No.: 51


Object Oriented Programming – C++ Unit 3

Unit 3 Functions and Structures


Structure:
3.1 Introduction
Objectives
3.2 Introduction to Functions
3.3 Passing Data to Functions
Pass by value
Pass by reference
3.4 Scope and Visibility of Variables in Functions
Storage classes
3.5 Strings
Declaration and initialization of strings
Standard C++ String functions
3.6 Structures and Unions
3.7 Summary
3.8 Terminal Questions
3.9 Answers

3.1 Introduction
In previous unit, you have studied execution flow of programs based on
certain conditions/statements. You have also studied how to store collection
of values in single variable using array. In this unit, we will discuss the reuse
of code using function, how to declare and define a function. We will also
discuss scope and visibility of variables, use of storage classes, declaration
of strings and how to initialize values to strings. Finally we will discuss user
defined data types, structures and unions.
Objectives:
After studying this unit you should be able to:
 explain functions and how they enable program organization
 discuss different types of variables based on scope
 define strings and explain its uses
 describe different types of string library functions
 define structure and union
 differentiate between structures and unions

Manipal University Jaipur B2114 Page No.: 52


Object Oriented Programming – C++ Unit 3

3.2 Introduction to Functions


Till now you have studied the usage of conditional, un-conditional
statements and loops. You must have experienced how execution control
can be passed from one statement to another statement. Now it’s time to
discuss functions. To perform individual tasks, user uses functions. One of
the benefits of function is reusability. Reusability means use of existing code
i.e. we have defined our code somewhere and then we are using it.
A function is defined as a group of statements that performs a task together
and the user can execute them whenever required. There are two types of
functions: predefined functions and user defined functions. You can use a
predefined function without worrying about the code to implement. In
section 3.5.2, you will study examples of predefined function or standard
library functions such as strcpy, strlen. In this section, we will discuss how to
define and implement user defined functions.
Declaration of function
Every user defined function should be declared before it is used. The
declaration of function contains mainly three parts: function_name,
return_type and set of parameters (parameter list). If a user wants to call
and execute the code defined in function, he/she has to refer it through
function name. The general syntax of function declaration is:
return_type function_name (parameter list);
Function declaration is also called as function prototype. Function name
together with parameter list is known as function signature and it does not
include return type of function.
If a user returns value to function, the data type of the return value should
be specified. If the user does not return any value, it should be specified as
void. Every program starts with a default function - void main (), which
means the function returns no value. When you have several users defined
functions in a program, the statements in the main () function is executed
first irrespective of where it is located in the program.
The input to function can be passed through parameters. Every function can
have zero or more number of parameters. During declaration of function
along with parameter name, the data type of parameters should be specified.

Manipal University Jaipur B2114 Page No.: 53


Object Oriented Programming – C++ Unit 3

If function has more than one parameter they should be separated with a
comma.
A function that accepts data from other functions does so by accepting one
or more parameters from the sending function. Information that is passed to
a function is called arguments to the function or simple arguments.
Definition of function
A function definition provides the actual body of the function. A c++ function
definition consists of a function header and function body. Function header
is similar to prototype of function. Function header specifies return type of
function, function name and parameter list. The only difference between the
header and the prototype is the semicolon. If you specify semicolon at the
end of function heading, it generates a syntax error. Function body is group
of statements or syntactical statement. Function needs to be declared
before it is used, but can be defined anywhere in the program or linked file.
The idea of declaring a function before defining it is called forward
declaration. If you define a function before calling it, you do not necessarily
need a definition.
The general syntax of function definition is:
return-type function_name (parameter list) // function header
{
Statements; //Function body
}
The arguments should match during function call with respect to data type
and order of the arguments. In case of default arguments, the value need
not be specified during call.
Let us discuss an example of declaration of a function named square which
inputs a number and returns the square of the number.
int square(int);
Please note that all the arguments are enclosed within brackets. If there are
no arguments, void should be specified within the brackets. The following is
the declaration of a function which does not have return value and does not
have any arguments.
void xyz(void);

Manipal University Jaipur B2114 Page No.: 54


Object Oriented Programming – C++ Unit 3

The functions can be invoked or called by referring to the function name


followed by the variables or constants that have to be passed as arguments.
If there are no arguments that have to be passed to the functions, then the
function name should be followed by a pair of parenthesis. The following
program would invoke the xyz function:
xyz();
To invoke a square function which inputs a number and returns a number,
following statement can be used:
s=square (n);
Where s and n are integer variables. The function will compute square of n
and the result will be stored in variable s. Please note that during function
call, constants can also be passed.
To understand the relevance of functions and its use, let us take an
example. Let us suppose, you would like to write a program that computes
the factorial of a number. We can define a user defined function named fact
which would input a number and compute the factorial of that number and
return the result. The declaration for the function will be:
int fact(int);
We can compute the factorial of n just by specifying fact (n) which would call
the function fact and execute the statements
The following program (fact.cpp) explains how to calculate factorial of a
number
//fact.cpp
# include <iostream.h>
#include< iostream.h>
#include<conio.h>
int fact (int); // function declaration
int main()
{
int n, i, result;
cout<<” enter the number”;
cin>>n;
result=fact (n);

Manipal University Jaipur B2114 Page No.: 55


Object Oriented Programming – C++ Unit 3

cout<<” resultant factorial value is”<< result;


getch ();
return 0;
}
int fact(int n) // function definition
{
Int i, factorial=1;
for (i=1; i<=n; i++)
{
factorial=factorial *i;
}
return factorial;
}
The program receives input from user. The user enters any integer number
as input. To calculate factorial of the particular number, the fact () function is
invoked by passing variable n. When a compiler encounters function
definition i.e. first statement of the function, it copies variable n value. The
variables i and factorial are defined to calculate factorial. The value of n is
constant or same through the function. By using for loop the factorial of
number is calculated. The return statement is used to return result to main
program.
If the function does not have any return value, the return statement can be
skipped. The control goes back to the main program once the last statement
in the program is encountered. Alternatively, simply using the return
statement without any variable would also imply that no value is returned to
the main program.
Self Assessment Questions
1. Function declaration is also called ___________.
2. Function name together with parameter list is known as _________.
3. ________ Statement is used to return value to the main program.
4. Function call should always contain function name followed by
parenthesis even if there are no arguments. (True/False)

Manipal University Jaipur B2114 Page No.: 56


Object Oriented Programming – C++ Unit 3

3.3 Passing Data to Functions


After a function is declared, you must be concerned with how interaction will
happen to function from main () function or other function. Interaction with a
function can happen by passing data to a function or by returning values
from function. Data can be passed to functions in two ways: (i) Pass by
value and (ii) Pass by reference.
3.3.1 Pass by value
One method of passing data to function is passing by value. The fact
function discussed in previous section implements passing by value. In this
way of passing variables, a copy of the variable (main program) is created
during function call with the name specified in the function and initialized
with the value in the original variable. All the operations in the function are
then performed on the function variable. The values in the variables
declared in the main program remain unchanged by the function operations.
3.3.2 Pass by reference
Another alternative to passing arguments is passing by reference. When
we pass argument by reference, no copy of the variable is created. However,
the variables in the main program are referred to by different name in the
function. Since no copy is created, when the values in the function variables
are modified, the values in the variables in the main program are also
modified. Pass by reference provides an easy mechanism for modifying the
variables by functions and also enables to return multiple variables.
To pass arguments by reference, all the variable names in the argument list
should be prefixed with & (ampersand) or address of operator when function
is declared and defined. The following example (passingbyreference.cpp)
shows the implementation of passing argument by reference.
Function is invoked by calling the function with a pair of parentheses
containing any number of parameters. Pass by reference function call is the
same as normal function call. Only difference is in case of pass by reference
a copy of address of the actual parameter is stored.
//passingbyreference.cpp
# include <iostream.h>
int swap(int& m, int& n); // function declaration
void main()
{
Manipal University Jaipur B2114 Page No.: 57
Object Oriented Programming – C++ Unit 3

int a,b ;
cout<< “enter two numbers”;
cin>>a>>b;
swap(a,b);
cout<<”The value of a is”<<a<<endl;
cout<<”The value of b is”<<b<<endl;
}
void swap(int& m, int& n)
{ int temp;
temp=m;
m=n;
n=temp;
}
In the above program, the variables a and b are passed by reference which
implies that they will be accessed directly. However, the variables will be
referred as m and n in the function and are swapped. The result is that the
function swaps the values in the original variables a and b.
You can also have more than one user defined functions that can have
same name and perform different operations. This is a powerful feature of
C++ and is known as function overloading. Every overloaded function
should however have a different prototype. The following example
(printoverload.cpp) program implements an overloaded function print line ()
# include <iostream.h>
void printline();
void printline(char ch);
void printline(char ch, int n);
void main()
{
printline();
printline(“*”);
printline(“*”, 20);
}
void printline();
{ for(int i=0;i<25;i++)
cout<<”-“;
cout<<endl;
Manipal University Jaipur B2114 Page No.: 58
Object Oriented Programming – C++ Unit 3

}
void printline(char ch);
{for (int i=0;i<25;i++)
cout<<ch;
cout<<endl;
}
void printline(char ch, int n);
{ for (int i=0;i<n;i++)
cout<<ch;
cout<<endl;
}
In the above program, the function printline has three different prototypes
depending on the arguments passed to it. The relevant function is invoked
depending on the type and number of arguments passed to it.
Functions can also contain default arguments. Default arguments are
those whose values need not be explicitly passed during function call.
However, the default arguments should be specified in the end of the
argument list to avoid ambiguity arising during function overloading. The
default values are specified while declaring the function along with the data
type of the argument. The variable name may or may not be specified
during declaration.
The prgram (printoverload.cpp) can also be implemented through default
arguments as shown below example (default.cpp).
//defaultarg.cpp
# include <iostream.h>
void printline(char ch=”*”, int n=25);
void main()
{
printline();
printline(“-”);
printline(“-”, 20);
}
void printline(char ch=”*”, int n=25);
{ for(int i=0;i<n;i++)
cout<<ch;

Manipal University Jaipur B2114 Page No.: 59


Object Oriented Programming – C++ Unit 3

cout<<endl;
}
In the example 3.4, variable ch and n values are declared as value of
variable n is 25 and value of ch is *. However, if the values are specified
explicitly, then the default values will not be considered.
Arrays can be used as arguments to functions. It is similar to pass any other
variables as shown in the example program (matrix.cpp) below:
//matrix.cpp
# include<iostream.h>
void display(int arr[3][4]);
void main()
{ int matrix1[3][4], matrix2[3][4], sum[3][4];
int i,j;
cout<<”Enter the elements of matrix one”;
for(i=0; i<3;i++)
for(j=0:j<4;j++)
cin>>matrix1[i][j];
cout<<”Enter the elements of matrix two”;
for(i=0; i<3;i++)
for(j=0:j<4;j++)
{
cin>>matrix2[i][j];
sum=matrix1[i][j]+ matrix2[i][j];
}
cout<<”sum is”;
display(sum);
}
void display(int arr[3][4] )
{
for(int i=0;i<3;i++)
{for(int j=0;j<3;j++)
cout<<arr[i][j]<<” “;
cout<<endl;}
}

Manipal University Jaipur B2114 Page No.: 60


Object Oriented Programming – C++ Unit 3

Self Assessment questions


5. The values in the original variable remain unchanged during ________
type of function call.
6. The advantage of passing arguments by reference is _____________.
7. The feature of C++ which enables two or more functions to have same
name but different prototypes are known as ___________.
8. Default values for the arguments have to be specified during
_____________.

3.4 Scope and Visibility of variables in Functions


Functions help to save memory as all the calls to the function uses the
same code for execution. However, with function, there is overhead of
execution time as there must be instructions for jump to the function, saving
data in registers, pushing arguments to stack and removing them, restoring
data, instructions for returning to the calling program and return values. To
save execution time of functions, one of the features in c++ is inline
functions.
Inline functions:
The main use of inline function is that it reduces the size of the code and
improves in the speed of program execution. You should define inline
function before the main () function. Inline functions are same like normal
functions except that the function declaration begins with the keyword inline.
Whenever you call inline function the function code is placed within the
calling program.
The syntax of inline function is:
inline return-type name_of_function (arguments)
{
Statements of function; // function body
}
Inline functions are suitable for small functions which have to be repeatedly
called. This enables the user to write programs using functions which would
make programs look neat and less lengthy, at the same time the actual
code is inserted in all the places where the function is called after
compilation enabling faster execution of the program.

Manipal University Jaipur B2114 Page No.: 61


Object Oriented Programming – C++ Unit 3

Example program to calculate addition of three numbers using inline


function is given in program below (inlineexample.cpp)
//inlineexample.cpp
#include<iostream.h>
#include<conio.h>
inline int add(int x, int y, int z)
{
return (x+y+z);
}
int main()
{
int x=6;
int y=4;
int z=2;
cout<<add(x,y,z);
return 0;
}
3.4.1 Storage Classes
A storage class defines the scope (visibility) and life-time of variables and/or
functions within a C++ program i.e. storage class is used to determine when
variable is allocated, how long it lives, how it is accessed, where it is stored.
C++ supports different types of storage classes. They are: automatic, static
and external variables.
Automatic
Automatic variable also called local variables and these are default
variables.
The variables which we create and use in programs are automatic variables.
The keyword auto is used to declare automatic variables, but since the
variables declared in functions are automatic by default, this keyword may
be dropped during variable declarations. The scope of the automatic
variable is within the function block where it is declared. Once the execution
of function is over, the value of automatic variable is lost. The lifetime of
automatic variable is limited and hence it saves memory. By default, the
memory of variable is removed, if variable is not used by function. If no
value is assigned or initialized to automatic variable it takes junk value
Manipal University Jaipur B2114 Page No.: 62
Object Oriented Programming – C++ Unit 3

depending on the value stored in memory. Therefore, it is good practice to


initialize values to avoid debugging problems.
External
External variables are variables defined outside/external to any function.
External variables are recognized globally i.e. once variable is declared, it
can be used by multiple functions. It is easy to share the external variable
values among various functions. An external variable can be declared
before main function so declaration statement is not specific to any one
function. External variables are also called global variables and are
automatically initialized to zero. However, too many external variables can
create problems in debugging as the programmer will have tough time
figuring out which function modified which data. Object oriented
programming provides an alternative to use external variables. This feature
is just to support backward compatibility with C.
The program (external.cpp) shown below illustrates the difference between
an external variable and an automatic variable.
//external.cpp
# include<iostream.h>
int x;
void f1();
void f2();
void main()
{
x=x+2;
f1();
f2();
cout<<x;
}
void f1()
{ int x;
x=x*2;
}
void f2()
{ x++;
}

Manipal University Jaipur B2114 Page No.: 63


Object Oriented Programming – C++ Unit 3

In the above program, we have defined an external variable x. This variable


will be automatically initialized to zero. The statement x=x+2; will store two
in x. The function f1 will not have any impact on the value of the external
variable as there is another local automatic variable x defined in the function
which will be modified (Please note that when automatic and global variable
have same name, the local variable will override the global variable).
The function f2 will increment global variable by one. Thus, the final output
of the above program will be 3.
Static
The scope of static variables is within the function in which they are defined
like automatic variables. Static variables are the variables which are
initialized and storage space is allocated only once at the beginning of
program execution. The static variable retains its value until the end of
program and it is automatically initialized to zero like the external variables.
A variable is declared static by prefixing it its declaration by the keyword
static. Both local and global variables can be declared as static. When a
local variable is declared as static, it is known as static local variable. When
a global variable is declared as static, it is known as static global variable.
The lifetime and initialization of static global variable is the same as the
static local variable.
The below program (static.cpp) shows the use of the static variables.
// static.cpp
# include <iostream.h>
void main()
{
int num;
char ch;
do
{
cout<<”Enter a number”;
cin>>num;
f1(num);
cout<<”Do u want to enter another number”;
cin>>ch;
}while (ch==’y’)
Manipal University Jaipur B2114 Page No.: 64
Object Oriented Programming – C++ Unit 3

}
void f1(int x)
{ static int sum, n;
sum=sum+x;
n=n+1;
avg=sum/n;
cout<< “Average is”<<avg;
}
The above program allows the user to enter any number of integers and
computes the average of the numbers. The static variables sum and n are
initialized to zero. They are updated when user enters a new number and
the function is called. The values of these variables are retained even after
the function returns to the main program.
The summary of all three storage classes is shown below:
Automatic Static External
Visibility Function Function Program
Lifetime Function Program Program
Initialized Junk value in Zero Zero
to memory
Purpose Variables used Same as automatic but the Variables used
by single value should be retained by several
function when function terminates functions

Self Assessment Questions


9. Inline functions help in saving ______________ of programs
10. Static variables are initialized to _________ automatically.
11. External variables are accessible throughout the _________.

3.5 Strings
C++ implements strings as character array. We know that C language does
not support a built in string type. We have to use character arrays to store
and manipulate strings. One problem with character array is that memory
crashes due to insufficient declaration. To avoid that problem C++ provides
a new class called string. The string object may be used like any other
built-in data type. C++ provides a data type "string", by using string data
type we can declare and initialize string values easily.

Manipal University Jaipur B2114 Page No.: 65


Object Oriented Programming – C++ Unit 3

Strings are used to store character names like name, address, password etc.
Stings are similar to arrays. Like array, string sizes are also defined during
declaration statement. Main difference between string and array is that
every string in c++ must be terminated by null character (’/0’) to mark end of
the string. Strings, unlike other arrays can be input without using a loop.
When inputting strings using cin statement, the compiler stops taking input
from the user once it encounters space or linefeed (pressing enter key).
3.5.1 Declaration and initialization of strings
The string variable declaration and initialization can be done by using single
statement. The strings can also be initialized as arrays.
The following example declares an array of 6 elements of type char
initialized with the characters that form the word "hello" plus a null character
'\0' at the end. It is specified by enclosing the text (hello) between double
quotes.
char str[6]= “hello”;
Strings can also be defined without specifying the size, but in that case they
have to be initialized to a string constant as shown in the following example.
char str[]=”hello world”
However, there is no built in mechanism in C++ that disallows the user to
enter characters than the string maximum size. The extra characters
entered by the user will be truncated. To keep a check on the number of
characters, setw () function can also be used. To use this function,
iomanip.h header file should be included. Let us see one example of it in the
following program (stringexample.cpp).
#include<iostream.h>
#include<iomanip.h>
const int size=10;
void main()
{
char str[size];
cout<<”enter a string”;
cin>>setw(size)>>str;
}

Manipal University Jaipur B2114 Page No.: 66


Object Oriented Programming – C++ Unit 3

In the program shown above, the user can enter only nine characters
because last one character stores null character (’/0’). While the strings are
input, cin stops reading once it encounters space or linefeed character
(when user presses enter). To read the text containing blank space and to
read multiple lines of text cin.get function can be used. The following
statement will allow the user to input a maximum of 39 characters which can
even include blanks. It will stop reading once it encounters linefeed
character.
cin.get(str, 40);
To read multiple line of text from the user, you have to specify a terminating
character which will be used to recognize end of input. In the following
example, the terminating character is $.
cin.get(str,40,$);
The above example will allow users to enter a maximum of 39 characters
which can include embedded blanks and linefeed.
3.5.2 Standard C++ String functions
C++ standard library provides several string functions used to manipulate
strings. All string library functions are defined in the header file string.h.
Whenever you use string standard function, the header file “strig.h” has to
be included. The table 3.1 lists some of commonly used string functions
Table 3.1: String library functions
String Library
Meaning
function
strlen() Used to find the length of string
strrev() Used to arrange the characters in the string variable in
reverse order except for the null character.
strcpy Used to copy the contents of one string to another.
strcmp Used to compare two strings.
Strlen Function
This function is used to find the length of the string. The general syntax is:
strlen(string variable)
strlen(n) function returns the number of characters or length of the string n.

Manipal University Jaipur B2114 Page No.: 67


Object Oriented Programming – C++ Unit 3

The return value of the function is integer.


Example:
int X;
char s[10]= “ SMUDDE”
X= strlen(s);
The number of characters in string s is six characters. So the length of the
string is stored in integer variable X.
Strrev function
This function is used to arrange the characters in string in reverse order
except for the null character. The general syntax is:
strrev(string variable)
This function returns the reversed string.
Example:
char A[10] = “HAI”
cout<<strrev(A);
The output will be IAH
Strcpy function
This function is used to copy the content of one string to another. The
general syntax is:
strcpy(destination string, source string);
This function copies the source string content to destination string content.
Example:
char p[10] = “OOPS”;
char q[10];
strcpy(q, p);
cout<<q;
The output will be OOPS.
The strcpy can also use string constants to be assigned to a string variable
like in the following statement.
strcpy(q,”OOPS”);

Manipal University Jaipur B2114 Page No.: 68


Object Oriented Programming – C++ Unit 3

In the statement shown above, the string constant OOPS is assigned to the
string variable name q. The assignment of a string variable cannot be done
using an assignment operator. It should be done using strcpy function.
Strcmp function
Strcmp function is used to compare two strings. The syntax of strcmp is :
strcmp(string1,string2)
Every character of string1 will be compared with the corresponding
character of string2. The ASCII values of the character will be used to
decide the return value. The function returns an integer and the value
returned will differ based on the conditions as shown below:
If string1 < string2, value returned will be <0
If string1==string2, value returned will be 0
If string1> string2, value returned will be greater than zero.
Thus, a return value 0 implies that strings are equal and a non-zero return
value implies that the two strings are not equal. Please note that the above
function is case sensitive. strcmpi () function can be used if the two strings
have to be compared without case sensitiveness.
The following program (stcmpexample.cpp) implements strcmp function
// stcmpexample.cpp
#include <iostream.h>
#include <string.h>
void main ()
{
char str1[30], str2[30];
for(int i=0;i<10;i++)
{
cout<<"Enter first string: ";
cin>>str1;
}
for(int i=0;i<10;i++)
{
cout<<"Enter first string: ";
cin>>str2;
}

Manipal University Jaipur B2114 Page No.: 69


Object Oriented Programming – C++ Unit 3

if(strcmp(str1,str2)==0)
cout<<"Both strings are equal";
else
cout<<"Strings are unequal";
return 0;
}
Self Assessment Questions
12. The string variable declaration and initialization can be done by using
single statement. (True/False)
13. _____________ Function is used to copy the contents of one string to
another.
14. To read blanks between the strings or to read multiple lines of text,
_________ function which is a member function of cin can be used

3.6 Structures and Unions


In unit 2 you have learnt arrays and the process of grouping together similar
type of data. We can also group together different type of data which are
logically related. We can do this through structures and unions. In this
section, we will discuss the use of structures and unions.
Structures
Structures are used for grouping together elements with dissimilar types.
The general syntax of structure declaration is:
struct name {
datatype member1;
datatype member2;
........
.........
};
For example, if you want to store all the details of an employee such as
employee id (integer), name (string), department code(integer), and salary
as one entity, you can do this using structure as shown below:
struct employee
{ int empid;
char name[35];

Manipal University Jaipur B2114 Page No.: 70


Object Oriented Programming – C++ Unit 3

int deptcode;
float salary;
};
Structure is a feature in C++ that enables you to define a user-defined
datatype. Once you specify the definition of the structure, you can create
variables of that structure. In the above definition, we have defined a
structure using the keyword struct followed by the name of the structure
(employee). All the data items that need to be defined are defined by
specifying the datatype and name of the variable. Once the definition is
done, variables of type employee can be created. For example, the
following statement creates a variable e1 of type employee.
employee e1;
Structure variables can be initialized during declaration. The values for all
the members should be specified separated by comma and all the values
enclosed within flower brackets as shown below
employee e1= {1234, “Ajay”, 12, 6900.00};
Structure variables can be copied and assigned to another structure
variable as shown below
employee e2;
e2=e1;
To access the members of the structure variables, dot operators can be
used. For example to access empid of structure variable e1, you would say
e1.empid (structure variable. member variable name).
Structures can be nested within each other. When accessing the members
and sub members dot operators can be used. Let us suppose you have
defined a structure named distance with two members’ length and width as
declared below:
struct distance
{ int feet;
int inches;
}

Manipal University Jaipur B2114 Page No.: 71


Object Oriented Programming – C++ Unit 3

Let us now define a structure named room, which contains variables of type
distance:
struct room
{ distance length;
distance width;
distance height;
} bedroom;
In the definition of room given above, we have declared a variable bedroom
of type room along with the definition. To access the members of the
bedroom you can use:
bedroom.length.feet
bedroom.length.inches
bedroom.width.feet
bedroom.width.inches and so on
To initialize nested structures you have to group together all the elements of
the structure:
room dining = {{12, 3},{13,0},{11,2}}
In the declaration of room dining, the values 12 and 3 refer to
dining.length.feet and dining.length.inches respectively. Similarly, the
second and third set of values represent feet and inches of width and height
respectively.
You can also create array of structures. For this, the index number should
be specified immediately after the structure variable. For example, the
statement
employee emp[50] ;
will create an array of structure employee.
To access the first array member, you can say emp[0].empid
The below program (structexample.cpp) implements a structure point with
x and y co-ordinates.
//structexample.cpp#include<iostream.h>
#include<conio.h>
# include<math.h>
struct point

Manipal University Jaipur B2114 Page No.: 72


Object Oriented Programming – C++ Unit 3

{ int x,y;
} p1,p2;
void main()
{
int s;
cout<< “Enter the co-ordinates for first co-ordinate” ;
cin>> p1.x>>p1.y;
cout<<”enter the co-ordinates for second co-ordinate”;
cin>>p2.x>>p2.y;
s=sqrt(((p2.y-p1.y)*(p2.y-p1.y))+((p2.x-p1.x)*(p2.x-p1.x))) ;
cout<<endl<<”the distance between the two points is”<<s;
getch();
}
In the program shown above, we have defined a structure point which
stores x and y co-ordinates of the point. Along with the declaration, we have
also created two point variables p1 and p2. This is a way to create variables
along with the structure declaration. This can be a separate statement also
as discussed earlier. The program accepts two points from the user and
displays the distance between them.
Structures are good mechanism of creating user defined datatypes. C++
specifies another method known as enumerated data type to enable users
create their own datatypes. Enumerated data types can store fixed set of
values and you can perform arithmetic on them as well. They are defined
using the keyword enum. The program shown below (enumerated.cpp)
creates an enumerated datatype that stores different days of the week.
//enumerated.cpp
#include <iostream.h>
enum weekday {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
void main ( )
{
weekday day1,day2;
day1=Mon;
day2= Fri;
int diff=day2-day1;
cout<<”days between =”<<diff;
if (day1<day2)
Manipal University Jaipur B2114 Page No.: 73
Object Oriented Programming – C++ Unit 3

cout<<”day1 comes before day2”;


}
In the program given above, enumerated datatype - weekday is created.
The first value (Sun) is assigned zero by default and so on. The variables
day1 and day2 can be assigned only the values specified in the datatype
declaration or their integer equivalent. They cannot be assigned any other
value.
Union
Union is a special type of class that can hold only one of its non-static data
members at a time. Union declaration is similar to structure declaration as it
allows us to group together dissimilar type of elements inside a single unit.
The difference between structures and unions with regard to their
implementation is that the size of structure type is equal to sum of the sizes
of individual members. However, the size of union is equal to the size of
large number of element.
In simple words, we can say that unions are memory-efficient alternatives of
structures particularly in situations where it is not required to access the
different member elements simultaneously. Example of union is:
union result
{
int marks;
char grade;
float percentage;
};
The union occupies 4 bytes in memory as it is the largest size member
element. However, if we define the same with the help of structure, it will
occupy
7 bytes of memory (i.e. sum of size of individual member elements).
So, we can say that unions are memory-efficient alternatives of structures
particularly in situations where it is not required to access the different
member elements simultaneously.
Self Assessment Questions
15. Structures and unions are used to group data of similar type.
(True/False)

Manipal University Jaipur B2114 Page No.: 74


Object Oriented Programming – C++ Unit 3

16. ___________ Keyword is used to create structures.


17. Member data of the structure are accessed by ________ operator.

3.7 Summary
Let us recapitulate the important points of this unit:
 Functions provide good mechanism to organize data. Functions are
given a name which can be used to call the function and execute the
statements in the functions.
 Functions can also take inputs which are known as arguments which
passed during function call.
 Arguments can be passed either by value or by reference. They can
also have return value which can return a computed value back to the
main program.
 Inline functions enable programmers to save processing time by
reducing the overheads involved in function call.
 Programs can make use of automatic, external and static variables
which have different types of utility depending on the way the variable
should be accessed and whether the value has to be retained.
 Strings are nothing but character arrays. C++ standard library provides
several string functions used to manipulate strings.
 Structures and unions data types enable users to create user defined
data types. Structure, is a group data item which has heterogeneous
collection of data.
 Enumerated data types create data types that can store pre-defined and
fixed set of values.
 Union is a special class type that can hold only one of its non-static data
members at a time.
 Union declaration is similar to structure declaration as it allows us to
group together dissimilar type elements inside a single unit.

3.8 Terminal Questions


1. Differentiate between the way arguments are passed in terms of pass by
value and pass by reference.
2. Define inline function. Explain it using example.

Manipal University Jaipur B2114 Page No.: 75


Object Oriented Programming – C++ Unit 3

3. What is a string? Explain with example how string can be declared and
initialized.
4. Differentiate between structures and unions.
5. Define a structure named product with elements productcode,
description, unitprice and qtyinhand. Write a C++ program that
implements the structure and enables to store at least 100 product data.
6. Write a function that takes input as radius of the circle from keyboard
and return the area of the circle.
7. Write a function that takes two integers, finds out which is smaller and
then assigns zero to the smaller variable and returns the value.

3.9 Answers
Self Assessment Questions
1. function prototype
2. function signature
3. return
4. True
5. pass by value
6. returning multiple values and modifying original values
7. Function overloading
8. declaration
9. execution time
10. zero
11. Program file
12. True
13. Strcpy
14. get
15. False
16. struct
17. dot operator (structure variable name.member name)
Terminal Questions
1. One method of passing data to function is passing by value. In this way
of passing variables, a copy of the variable (main program) is created
during function call with the name specified in the function and initialized
with the value in the original variable.

Manipal University Jaipur B2114 Page No.: 76


Object Oriented Programming – C++ Unit 3

Another alternative to passing arguments is passing by reference. In


passing by reference, no copy of the variable is created. However, the
variables in the main program are referred to by different name in the
function. Refer to section 3.3.1 and 3.3.2 for more details.
2. The main use of inline function is it reduces the size of the code and
speed up the programs. You should define inline function before the
main () function. Inline functions are same like normal functions except
that the function declaration begins with the keyword inline. Refer to
section 3.4 for more details.
3. The string variable declaration and initialization can be done by using
single statement. The strings can be also initialized as arrays. Refer to
section 3.5.1 for more details.
4. The difference between structures and unions as far as their
implementation is concerned. The size of structure type is equal to sum
of the sizes of individual members. However the size of union is equal to
the size of large number of element. Refer to section 3.6 for more details.
5. //arrayproduct.cpp
# include <iostream.h>
structure product
{ int productcode;
char description;
float unitprice;
int qtyinhand;
}p[100];
void main()
{ int i;
for(i=0;i<100;i++)
{
cout<<”enter product code”;
cin>>p[i].productcode;
cout<<”enter product description”;
cin>>p[i].description;
cout<<”enter unit price”;
cin>>p[i].unitprice;
cout<<”enter qty in hand”;

Manipal University Jaipur B2114 Page No.: 77


Object Oriented Programming – C++ Unit 3

cout<<p[i].qtyinhand;
}
}

6. //areacircle.cpp
# include <iostream.h>
int carea(int radius); // function declaration
void main()
{
int radius ;
cout<< “enter radius”;
cin>>radius;
cout<<“The area of circle is”<<carea(radius)<<endl;
}
int carea(int radius) //function defintion
{ int a;
a= 3.14*radius*radius;
return a;
}
7. //smallzero.cpp
# include <iostream.h>
void smallzero (int& m, int& n); // function declaration
void main()
{
int a,b ;
cout<< “enter two numbers”;
cin>>a>>b;
smallzero(a,b);
cout<<“The value of a is”<<a<<endl;
cout<<“The value of b is”<<b<<endl;
}
void smallzero(int& m, int& n) //function definition
{ if (m<n)
m=0;
else if (m>n)
n=0
else

Manipal University Jaipur B2114 Page No.: 78


Object Oriented Programming – C++ Unit 3

{
m=0;
n=0;
}
}

References:
 An Introduction to Object-Oriented Programming in C++, 2nd edition,
By Graham M. Seed, Springer Science & Business Media.
 Object Oriented Programming with C++ - Sixth Edition,
by E Balagurusamy. Tata McGraw-Hill Education.
 Object-Oriented Systems in C++, by Dr. Durgesh Pant, Mahesh Kumar
Sharma, K.S. Vaisla, Firewall Media.

Manipal University Jaipur B2114 Page No.: 79


Object Oriented Programming – C++ Unit 4

Unit 4 Classes and Abstraction


Structure:
4.1 Introduction
Objectives
4.2 Creating Classes
4.3 Creating Objects
4.4 Access Specifiers
4.5 Objects and Arrays
4.6 Objects and Functions
4.7 Objects and Pointers
4.8 Abstract class
4.9 The this Pointer
4.10 Friend Functions
4.11 Static Variable and Static Functions
4.12 Summary
4.13 Terminal Questions
4.14 Answers

4.1 Introduction
In the previous unit, you have studied how to reuse code using function.
You have also studied storage classes, strings (array of characters),
structures and unions. Structures and unions are used to group
heterogeneous data.
In this unit, we will discuss implementation of objects and classes. In real life
we come across the situations where we have to model the functionality of
data type along with data. Classes bind data and functions that act on data
together. However, in C++ structures are used in the same way as classes
by binding together functions and data. But you should use structures only
in situations when it is required to group together the data and the functions.
In C++ there are objects which are the instances of class. The objects have
a similar relationship with classes as variables have with data types. Object
is an instance of a class.
In this unit, we will also discuss important features of C++, such as, access
specifiers, abstract classes, this pointer, friend functions, and static
functions.

Manipal University Jaipur B2114 Page No.: 80


Object Oriented Programming – C++ Unit 4

Objectives:
After studying this unit you should be able to:
 explain the role of class and objects in oops
 define different types of access specifiers
 describe this pointer
 discuss friend function, its advantages, and scope
 discuss static variables and static functions.

4.2 Creating classes


In unit 1, you have studied the basic features of Objects Oriented
programming. In this section we will discuss the uses of classes and how to
create a class. Classes provide users a way to create user defined data
types.
Classes provide a convenient way to group related data and the methods
that operate on data together. One advantage of creating a class is that
when you create an object from the class, you automatically create all the
related fields. Another advantage of using classes is that you can think
about them and manipulate them in the same way as you do with real-life
classes.
Characteristics of class:
A class is a template that units data and operations.
A class is an abstraction of the real world entities with similar properties.
A class identifies a set of similar objects.
A class is implementation of an abstract data type.
You can define a class by using the keyword class followed by the name of
the class and an open and closed brace. Between curly braces, you define
all the data and member functions of class. When you create or define a
class you can describe what it has and can do.
General syntax of class:
class classname
{
variable declaration;
function declaration;
Manipal University Jaipur B2114 Page No.: 81
Object Oriented Programming – C++ Unit 4

}
Real world entities such as, employee, vehicle, animal, etc. can be modelled
by class or it can model a user defined data type such as string, distance,
etc.
Example:
class Student
{
int rollnumber;
string name;
float grade;
};
Let see one more simple example of class

class product
{
int product_id; // data varibles declartion
double cost;
void getdat(int a, float b); // member function decalrtion
void putdat(void);
}
In the above example the class product contains two data variables and two
member functions.
Self Assessment Questions
1. A ________ is an abstraction of the real world entities with similar
properties.
2. A class is an implementation of _____________ datatype.

4.3 Creating objects


Objects hold the similar relationship with class as a variable holds with a
data type. An instance of a class is known as an object of that class and is
used in the program to store data. The objects are declared in the program
like the variable declaration.
Objects are mainly used for the following purposes:
 Understanding real world and a practical base for designers.

Manipal University Jaipur B2114 Page No.: 82


Object Oriented Programming – C++ Unit 4

 Decomposition of a problem into objects depends on judgment and


nature of problem.
A blueprint for objects is given by class. Basically an object is created from
a class. The object is created by using the class name followed by the
object name. The statements shown below declare two objects of class
product.
product p1; // declare p1 object of the type product
product p2; // declare p2 object of the type product
Both of the objects p1 and p2 will have their own copy of data members.
The object creation syntax that has been used so far called direct
initialization. The object can also be value initialization.
product p=product(); // value initialization
The parentheses can supply constructor arguments, or remain empty to
construct the object using parameter less constructor.
To understand the various syntactical requirements for implementing a
class, let us take an example.
// distance.cpp
#include<iostream.h>
class distance
{ private:
int feet;
int inches;
public:
void setdistance(int c, int d)
{ feet=c;
inches=c;
}
void printdistance()
{ cout<<feet<<”ft”<<inches<<”inches;
};
void main()

Manipal University Jaipur B2114 Page No.: 83


Object Oriented Programming – C++ Unit 4

{ distance d1;
d1. setdistance(10, 2);
d1.printdistance();
}
In the above program, there is a class distance with two data members- feet
and inches and two member functions or methods; setdistance() and
printdistance(). You can define a class with the keyword class followed by
the name of the class. As you can see in the main program, d1 is an object
of class distance. Every object of a class has its own copy of data, but all
the objects of a class share the functions. There is no separate copy of the
member function for every object of class. The data can be accessed by the
objects through member functions or methods. To invoke the member
functions of class we have to use object of that class. The member functions
cannot be invoked without the objects of the class. The methods defined in
the class can only be invoked by the objects of the class. Without an object,
methods of the function cannot be invoked.
Self Assessment Questions
3. An instance of a class is known as an ______ of that class and is used
in the program to store data.
4. The object is created by using the class name followed by object name.
(True/False)

4.4 Access Specifiers


As you have seen in the above program, we have defined the data elements
-feet and inches- as private and member functions or methods as public.
These are known as access specifiers. Data and functions in a class can
have any one of the following access specifiers: private, public and
protected. Only the member functions of the class can access the private
data and functions but the external functions cannot access it. Any external
function of the class can access public data and member functions and for
that you need to have an object of that class. This feature of object oriented
programming is sometimes referred to as data hiding. The data is hidden
from accidently getting modified by an unknown function. Only a few sets of
functions can access the data. By default, the data and functions are private

Manipal University Jaipur B2114 Page No.: 84


Object Oriented Programming – C++ Unit 4

in a class so there is no need to explicitly mention the private keyword these


are depicted in figure 4.1.

Figure 4.1: Access specifiers in a class

The methods or member functions are referred to as messages in some


programming languages. Thus, d1.display() is a message to d1 to display
itself. Generally, data are declared as private and functions as public.
However, in certain cases, you may even declare functions as private and
data as public. The class definition should be terminated with a semicolon.
You can also create an array of objects that is same as the array of
structures. For example distance d[10]; creates an array of objects of type
distance. If the first distance object accesses the member function display
you can use d[0].display().
Self Assessment Questions
5. Data and functions in a class can have any one of the following access
specifiers ___________.
6. In general practice, data are declared as ________ and functions as
_________.

4.5 Objects and Arrays


In the above section, we mentioned about creating an array of objects. In
this section we shall discuss this concept in more detail. The data type of
array can be of any type including struct. So there can be arrays of variables

Manipal University Jaipur B2114 Page No.: 85


Object Oriented Programming – C++ Unit 4

of type class and those variable are called arrays of objects. Let us consider
the following definition of class:
class distance
{
Private:
int feet;
float inches;
public:
void getdist();
void printdist();
};
The identifier distance is a name of the class which is a user defined
datatype and can be used to create objects of type distance.
Example:
distance D[2] // array of two distances
distance dist[5] //array of five distances
The array D contains two objects namely D[0] and D[1]. The array dist
contains five objects namely dist[0], dist[1], dist[2], dist[3].
To access the member functions you can use the usual array accessing
method followed by a dot operator.
For example the statement D[i].printdist(); will print the distance value of ith
element of the array D.
We will demonstrate it by a program array.cpp containing array of distances.
//array.cpp
#include<iostream.h>
class distance
{
private:
int feet;
float inches;
public:
void getdist() //input length from user

Manipal University Jaipur B2114 Page No.: 86


Object Oriented Programming – C++ Unit 4

{
cout<< “ enter feet:\n”;
cin>>feet;
cout<<”enter inches:”;
cin>> inches;
}
void printdist() // print the distance
{
cout<< feet << “\ ‘ -“ << inches << ‘\” ’;
}
};
int main()
{
distance D[50]; //array of distances
int count=0; // count the entries
char res; //response of user (y or n)
cout<< endl;
do
{
cout<< “ enter the value of distance:” << count+1;
D[n++].getdist(); //store distance in array
cout<< “ do you want to enter another distance (y/n)?:”;
cin>>res;
} while(res!= (’n’ || ‘N’))
for(j=0; j<count; j++)
{
cout<< “\ndistance number” << j+1 << “ is “;
D[j].showdist();
}
cout<<endl;
return 0;
}
In this program the user can enter the required number of distances.
After entering every distance. The program asks if user wants to enter

Manipal University Jaipur B2114 Page No.: 87


Object Oriented Programming – C++ Unit 4

another distance value. If not, then the program terminates and prints all the
distances entered. Here is the output of the program when user enters three
distances.
enter distance number:1
enter feet:4
enter inches:5
do you want to enter another distance(y/n)? y
enter the value of distance:2
enter feet: 7
enter inches: 8
do you want to enter another distance(y/n)? n
distance number 1 is 4’ -5”
distance number 2 is 7’ -8”
Self Assessment Questions
7. There can be arrays of variables of type class and those variable are
called _________.

4.6 Objects and Functions


In this section you will learn to perform operations on data. We can start
with a program which implements an add member function to the distance
class. This can be done in two ways. Shown below are the prototypes of the
function:
void add(distance, distance);
or
distance add(distance);
The first function takes two distance objects as arguments and stores the
result in the object invoking the member function. It can be implemented as
follows:
//adddistance.cpp
#include<iostream.h>
class distance
{ private:
int feet;
Manipal University Jaipur B2114 Page No.: 88
Object Oriented Programming – C++ Unit 4

int inches;
public:
void setdistance(int c, int d)
{ feet=c;
inches=d;
}
void printdistance()
{ cout<<feet<<”ft”<<inches<<”inches;}
void adddist(distance d1, d2)
{ feet=d1.feet+d2.feet;
inches=d1.inches+d2.inches;
if (inches>12)
{ feet++;
inches=inches-12;
}
}
};
void main()
{ distance D1,D2,D3;
D1. setdistance(10, 2);
D2.setdistance(2,4);
D3.adddist(d1,d2);
D3.display();
}
In the above program, object D3 invokes the add function so the feet and
inches refer to invoking object’s data members. After adding the respective
data of D1 and D2 it is stored in D3 object.

4.7 Objects and Pointers


Pointers can point to simple data types, arrays and to objects as well. Let us
consider the following statement:
item A;

Manipal University Jaipur B2114 Page No.: 89


Object Oriented Programming – C++ Unit 4

Here item is a class and A is the object of the class item. You can define a
pointer iptr of type item as shown below:
item *iptr;
We use pointers in the situations where we do not know that how many
objects we have to create in a program. In that situation we use new
function to create objects at run time. The new function returns a pointer to
an unnamed object. Let us understand this concept with the help of an
example shown below.
//pointer.cpp
#include<iostream.h>
class distance
{
private:
int feet;
float inches;
public:
void getdist() //input length from user
{
cout<< “ enter feet:\n”;
cin>>feet;
cout<<”enter inches:”;
cin>> inches;
}
void printdist() // print the distance
{
cout<< feet << “\ ‘ -“ << inches << ‘\” ’;
}
};
int main()
{
distance D; //define a named distance object
D.getdist();

Manipal University Jaipur B2114 Page No.: 90


Object Oriented Programming – C++ Unit 4

D.printdist();
distance *dptr; //pointer to distance class
dptr = new distance; //points to new distance object
dptr->getdsit(); // points to new distance object
dptr->printdist(); //access object members with -> operator
return 0;
}
The main() function defines dist, uses the Distance member function
getdist() to get a distance from the user and then uses printdist() to display
it.
Self Assessment Questions
8. We use ________ in the situations where we do not know how many
objects we need to create in a program.
9. The new function returns a pointer to an unnamed object. (True/False)

4.8 Abstract class


An abstract class is the class which acts as a base class and can be
inherited by other classes. It is not used to create objects. It provides a base
upon which other classes can be built. In programming the concept of
abstract class is of great importance and used deliberately in a program for
creating derived class.
You can make a class abstract by declaring at least one of its virtual
functions as pure virtual function. You can specify a pure by placing "= 0" in
its declaration. An example is shown below:

class container
{
public:
virtual double getvolume() = 0; //pure virtual function
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box

Manipal University Jaipur B2114 Page No.: 91


Object Oriented Programming – C++ Unit 4

};
The concept of pure virtual function is discussed in unit 8.
Abstract Class Example:
Let us see the following example where an interface is provided by parent
class to the base class to implement a function called getArea().
include <iostream.h>

// Base class
class shape
{
public:
// pure virtual function providing interface framework.
virtual int getarea() = 0;
void setlenght(int l)
{
length = l;
}
void setbreadtht(int b)
{
breadth = b;
}
protected:
int length;
int breadth;
};
// Derived classes
class rectangle: public shape
{
public:
int getarea()
{
return (length * breadth);
}

Manipal University Jaipur B2114 Page No.: 92


Object Oriented Programming – C++ Unit 4

};
class square: public shape
{
public:
int getarea()
{
return (length*length);
}
};

int main()
{
rectangle rect;
square sq;;

rect.setbreadth(5);
rect.setlengtht(7);
// Print the area of the object.
cout << Area of rectangle is: " << rect.getarea() << endl;

sq..setlenght(5);
// Print the area of square.
cout << "Area of square is: " << sq..getarea() << endl;

return 0;
}
The result of the above program is as shown below:
Area of rectangle is: 35
Area of square is: 25

4.9 The this Pointer


Every time when the program creates a class instance, a special pointer is
created in C++ called this and it contains the address of the current object
instance. The address of the class instance is passed as an implicit

Manipal University Jaipur B2114 Page No.: 93


Object Oriented Programming – C++ Unit 4

parameter to the member functions. The example shown below describes


how to use this pointer. C++ maintains a single copy of its member functions
and memory is allocated to data members for all of their instances. And
these many instances of data are maintained by this pointer.
The following are the features of this pointer:
 this pointer stores the address of the class instance, to enable pointer
access of the members to the member functions of the class.
 this pointer is not counted for calculating the size of the object.
 this pointers are not accessible for static member functions.
 This pointer can’t be modified. Let us see the following example to
understand the concept of this pointer.
class this_pointer_example { // class for explaining C++ tutorial
int data1;
public:
//Function using this pointer for C++ Tutorial
int getdata() {
return this->data1;
}
//Function without using this pointer
void setdata(int newval) {
data1 = newval;
}
};
Thus, a member function can gain the access of data member by either
using this pointer or not.

Self Assessment Questions


10. __________________ contains address of the current object instance.
11. this pointers can be modified. (True/false)

4.10 Friend Functions


Friend functions allow us to access some non-member functions or other
classes in C++. Access to non-member functions or to another class is
given in C++ by using friend keyword. The private as well as protected class

Manipal University Jaipur B2114 Page No.: 94


Object Oriented Programming – C++ Unit 4

members can be accessed by friend classes. There are places where


friends can lead to more intuitive code, and are often needed to correctly
implement operator overloading.
From designer’s point of view, friend functions can be treated similar to that
of public member functions. The concept of a class interface can be
extended from public members to include friend functions and friend
classes. Put another way: Friend functions do not break encapsulation;
instead they naturally extend the encapsulation barrier.
You can declare friend function anywhere in the class declaration. But in
common practice we list friends at the beginning of the program as the class
has no control over the scope of friends so the public and protected
keywords do not apply to friend function
If we want to declare an external function as friend of a class, thus allowing
this function to have access to the private and protected members of this
class, we do it by declaring a prototype of this external function within the
class, and preceding it with the keyword friend:
// friend functions
#include <iostream.h>
class Rect
{
int w, h // w is the variable to store width and h is the variable to store
height
public:
void setvalue (int, int);
int area () {return (w * h);}
friend Rect duplicate (Rect);
};
void Rect::setalue (int c, int d) {
w = c;
h = d;
}
Rect duplicate (Rect rectparam)
{

Manipal University Jaipur B2114 Page No.: 95


Object Oriented Programming – C++ Unit 4

Rect r;
r.w = rectparam.w*2;
r.h = rectparam.h*2;
return (r);
}
int main () {
Rect r1, r2;
r1.setvalues (2,3);
r2 = duplicate (r1);
cout << r2.area();
return 0;
}
The function duplicate is a friend of Rect function. With the friend function
named duplicate, it is possible to access the members w and h of objects of
type rectangle. You can observe that the function duplicate is not a member
function of class Rect but it has access to the private members of the class
Rect.
Friend Classes
You should use friend class in the situation when the two classes are
strongly coupled. For example, suppose we have a class CCord that
represents a coordinate, and a class CCollect that holds a list of points. The
collections class may be used to change the point objects so we can
declare CCollect as a friend class of CCord.
// Forward declaration of friend class.
class CCollect;
// Point class.
class CCord {
friend CCollect;
private:
double m_x;
double m_y;
public:
CCordt(const double x, const double y):

Manipal University Jaipur B2114 Page No.: 96


Object Oriented Programming – C++ Unit 4

m_x(x),
m_y(y) { }
~C Cord(void) { }
// ...
};
As you can see in the example above, the CCollect and CCord classes are
friend classes. Hence, CCollect class can access the data of any object of
CCord class. This is proved to be useful when you need to modify individual
elements of class CCollect. For example a setvalue method ofclass
CCollect can set all the values of the class CCord to a particular value.
class CCollect {
private:
vector<CCord> m_vecPoints;
public:
CCollect(const int nSize) :
m_vecPoints(nSize) { }
~CCollect(void);
void set(const double x, const double y);
// ...
};
The set member can iterate over the collection and reset each point:
void CCollect::set(const double x, const double y) {
// Get the number of elements in the collection.
const int nElements = m_vecPoints.size();
// Set each element.
for(int i=0; i<nElements; i++) {
m_vecPoints[i].m_x = x;
m_vecPoints[i].m_y = y;
}
}
The friendship is not mutual among friend classes. As in the above
example, CCollect class can access the data of CCord but the vice versa is
not true. The friendship is not passed down in the hierarchy of class. For
example the derived classes of CCollect will not be able to access the data

Manipal University Jaipur B2114 Page No.: 97


Object Oriented Programming – C++ Unit 4

of CCord class. The principle is that it is not possible for a class to implicitly
grant friendship; each class must choose its friends explicitly.
Friend Scope
The friend function’s name or class which is introduced first in a friend
declaration is not in the scope of class granting friendship (also known as
the enclosing class). And also it is not a member of class granting
friendship.
The name of a function first introduced in a friend declaration is in the scope
of the first nonclass scope that contains the enclosing class. The body of a
function provided in a friend declaration is handled in the same way as a
member function defined within a class. Processing of the definition does
not start until the end of the outermost enclosing class. In addition,
unqualified names in the body of the function definition are searched for
starting from the class containing the function definition.
If we introduce a friend’s class name before the friend declaration, then the
compiler will search for a class name that matches with the name of the
friend class beginning at the scope of the friend declaration. If the name of a
friend class is introduced before the friend declaration, the compiler
searches for a class name that matches with the name of the friend class
beginning at the scope of the friend declaration. If the declaration of a
nested class is followed by the declaration of a friend class with the same
name, the nested class is a friend of the enclosing class.
The scope of a friend class name is the first nonclass enclosing scope. For
example:
class X {
class Y { // arbitrary nested class definitions
friend class Z;
};
};
is equivalent to:
class Z;
class X {
class Y { // arbitrary nested class definitions
friend class Z;

Manipal University Jaipur B2114 Page No.: 98


Object Oriented Programming – C++ Unit 4

};
};
You have to use the scope resolution operator(::) if the friend function is a
member of another class. Example to explain this concept is shown below.
class X {
public:
int func() { }
};
class Y {
friend int A::func();
};
Friends of a base class are not inherited by any classes derived from that
base class. The following example demonstrates this:
class X {
friend class Y;
int p;
};
class Y { };
class Z : public Y {
void func(p* q) {
//q->p = 2;
}
};
The compiler would not allow the statement p->q= 2 because class Z is not
a friend of class X, although Z inherits from a friend of X.
Friendship cannot be transitive. The example below explains this concept.
class X {
friend class Y;
int p;
};
class Y {
friend class Z;
};
class Z {
Manipal University Jaipur B2114 Page No.: 99
Object Oriented Programming – C++ Unit 4

void func(pA* q) {
//q->p = 2;
}
};
The following statement q->a = 2 is not allowed by compiler as classes Z
and x are not friends, even though class Z is a friend of friend of X.
If you declare a friend in a local class, and the friend's name is unqualified,
the compiler will look for the name only within the innermost enclosing
nonclass scope. Before declaring a friend of a local scope you must declare
a function. However, the declaration of a friend class will hide a class in an
enclosing scope with the same name. The example to explain the concept is
shown below. The following example demonstrates this:
class X { };
void a();
void f() {
class Y { };
void b();
class A {
friend class X;
friend class Y;
friend class Z;
//friend void a();
friend void b();
//friend void c();
};
::X moocow;
//X moocow2;
}
The following statements will be allowed by the compiler in the above
example:
 friend class X: This statement does not declare ::X as a friend of A, but
the local class X as a friend, even though this class is not otherwise
declared.

Manipal University Jaipur B2114 Page No.: 100


Object Oriented Programming – C++ Unit 4

 friend class Y: In the scope of f() the local class Y is declared. friend
class Z: This statement declares the local class Z as a friend of A even
though Z is not otherwise declared.
 friend void b():In the scope of f() the function b() has been declared.
 ::X moocow: The object of the nonlocal class ::X is created by this
statement.
The following statements will not be allowed by the compiler: friend void a():
The function a() is not considered by this function in namespace scope. The
compiler will not allow this statement as the function a() is not declared in
scope of a(). friend void c(): The compiler will not allow this statement
because the function c() is not declared in the scope of f().X moocow2: This
statement attempt creating an object of the local class named X, and not the
nonlocal class ::X. This statement is not allowed by the compiler because
the local lass X is not defined.
Self Assessment Questions
12. Access to non-member functions or to another class is given in C++ by
using ____________ keyword.
13. In general practice the friend functions are listed in __________ of the
program.

4.11 Static variables and Static Functions


You have observed that a separate copy of data members is created for
every object when it is created. But there is an exception in terms of static
data members. Static data member of the class is one data member that is
common for all the objects of the class and is accessible for the class. It is
beneficial to store some common data about the class like count of number
of objects created for a class. To declare static data member you should
prefix it with the keyword ‘static’.
You have already learnt in the unit that member functions of a class are
invoked via objects of the class. Let us suppose that we have a static data
member that contains count of the total objects created and a function
display_count prints the total. We cannot access the total without the
support of Static functions or a special type of functions which can be
invoked even without an object of the class. To define the static function you
should prefix it with the keyword ‘static’. Static functions are also defined by

Manipal University Jaipur B2114 Page No.: 101


Object Oriented Programming – C++ Unit 4

prefixing the keyword static. You can call the static function by using the
name of the class and then the scope resolution operator followed by the
function name. The example below demonstrates the implementation of
static data and static functions.
//static.cpp
# include <iostream.h>
class X {
static int count;
int id;
public:
X()
{ count++;
id=count;
}
~X()
{ count--;cout<<"\n destroying ID number="<<id;
}
static void display_count()
{cout<<"endl "<<countl;}
void showid()
{cout<<"endl "<<id;}
};
int X::count=0;
void main()
{
X::display_count();();X x1, x2;
X::display_count();
x1.showid();
x2.showid();
}

Manipal University Jaipur B2114 Page No.: 102


Object Oriented Programming – C++ Unit 4

The output of the above program is:


0
2
1
2
In the above program count is a static variable which is shared by all objects
of the class X. We have to explicitly initialize the static variables outside the
class. Static variable is declared using the name of the class then the scope
resolution operator followed by the name of the static variable. You should
keep in mind that during initialization of static data member you need to
specify the data type and no need to specify the static keyword. In the
above program there is a static variable count which is incremented in the
constructor when the new object is created. And whenever the object is
destroyed, the count is decremented by the destructor. In the program the
static function is display_count which can be invoked by using the name of
the class without using the object of the class.
The comparison between a static member functions and non-static member
functions are shown in table 4.1.
Table 4.1: Comparison between static and non-static member functions

Static member function Non-static member functions


Only the static member data, static Whereas all of these including static
member functions , data and functions data member can be accessed by
outside the class can be accessed by non-static functions.
the static member functions
Even if the class is not initiated it is But these functions can be called only
possible to call a static member through the objects of the class.
function.
It is not allowed in C++ to declare These functions can be declared as
these functions as virtual virtual.
Do not have access to this pointer of Have access to this pointer of the
the class. class.
These functions are not used very These function are used frequently in
frequently in the class but there are the programs.
very useful when the class is not
initialized.

Manipal University Jaipur B2114 Page No.: 103


Object Oriented Programming – C++ Unit 4

You cannot declare the static and non-static member functions with the
same name, having same number and same type of arguments. A static
member function does not have this pointer. The following example
demonstrates this:
#include <iostream.h>
struct X
{
private:
int i;
static int si;
public:
void set_i(int arg) { = arg; }
static void set_si(int arg) { si = arg; }
void print_i() {
cout << "Value of i = " << i << endl;
cout << "Again, value of i = " << this->i << endl;
}
static void print_si() {
cout << "Value of si = " << si << endl;
//cout << "Again, value of si = " << this->si << endl;
}
};
int X::si = 77; //Initialize static data member
int main() {
X xobj;
xobj.set_i(11);
xobj.print_i();
//static data members and functions belong to the class and
//can be accessed without using an object of class X
X::print_si();
X::set_si(22);
X::print_si();
}
Manipal University Jaipur B2114 Page No.: 104
Object Oriented Programming – C++ Unit 4

Output:
Value of i = 11
Again, value of i = 11
Value of si = 77
Value of si = 22
As the member function A::print_si() is declared as static and hence, it does
not have this pointer. So the member access operation this->si is not
allowed by the compiler.
You can call a static member function using this pointer of a non-static
member function. In the following example, the non-static member function
printall() calls the static member function f() using this pointer:
#include <iostream.h>
class A {
static void xyz() {
cout << "The value of p is:: " << p<< endl;
}
static int p;
int q;
public:
A(int q1): q(q1) { }
void print();
};
void A::print() {
cout << "the value of q is:: " << this->q << endl;
this->xyz();
}
int A::p = 3;
int main() {
A obj_A(0);
obj_A.print();
}

Manipal University Jaipur B2114 Page No.: 105


Object Oriented Programming – C++ Unit 4

Output:
the value of q is: 0
the value of p is: 3
It is not allowed in C++ to declare a static member function with the
following keywords: virtual, const, volatile, or const volatile. Only the names
of the following can be accessed by a static member function: static
members, enumerators, and nested types of the class in which it is
declared. A static member function cannot be declared with the keywords
virtual, const, volatile, or const volatile. A static member function can access
only the names of static members, enumerators, and nested types of the
class in which it is declared. Suppose a static member function A() is a
member of class C. The static member function A() cannot access the non-
static members C or the non-static members of a base class of C. The
figure 4.2 summarizes member functions and data of a class

Object 1 Object 1 Object 1


Data1 Data1 Data1
Data2 Data2 Data2
Data3 Data3 Data3

Member Function1
Member Function2
Static Function
Static Data

Figure 4.2: Data and Functions in a class

Self Assessment Questions


14. _______ is the data member that is common for all the objects of the
class and is accessible for the class.
Manipal University Jaipur B2114 Page No.: 106
Object Oriented Programming – C++ Unit 4

15. ___________ functions cannot be invoked without the objects of the


class.
16. In C++ it is possible to declare static and non-static member functions
with the same names. (True/False)

4.12 Summary
 Classes provide users a way to create user defined data type.
 Object is an instance of a class and is used in the program to store data.
 Pointers can point to simple data types, arrays and to objects as well.
We use pointers in the situations where we do not know that how many
objects we have to create in a program.
 An abstract class is the class which acts as a base class and can be
inherited by other classes and is not used to create objects.
 Every time when the program creates a class instance, a special pointer
is created in C++ called this and it contains the address of the current
object instance.
 Friend functions allow us to access some non-member functions or
other classes in C++.
 With the possibility of selecting a non-member friend function, there are
two more options for its friends. These options are that either the class
can declare as a friend a member function of another class or another
class also can be declared as a friend.
 Static data member of the class is one data member that is common for
all the objects of the class and are accessible for the class.

4.13 Terminal Questions


1. What is this pointer?
2. Brief about class and objects.
3. Explain the scope of friend functions.
4. Describe friend functions and friend classes.
5. Discuss static variable and function.

Manipal University Jaipur B2114 Page No.: 107


Object Oriented Programming – C++ Unit 4

4.14 Answers
Self Assessment Questions
1. Class
2. Abstract
3. Object
4. True
5. Public, private and protected
6. private and public
7. Array of objects
8. Pointers
9. True
10. this
11. False
12. Friend
13. Beginning
14. Static Functions
15. Member functions
16. False

Terminal Questions
1. Every time when the program creates a class instance a special pointer
is created in C++ called this that contains the address of the current
object instance. For more details refer section 4.9.
2. Classes provide users a way to create user defined data types. Classes
provide a convenient way to group related data and the methods that
operate on data together. For more details refer section 4.2.
3. The name of a function first introduced in a friend declaration is in the
scope of the first nonclass scope that contains the enclosing class. For
more details refer section 4.10.3.
4. With the possibility of selecting a non-member friend function, there are
two more options for its friends. These options are: either the class can
declare a member function of another class as a friend or another class
can also be declared as a friend. For more details refer section 4.10.2.

Manipal University Jaipur B2114 Page No.: 108


Object Oriented Programming – C++ Unit 4

5. Static data member of the class is one data member that is common for
all the objects of the class and is accessible for the class. Static
functions are special type of functions which can be invoked even
without an object of the class. For more details refer section 4.11.

References:
 Object Oriented Programming In C++, 4/E by Robert Lafore. Pearson
Education India.
 Object Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
 Object-Oriented Programming Using C++, By Joyce Farrell. Cengage
Learning.

Manipal University Jaipur B2114 Page No.: 109


Object Oriented Programming – C++ Unit 5

Unit 5 Constructors and Destructors


Structure:
5.1 Introduction
Objectives
5.2 Constructors
5.3 Multiple Constructors
5.4 Parameterized constructors using Dynamic Objects
5.5 Copy Constructors
5.6 Destructors
5.7 Name Space
5.8 Summary
5.9 Terminal Questions
5.10 Answers

5.1 Introduction
In the previous unit you studied classes, objects and procedure to define
them. You also learnt the abstract classes and friend functions and their use
in C++. In this unit you study constructors and destructors. There are
several special C++ member functions that determine how the objects of a
class are created, initialized, copied, and destroyed. Constructors and
destructors are the most important of these. They have many of the
characteristics of normal member functions – you declare and define them
within the class, or declare them within the class and define them outside -
but they have some unique features. In this unit we will discuss the role of
constructor and overloading constructor. We will also focus on destructor
with its role to de allocate the objects which were created by the constructor.
Objectives:
After studying this unit you should be able to:
 explain the use constructors.
 discuss overloading constructor.
 describe the role of destructors.

5.2 Constructors
Constructors are member functions of a class and have the same name as
the class name. Constructors are called automatically whenever an object of

Manipal University Jaipur B2114 Page No.: 110


Object Oriented Programming – C++ Unit 5

the class is created. This feature makes it very useful to initialize the class
data members whenever a new object is created. It can also perform any
other function that needs to be performed for all the objects of the class
without explicitly specifying it.
A constructor knows only to build an object of its own class. Constructors
aren't automatically inherited between base and derived classes. If the
constructors are not provided in the derived class then C++ will provide a
default constructor but it may not perform the functions as you like. And if
you do not provide a constructor, the C++ will create a default constructor
with no parameters in it. The default constructor will not be created if you
provide a constructor in the derived class.
Characteristics of a constructor
 These are the functions having the name similar to its class. Their role is
to initialize the class members when an object of the class is created.
 They should be declared in public section of class for availability to other
functions.
 No return type, not even void is specified for the constructors.
 They cannot be inherited but the derived class can call the constructor
of its baser class.
 They can call member functions of its class.
 They cannot be virtual.
 They can have default values and can be overloaded.
 It is possible to create multiple constructors of the same class but they
should have different parameters so that they can be easily
distinguished.
The syntax to define a constructor is as follows:
class classname
{
public:
classname(); //constructor
classname(argument list); //another constructor

};

Manipal University Jaipur B2114 Page No.: 111


Object Oriented Programming – C++ Unit 5

5.3 Multiple Constructors


As you have already studied, you can declare multiple constructors of a
class. And then you can use any of the constructors while creating an object
of that class. Customization of the created object is facilitated by multiple
constructors. As discussed above multiple constructors are differentiated by
their argument list. When you declare multiple constructor of a class it is
called constructor overloading. As you already know, constructors don’t
have return type. The example below demonstrates how to define multiple
constructors in a class and how to call a desired one while instantiating the
class.
#include<iostream.h>
class point
{
public:
int x, y;
public:
point()
{
x=0;
y=0;
cout<<’’this is the constructor with no arguments\n”;
};
point(int x1)
{
x=x1;
y=0;
cout<<”this is the constructor with one argument\n”;
};
point(int x1, int y1)
{
x=x1;
y=y1;
cout<<”this is the constructor with two arguments\n”;
};
void main()
Manipal University Jaipur B2114 Page No.: 112
Object Oriented Programming – C++ Unit 5

{
point p1;
cout<<”point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
point p2(5);
cout<<”point p2 (“ << p2.x << “,” << p2.y << “)” << endl;
point p3(10,10);
cout<<”point p3 (“ << p3.x << “,” << p3.y << “)” << endl;
}
In the above program you can see the point class having two data members
x and y and three constructors. The first constructor is without any
arguments and initializes both the data members to zero. The second
constructor takes a parameter of integer type. In that one data member is
initialized with the parameter x1 passed to the constructor and another is
initialized with zero. The last constructor takes two arguments. The data
members are initialized with the parameters x1 and y1 passed to the
constructor. When a constructor is called, a message is printed on the user
console.
Constructor pitfalls are:
As mentioned above, defining any constructor explicitly requires explicitly
defining a default constructor if needed.
Defining constructors that take only one parameter allows the constructor to
be implicitly used by the compiler to convert from the parameter type to the
class type of the constructor. This is OK in many situations, such as
converting a string literal to a string class instance. However in many other
places it does not make sense. For example, a vector (single dimensional
array) class that takes an integer type parameter to specify an initial number
of elements in the vector object. In this case such an integer type can be
implicitly converted to a vector type - which is probably not too useful and
will probably hide errors (bugs!). In such cases you have to mark the
constructor explicit:
class Vector
{
public:
explicit Vector( unsigned int size );

Manipal University Jaipur B2114 Page No.: 113


Object Oriented Programming – C++ Unit 5

// ...
};

// Explicitly call the Vector::Vector(unsigned int) constructor


Vector v(10);
// Do stuff with v, fill it up with values etc.
v = 10; // ERROR as Vector::Vector(unsigned int) is explicit.
The above example assumes Vector has a meaningful assignment operator
(operator=), which implies it also has a meaningful copy constructor as if
one makes sense so does the other. I have not shown either in the parts of
the Vector class shown to keep things simple. Without the 'explicit'
qualification on the Vector::Vector (unsigned int) constructor declaration the
line with the comment starting ERROR next to it would be legal. In this case
10 would be converted to a new (temporary) Vector by implicitly calling the
Vector::Vector (unsigned int) constructor. Although this sounds as if it is
neat, it would cause more errors and bugs. Assuming vector stored integer
values, it is more likely that v = 10 should have been something like v[index]
= 10 and the author forgot the subscript. By adding the 'explicit' qualification
to a constructor it prevents the constructor calling it implicitly when we are
not looking, i.e. an explicit constructor can only be called when we explicitly
use it, as in the Vector v(10);
Self Assessment Questions
1. Special member function which has the name as class called
_______________.
2. The ____________ constructor will not be created if you provide a
constructor in the derived class.
3. When you declare multiple constructor of a class it is called _________.

5.4 Parameterized Constructors using Dynamic Objects


You can call a parameterized constructor while creating an object
dynamically. It is as simple as calling a desired constructor while creating an
object statically. The desired list of parameters is enclosed in parentheses
following the point declaration. For example, the statement shown below
calls the constructor of the class point and prints the values of data
members in the user console.
point *p1 = new point();

Manipal University Jaipur B2114 Page No.: 114


Object Oriented Programming – C++ Unit 5

The following statement calls a single argument constructor and initializes x


to 5 and y to 0.
console.cout<<”point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
point *p2= new point(5);
The program to demonstrate this concept is shown below:
#include<iostream.h>
class point
{
public:
int x, y;
public:
point()
{
x=0;
y=0;
cout<<’’this is the constructor with no arguments\n”;
};
point( int x1)
{
x=x1;
y=0;
cout<<”this is the constructor with one argument\n”;
};
point(int x1, int y1)
{
x=x1;
y=y1;
cout<<”this is the constructor with two arguments\n”;
};
void main()

Manipal University Jaipur B2114 Page No.: 115


Object Oriented Programming – C++ Unit 5

{
point *p1 = new point(); // it calls no argument constructor f the point class
and prints the values of data members in user
console.cout<<”point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
point *p2= new point(5); // it calls a single argument constructor and
initializes x to 5 and y to 0.
cout<<”point p2 (“ << p2.x << “,” << p2.y << “)” << endl;
point *p3= new point(10,10); //it calls the two argument constructor which
initializes both x and y to 10.
cout<<”point p3 (“ << p3.x << “,” << p3.y << “)” << endl;
}

5.5 Copy Constructors


In some situations you may have to create a copy of an already existing
object. You can do this by creating a constructor in the definition of your
class. And you have to pass the object to be copied as an argument in that
constructor. This type of constructor is known as copy constructor. Shown
below is the definition of such a copy constructor:
point(point &p)
{
x=p.x;
y=p.y;
}
In the example shown above the single argument is passed in the
constructor that is the reference to the object of point class. The data
members of the passed object are explicitly copied in the respective data
members of the new object.
The example below demonstrates how to define and use a copy constructor.
#include<iostream.h>
class point
{
public:

Manipal University Jaipur B2114 Page No.: 116


Object Oriented Programming – C++ Unit 5

int x,y;
public:
point( int x1, int y1)
{
x=x1;
y=y1;
cout<<”constructor called\n”;
};
point (point &p)
{
x=p.x;
y=p.y;
cout<<” copy constructor is called”;
}
};
void main()
{
point p1(5,5);
cout<< “point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
point p2(p1)
cout << “point p2 (“ << p2.x << “,” << p2.y << “)” << endl;
//testing for two objects
cout << “” setting data members of two objects\n”;
p1.x =10; p1.y=10;
p2.x=20, p2.y=20;
cout<< “point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
cout << “point p2 (“ << p2.x << “,” << p2.y << “)” << endl;
}
As you can see in the above example, two constructors are declared in the
point class, i.e. the constructor with two arguments and a copy constructor.
We create an object p1 that sets both data members of the point object to
the value 5. The program prints these values on the user console for
verification.
Manipal University Jaipur B2114 Page No.: 117
Object Oriented Programming – C++ Unit 5

point p1(5,5);
cout<< “point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
The statement point p2(p1) makes the use of copy constructor to construct
object p2 of type point.
You will also want to verify that the two independent objects are created by
the program. For this, as you can see in the program, individual data
members of the two objects have to be set to different values and dumped
the two objects on console. The following code member does this.
cout << “setting data members of two objects \n”;
p1.x =10; p1.y = 10;
p2.x =20, p2.y =20;
cout<< “point p1 (“ << p1.x << “,” << p1.y << “)” << endl;
cout << “point p2 (“ << p2.x << “,” << p2.y << “)” << endl;

Self Assessment Questions


4. In some situations it is required to create a copy of an already existing
object this can be done by creating a __________.
5. In copy constructor we have to pass the object to be copied as a
__________ in that constructor.

5.6 Destructors
Destructors are the member functions that are called automatically when an
object of a class is destroyed or goes out of scope. It also performs cleanup
work necessary before an object is destroyed. Likewise constructor the
name of the destructor is also similar to its class and is prefixed by a ~
(tilde). For example:
class A
{
public:
// Constructor for class A
A();
// Destructor for class A
~A();
};

Manipal University Jaipur B2114 Page No.: 118


Object Oriented Programming – C++ Unit 5

Characteristics of a destructor:
 Destructors are called automatically when an object of a class is
destroyed.
 They are declared in public section of a class.
 They don’t have any return type (not even void) and do not take any
argument as well.
 They cannot be declared const, volatile, const volatile or static. A
destructor can be declared virtual or pure virtual.
 If no user-defined destructor exists for a class and one is needed, the
compiler implicitly declares a destructor. This implicitly declared
destructor is an inline public member of its class.
 They cannot be inherited. But the derived class can invoke the
destructors of the base class.
 They cannot be overloaded.
 They can call other member functions of its class.
The compiler will implicitly define an implicitly declared destructor when the
compiler uses the destructor to destroy an object of the destructor's class
type. Suppose a class A has an implicitly declared destructor. The following
is equivalent to the function the compiler would implicitly define for X:
X::~X() { }
The following program implements the constructor and destructors for a
class
// constdest.cpp
# include<iostream.h>
class example
{ private:
int a;;
public:
example() {a=0; cout<<”Constructor invoked”<<endl;}
~example() {cout<<”Destructor invoked”;}
void show()
{ cout<<”Data is=”<<a<<endl;}

Manipal University Jaipur B2114 Page No.: 119


Object Oriented Programming – C++ Unit 5

};
void main()
{ example e1;
e1.show();
}
If you run the above program you will get the output as follows:
Constructor invoked
Data=0
Destructor invoked
When an object e1 of example class is created, the constructor is invoked
automatically and data value is initialized to zero. When the program is
terminated the object is destroyed and the destructor is automatically
invoked. When the program ends the object is destroyed which invokes the
destructor. Please note that both the constructor and destructor are
declared as public and they have no return value. The following program
implements the overloaded constructors for the distance class.
//overloadconst.cpp
#include<iostream.h>
class distance
{ private:
int feet;
int inches;
public:
distance()
{ feet=0;
inches=0;}
distance(int ft, int i)
{ feet=ft;
inches=i;}
void print()
{ cout<<feet<<”feet”<<inches<<”inches;}
};
void main()
Manipal University Jaipur B2114 Page No.: 120
Object Oriented Programming – C++ Unit 5

{ distance d1, d2(10,2);


d1.print();
d2.print()
}
Of the two constructors are used in the above program, one is without
parameters and the other is with parameters. These are automatically
invoked. The first constructor is invoked when the object d1 is created and
the second constructor i.e. distance (int ft, int i) is invoked when d2 is
created as two arguments are passed. Please note that to invoke a
constructor with arguments, argument values have to be passed along with
the object name during declaration.
The compiler first implicitly defines the implicitly declared destructors of the
base classes and non-static data members of class A before defining the
implicitly declared destructor of A.
A destructor of class A is trivial if all the following are true:
 It is implicitly defined
 All the direct base classes of A have trivial destructors
 The classes of all the nonstatic data members of A have trivial
destructors
The destructor is non-trivial if, any one of the above conditions is false. A
union member cannot be of a class type that has a nontrivial destructor.
Class members that are class types can have their own destructors. You
already know that the destructors cannot be inherited, even though both
base and derived classes can contain constructors. Suppose a base class X
or its member contains destructor and the derived class of X does not
declare a destructor, then the default destructor will be created. The
destructor of the base class and the members of the derived class are
called by the default destructor. The destructors of base classes and
members are called in the reverse order of the completion of their
constructor:
 The destructor for a class object is called before destructors for
members and bases are called.
 Destructors for nonstatic members are called before destructors for base
classes are called.

Manipal University Jaipur B2114 Page No.: 121


Object Oriented Programming – C++ Unit 5

 Destructors for non-virtual base classes are called before destructors for
virtual base classes are called.
When an exception is thrown for a class object with a destructor, the
destructor for the temporary object thrown is not called until control passes
out of the catch block. When an automatic object (an object which is
declared auto or register or not declared as static or extern) or a temporary
object passes out of scope, then the destructors are implicitly called. They
are implicitly called at program termination for constructed external and
static objects. Destructors are invoked when you use the delete operator for
objects created with the new operator. For example
#include <string>
class A
{
private:
char * string;
int n;
public:
// Constructor
A(const char*, int);
// Destructor
~A() { delete[] string; }
};
// Define class A constructor
A::A(const char* p, int x)
{
string = strcpy(new char[strlen(p) + 1 ], p);
nr = x;
}
int main ()
{
// Create and initialize
// object of class A
A aobj = A("somestring", 10);

Manipal University Jaipur B2114 Page No.: 122


Object Oriented Programming – C++ Unit 5

// ...
// Destructor ~A is called before
// control returns from main()
}
The destructors can be used explicitly to destroy the objects, even though
this method is not recommended. However to destroy an object created with
the new operator, you can explicitly call the object's destructor. This concept
is explained in the example below:
#include <iostream.h>
class X
{
public:
X() { cout << "X::X()" << endl; }
~X() { cout << "X::~X()" << endl; }
};
int main () {
char* ptr = new char[sizeof(X)];
X* xptr = new (ptr) X;
xptr->X::~X();
delete [] ptr;
}
The statement X* aptr =new(ptr) X creates a new object of type X
dynamically. The object is created not in the free store but in the memory
allocated by ptr. The storage allocated by ptr will be deallocated by the
statement delete [] ptr. But the run time will still believe that the object
pointed to by ap still exists until you explicitly call the destructor of X (with
the statement aptr->X::~X()).
Self Assessment Questions
6. Destructor takes arguments and returns value. State (True/False)
7. The destructor for a ________________ is called before destructors for
members and bases are called.
8. Destructors are declared in ______ section of a class.
9. Destructors can be overloaded. (True/False)
Manipal University Jaipur B2114 Page No.: 123
Object Oriented Programming – C++ Unit 5

10. Destructors are implicitly called at program termination for constructed


external and static objects. (True/False)

5.7 Name Space


If you are using different modules/or libraries there are always chances of
name clash. The reason is that these modules or libraries use the same
identifier for many things. This issue is resolved by using namespaces in
C++. A namespace is a certain scope for identifiers. Unlike a class, it is
open for extensions that might occur at any source. Thus, it is possible for
you to use a namespace to define components that are distributed over
several physical modules. The C++ standard library is an example of such a
component. In namespace known as std, all the identifiers of C++ standard
libraries are defined.
Defining a Namespace
To define a namespace you should use ‘namespace’ keyword followed by
the name of the namespace. The example to explain this concept is shown
below:
namespace namespace_name {
// code declarations
}
To call the namespace-enabled version of either function or variable,
prepend the namespace name as follows:
name::code; // code could be variable or function.
For example:
namespace xyz //defining identifiers in namespace xyz
{
class file;
void myglobalfunc();
….
}
xyz::file obj;// using a namespace identifier
……
xyz::myglobalfunc();

B2114 Page No.: 124


Object Oriented Programming – C++ Unit 5

Let us see how namespace scope the entities including variable and
functions:
#include <iostream>
using namespace std;
// first name space
namespace f1_space{
void f1()
{
cout << "this is the first name space" << endl;
}
}
// second name space
namespace f2_space
{
void f2(){
cout << "this is the second namespace" << endl;
}
}
int main ()
{
// Calls function from first name space.
f1_space::f1();

// Calls function from second name space.


f2_space::f2();
return 0;
}
If the above code is executed, it will produce the result shown below:
this is the first namespace
this is the second namespace

Manipal University Jaipur B2114 Page No.: 125


Object Oriented Programming – C++ Unit 5

The using directive


You can also avoid prepending of namespaces with the ‘using’ namespace
directive. This directive tells the compiler that the subsequent code is
making use of names in the specified namespace. The namespace is thus
implied for the following code:
#include <iostream>
using namespace std;
// first name space
namespace f1_sapce
{
void f1()
{
cout << "this is the first space" << endl;
}
}
// second name space
namespace f2_space{
void f2(){
cout << "this is the second space" << endl;
}
}
using namespace f1_space;
int main ()
{
// This calls function from first name space.
f1();
return 0;
}
If we compile and run above code, this would produce the following result:
this is the first space

Manipal University Jaipur B2114 Page No.: 126


Object Oriented Programming – C++ Unit 5

You can also use the directive to refer to a particular item within a
namespace. For example, if the only part of the std namespace that you
intend to use is cout, you can refer to it as follows: using std::cout;
Self Assessment Questions
11. A _______ is a certain scope for identifiers. Unlike a class, it is open
for extensions that might occur at any source.
12. We can also avoid prepending of namespaces with the using
namespace directive. (True/False).

5.8 Summary
 Constructors are member functions of a class, which have same name
as the class name and are called automatically whenever an object of
the class is created.
 We can declare multiple constructors of a class and it is called
constructor overloading.
 Defining constructors that take only one parameter allows that
constructor to be implicitly used by the compiler to convert from the
parameter type to the class type of the constructor.
 We can call a parameterized constructor while creating an object
dynamically. The required list of parameters is enclosed in the
parentheses while we call the constructor with no arguments of the point
class.
 In some situations, you may require to create a copy of an already
existing object this can be done by using copy constructors.
 Destructors are the member functions that are called automatically when
an object of a class is destroyed or goes out of scope.
 The destructors of base classes and members are called in the reverse
order of the completion of their constructor.
 A namespace is a certain scope for identifiers. Unlike a class it is open
for extensions that might occur at any source.
 We can also avoid prepending of namespaces with the ‘using’
namespace directive.

Manipal University Jaipur B2114 Page No.: 127


Object Oriented Programming – C++ Unit 5

5.9 Terminal Questions


1. Implement a class stack, which simulates the operations of the stack
allowing LIFO operations. Also, implement push and pop operations for
the stack.
2. Write the output of the following program
# include<iostream.h>
class A
{ int a;
static int s;
public:
A()
{a=0; cout<<”Default Constructor Invoked”<<endl;}
A(int i)
{a=i; cout<<”Overloaded constructor Invoked”<<endl;s=s+a;}
void display()
{cout<<a<<endl<<s<<endl;}
}
int A::s=0;
void main()
{
A obj1(12);
obj1.display();
A obj2(10);
obj2.display();
}
3. Write a short note on constructors.
4. Describe multiple constructors with the help of an example.
5. Explain destructor in detail with the help of an example.
6. Describe the concept of namespace in detail.

Manipal University Jaipur B2114 Page No.: 128


Object Oriented Programming – C++ Unit 5

5.10 Answers
Self Assessment Questions
1. Constructor
2. Default
3. Constructor overloading
4. Copy constructor
5. Argument
6. False
7. class object
8. Private
9. False
10. True
11. Namespace
12. True
Terminal Questions
1. //stack.cpp
# include <iostream.h>
# define size 100
class stack
{ int stck[size];
int top;
public:
stack() {top=0;
cout <<"stack initialised"<<endl;}
~stack() {cout <<"stack destroyed"<<endl;}
void push(int i);
int pop();
};
void stack::push(int i)
{
if (top==size)
{ cout <<"stack is full";
return;

Manipal University Jaipur B2114 Page No.: 129


Object Oriented Programming – C++ Unit 5

}
stck[top]=i;
top++;
}
int stack ::pop()
{ if (top==0) {
cout << "stack underflow" ;
return 0;
}
top--;
return stck[top];
}
void main()
{ stack a,b;
a.push(1);
b.push(2);
a.push(3);
b.push(4);
cout<<a.pop() << " ";
cout<<a.pop()<<" ";
cout<<b.pop()<< " ";
cout<<b.pop()<<endl;
}
2. Overloaded Constructor Invoked
12
12
Overloaded constructor Invoked
10
22
3. Constructors are member functions of a class which have same name
as the class name. Constructors are called automatically whenever an
object of the class is created. This feature makes it very useful to

Manipal University Jaipur B2114 Page No.: 130


Object Oriented Programming – C++ Unit 5

initialize the class data members whenever a new object is created. It


also can perform any other function that needs to be performed for all
the objects of the class without explicitly specifying it. For more details
refer section 5.2.
4. Multiple constructors of a class. And then we can use any of the
constructors while creating an object of that class. Customization of the
created object is facilitated by multiple constructors. For more details
refer section 5.3.
5. Destructors are usually used to deallocate memory and do other
cleanup for a class object and its class members when the object is
destroyed. For more details refer section 5.6
6. If you are using different modules/or libraries there are always chances
of name clash. The reason being that these modules or libraries use the
same identifier for many things. This issue is resolved by using
namespaces in C++. A namespace is a certain scope for identifiers.
Unlike a class it is open for extensions that might occur at any source.
Thus it possible for you to use a namespace to define components that
are distributed over several physical modules. For more details refer
section 5.7
References:
 Object Oriented Programming with C++, by Poornachandra Sarang.
Prentice Hall India Pvt., Limited.
 Object-Oriented Programming with ANSI and Turbo C++- Seventh
Edition, by Kamthane. Pearson Education India.

Manipal University Jaipur B2114 Page No.: 131


Object Oriented Programming – C++ Unit 6

Unit 6 Operator Overloading


Structure:
6.1 Introduction
Objectives
6.2 Operator Overloading in C++
6.3 Overloading Unary Operators
6.4 Overloading binary operators
6.5 Type Conversions
6.6 Summary
6.7 Terminal Questions
6.8 Answers

6.1 Introduction
In the previous unit you have studied the constructors, their different types
and their use in C++. You have also studied the destructors and the
namespaces in C++. In this unit you study the concept of operator
overloading. You will also learn how to overload different operators in C++.
You will also know the method of performing type conversions in C++.
Operator overloading is the ability to tell the compiler how to perform a
certain operation when its corresponding operator is used on one or more
variables. Operator overloading, less commonly known as operator ad-hoc
polymorphism, is a specific case of polymorphism, where different operators
have different implementations depending on their arguments. Operator
overloading is generally defined by the language, the programmer, or both.
Operator overloading is claimed to be useful because it allows the
developer to program using notation "closer to the target domain” and
allows user-defined types a similar level of syntactic support as types built
into the language. In this unit we are going to discuss unary and binary
operator overloading with examples.
Objectives:
After studying this unit, you should be able to:
 explain operator overloading
 describe unary operator overloading
 describe binary operator overloading
 discuss type conversion
Manipal University Jaipur B2114 Page No.: 132
Object Oriented Programming – C++ Unit 6

6.2 Operator Overloading in C++


With the use of operator overloading feature of C++, programmers can
specify the way the different arithmetic, relational and other operators work
with user defined data types or classes. It allows the programmer to modify
the functionality of the existing operators so that they can be used with user
defined data types such as classes, in addition to built-in data types.
Consider the following statements:
int x,y,z;
z=x+y;
In this example you can observe that the two integer variables are added
and the result is stored in the third variable z. But it is not possible in C++ to
add the two objects of the class with the same ‘+’ operator. For this purpose
you have to use operator overloading concept. For example if obj1, obj2 and
obj3 are the three objects of a class the following statements will generate a
compile time error if the ‘+’ operator is not overloaded.
obj3= obj1+obj2;
So if you want to perform this operation you have to overload the ‘+’
operator. In C++ almost all the unary, binary and special operators can be
overloaded.
In the unit 5, we had written an add function for the class distance. We used
a call d3.add (d1,d2) to add two distance objects. It would be easy for us if
use the statement d3=d1+d2. But it is only possible if we overload the ‘+’
operator to perform this function.
Shown below is the list of functions that can be overloaded in C.
+ - * / % ^ & | ~
! = < > += -= *= /= %=
^= &= |= << >> <<= >>= == !=
<= >= && || ++ -- , ->* ->
() [] new delete new[ ] delete[]
Some operators that cannot be overloaded are:
 dot operator (.)
 dereference pointer to class members (.*)
 scope resolution operator (::)
Manipal University Jaipur B2114 Page No.: 133
Object Oriented Programming – C++ Unit 6

 sizeof operator
 preprocessor symbol (#)
A special function called and operator function is used to overload an
operator. It defines the operations that the overloaded operator will perform
on the objects of the class for which it is redefined. An operator function is
defined either as a public function or as a friend function. You must follow
the following steps to overload an operator:
 Create the class for which an operator is to be overloaded.
 Declare the function either as a public function or a friend function.
 Define the operator either inside the class definition (member function)
or outside the class (friend function).
The syntax to define the member operator function inside the class is
return_type operator op (parameter list)
{
//function body
}
Example: int operator + (int a, int b)
If you are defining member function outside the class you have to
declare it first inside the class. The following is the syntax to declare the
member function inside the class:
return_type operator op (parameter list);
The following is the syntax to define member operator function outside
the class:
return_type class_name:: operator op (parameter_list)
{
//function body
}
Example: int test :: operator + ( int a, int b)
Where return_type(int) = data type of the value returned by the function
operator is C++ keyword

Manipal University Jaipur B2114 Page No.: 134


Object Oriented Programming – C++ Unit 6

op(+) is the name of the operator to be overloaded as well the name of


the operator overloaded function.
parameter_list ( int a, int b) is the list of arguments passes to the
operator function.
Here class_name is the name of the class to which the object belong
You should keep in mind the following rules while overloading operators.
 An operator function can be either a nonstatic member function, or a
nonmember function with at least one parameter that has class,
reference to class, enumeration, or reference to enumeration type.
 The precedence and associativity of the operators cannot be changed.
However you can use parentheses to change the order of evaluation.
 The number of operators (unary, binary or ternary) in an operator cannot
be changed.
 An overloaded operator (except for the function call operator) cannot
have default arguments or an ellipsis it is a notation that is used to
denote ranges and denoted by series of dots i.e. (.. or …) in the
argument list.
 The operators =, [], () and ->can be overloaded only as member
functions and not as friend functions.
 Except the assignment operator ‘=’ all the overloaded operators can be
inherited by the derived class.
The general rules discussed in this section are not followed by the
following operators – new, delete, new[] and delete[].
Benefits of operator overloading are:
It makes programs easier to read and debug.
It has the ability to provide the operators with a special meaning for a data
type.
Drawbacks of operator overloading:
Sometimes you may misunderstand the meaning of overloaded operators (if
the natural semantics is not used by the programmer). The extreme case,
where the plus-operator is re-defined to mean minus and the minus operator
is re-defined to mean plus, probably will not occur very often, but more
subtle cases are conceivable. Designing a class library is like designing a

Manipal University Jaipur B2114 Page No.: 135


Object Oriented Programming – C++ Unit 6

language if you use operator overloading, use it in a uniform manner; do not


use it if it can easily give rise to misunderstanding.
Self Assessment Questions
1. The functionality of the operators with any data types can be changed
by operator overloading? (True/False).
2. Not all the operators can be overloaded in C++. (True/False).
3. A special function called and _______ function is used to overload an
operator.

6.3 Overloading Unary Operators


As you know already that the unary operators are the ones that operate on
a single operator. Some of the unary operators are - the increment (++) and
decrement (--) operators, the unary minus (-) operator and the logical not (!)
operator.
In case of overloading of unary operators, the calling operand can be either
left or right side of the operator as in case of increment and decrement
operators. While defining the operator functionality for the class the keyword
operator is used. Let us overload the increment operator for a class.
//unary.cpp
# include <iostream.h>
class counter
{ unsigned int c;
public:
counter()
{c=0;}
int getcount()
{return c;}
void operator ++()
{ c++;}
};
void main()
{ counter c1;

Manipal University Jaipur B2114 Page No.: 136


Object Oriented Programming – C++ Unit 6

c1++;
++c1;
cout<<c1.getcount();
}

In the above example, the operator ++ is an overloaded function. It does not


return any value and no arguments are passed in this function. All unary
operators do not take arguments as they operate on only one operand and
that operand itself invokes the operator. Therefore the operand is sent by
default. However the above implementation cannot be used in statements
such as c2=c1++; where c1 and c2 are counter variables. The reason being
that a void value is returned by the ++ operator and is assigned to the
counter variable as shown in the above example. To resolve this problem
you can define the operator ++ in a way that it returns the value of the
counter variables, as shown below.
//increment.cpp
# include <iostream.h>
class counter
{ unsigned int count;
public:
counter()
{c=0;}
counter(int num)
{c=num;}
int getcount()
{return c;}
counter operator ++()
{ c++;
return counter(c);}
};
void main()
{ counter c1,c2;
c1++;
Manipal University Jaipur B2114 Page No.: 137
Object Oriented Programming – C++ Unit 6

c2=++c1;
cout<<c1.getcount()<<endl;
cout<<c2.getcount();
}

In the example shown above you can see that a counter variable is returned
without creating a variable. In the above implementation, we are returning
the counter variable without creating a variable. It is done by using a
constructor having one argument. When the statement return counter(c) is
executed, the value of the argument c of the invoking object is passed to the
constructor and a nameless object is created which is initialized to the value
stored in the count and returned to the calling program. One argument
constructor is used in this case. We are using one argument constructor in
this case.
The limitation of unary operator overloading is that the increment and
decrement operators cannot be totally duplicated. The reason is that the
C++ compiler is not able to differentiate between pre and post increment/
decrement operators.
Self Assessment Questions
4. Unary operators are implemented with _____ arguments.
5. Unary operators should have return value as ________.
6. Unary operators overloaded for the class can differentiate between
post and pre operators. (True/False)

6.4 Overloading Binary Operators


The operators that require two operands for its operation are known as
binary operators. The examples of some of the binary operators are
arithmetic operators like +, *, /, etc. relational operators like <,>. In binary
operator overloading one operand is the object of the class invoking the
function is passed implicitly to the member operator function. And the other
operand is passed as an argument, which can be passed either by value or
by reference. This concept is explained thorough the example shown below
illustrating the overloading of + operator:
#include<iostream.h>
class complex

Manipal University Jaipur B2114 Page No.: 138


Object Oriented Programming – C++ Unit 6

{
float x; //real part
float y; //imaginary part
public:
complex(){ } //constructor1
complex( float real, float imag) //constructor2
{
x=real;
y=imag;
}
complex operator+(complex c);
void display(void);
};
complex complex:: operator+(complex c)
{
complex temp; //temporary
temp.x = x + c.x;
temp.y = y + c.y;
return(temp);
}
void complex :: display(void)
{
cout << x << “+ j” << y << “\n”;
}
int main()
{
complex c1, c2, c3; //invokes constructor1
c1= complex(2.5, 3.5); //invokes cosntructor2
c2=complex(1.6, 2.7);
c3=c1+c2;
cout<< “c1 = ” ;
Manipal University Jaipur B2114 Page No.: 139
Object Oriented Programming – C++ Unit 6

c1.display();
cout<<”c2 = ”;
c2.display();
cout<<”c3 = ”;
c3.display();
return 0;
}
Here is the output of the above program:
c1= 2.5 + j3.5
c2 = 1.6 + j2.7
c3 = 4.1 + j6.2
Let us look at the following function:
complex complex :: operator+(complex c)
{
complex temp; //temporary
temp.x = x + c.x;
temp.y = y + c.y;
return(temp);
}

The features of the above function are as follows:


 It receives only one complex type argument explicitly.
 It returns a complex type value.
 It is a member function of complex.
You can observe that the function adds two complex numbers and returns a
complex number but it receives only one value as an argument. Now the
question is from where does the second value come? Let us now see the
following statement which invokes the operator+() function :
c3=c1+c2;
As you know that a member function can be invoked only by an object of
that class. So, here the object c1 invokes the function and c2 is passed as
an argument to the function. The above statement is equivalent to:

Manipal University Jaipur B2114 Page No.: 140


Object Oriented Programming – C++ Unit 6

c3= c1.operator+ (c2) //usual function call syntax


Hence in the operator+ () function, the data members of c1 are accessed
directly and the data members of c2 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 to store the result of addition of c1 and
c2. The function returns the complex temp to be assigned to c3. The figure
6.1 shows implementation of the above program.

Figure 6.1: Implementation of overloaded + operator

For overloading a binary operator, instead of member functions friend


functions can also be used. The difference is that a friend function requires
two arguments to be explicitly passed to it whereas a member function
requires only one argument.
We can modify the complex number function discussed above using a friend
function as shown below:
1. Replace the member function declaration by the friend function
declaration like this:
friend complex operator+ (complex, complex);
Manipal University Jaipur B2114 Page No.: 141
Object Oriented Programming – C++ Unit 6

2. Redefine the operator function as follows:


complex operator+ (complex a, complex b)
{
retrun complex((a.x+b.x), (a.y+b.y));
}
In this case the statement
c3 = c1 + c2; is equivalent to
c3 = operator+(c1, c2);
In most of the cases same result is generated either by using member
functions or by using friend functions. Then the question arises that why
an alternative is made available? The reason is that in some situations
we prefer using friend function to member function. For example let us
consider a situation where it is required to use two different types of
operands for binary operator, one is an object and other one is a built in
data type as shown below:
A = B + 2; (or A = B * 2);
Where A and B are the objects of same class. This is true if you use a
member function but the following statement will not work:
A = 2 + B; (or A = 2 * B);
The reason is that the left hand operator which is responsible for invoking
the member function should be an object of the same class. However, friend
function allows both the approaches.
It may be recalled that an object need not be used to invoke friend function
but can be passed as an argument. Thus, we can use a friend function with
a built-in type data as the left-hand operand and an object as the right-hand
operand.
A program illustrating the use of friend function is shown below:
# include<iostream.h>
class distance
{ private:
int feet, inches;
public:
distance()

Manipal University Jaipur B2114 Page No.: 142


Object Oriented Programming – C++ Unit 6

{feet=0; inches=0;}
distance(int f)
{feet=f; inches=0;}
distance(int f, int i)
{feet=f;inches=i;}
void display()
{cout<<feet <<" "<<inches<<endl;}
friend distance operator + (distance, distance);
};
distance operator + (distance d1, distance d2)
{ int f = d1.feet+d2.feet;
int i = d1.inches+d2.inches;
return distance(f,i);}
void main()
{
distance d1(2,5), d2;
d2=10+d1;
d2.display();
}
Let us now study how the relational operators can be overloaded. In this
situation also there can be either one argument or two argument
overloading (using friend function). But the return value should be integer (0
or 1) which indicates true or false.
The following program implements the program for relational operator
overloading (<) for the distance class.
# include<iostream.h>
class distance
{ private:
int feet, inches;
public:
distance()

Manipal University Jaipur B2114 Page No.: 143


Object Oriented Programming – C++ Unit 6

{feet=0; inches=0;}
distance(int f)
{feet=f; inches=0;}
distance(int f, int i)
{feet=f;inches=i;}
void display();
void getdata();
int operator < (distance d1)
{ if (feet<d1.feet)
return 1;
else if (feet==d1.feet) && (inches<d1.inches)
return 1;
else
return 0;
}
};
void distance :: display()
{cout<<feet <<" "<<inches<<endl;}
void distance :: getdata()
{ cout<<”Enter distance in feet and inches”;
cin>>feet >>inches;}
void main()
{
distance d1,d2;
d1.getdata();
d2.getdata();
if (d1<d2)
cout<<d1.display() << “is smaller”;
else
cout<<d2.display()<< “ is smaller”;
}
Manipal University Jaipur B2114 Page No.: 144
Object Oriented Programming – C++ Unit 6

As you can see in the above program the object d1 is responsible for
invoking the operator < whereas object d2 is passed as an argument. The
value returned by the overloaded operator function is either 1 or 0 which
indicates true or false respectively. Certain compilers support boolean
datatype which can be alternatively used instead of integer. The display and
getdata member functions are implemented in a different way in the above
program. You can observe that the member functions are declared inside
the class but defined outside the class. The class name with the function
name separated by scope resolution operator (::) is used to specify that the
member function belongs to the distance class.
Self Assessment Questions
7. Member functions of a class can be defined outside the class using
________ operator along with the class name.
8. In most of the cases same result is generated either by using member
function or by using friend function. (True/False).
9. Overloaded relational binary operators should return _________.
10. Left operand calls the operator in case of binary operator overloading.
(True/False).

6.5 Type Conversions


An expression can consist of constants and variables of same or different
data types. When evaluating an expression which contains a combination of
mixed data types, different variables are converted to the same, to avoid
compatibility issues. This is achieved by the process of type conversion.
Type conversion is defined as the process of converting one predefined
data type to another. An assignment operator performs the automatic type
conversion. The data that is at the right of the assignment operator is
converted to the same data type, which is to the left of assignment operator.
For example, consider the following statement:
int x;
float y= 4.14532
x=y;
In the above example, the compiler converts the value of y to integer before
assigning it to the x. The type conversions are implicit for the built in data
types. But for the user defined data types, implicit conversions are not
Manipal University Jaipur B2114 Page No.: 145
Object Oriented Programming – C++ Unit 6

supported by the compiler. So, for performing type conversion in user


defined data types you have to define the conversion rules.
Three situations may arise in data conversion between incompatible types.
1. Conversion from basic to class type.
2. Conversion from class type to basic type.
3. Conversion from one class type to another class type.
We will discuss all the three situations in detail.
1. Basic to class type
The process to convert basic type to class type is easy to perform. Let us
consider the following constructor:
string :: string ( char *x)
{
length = strlen(x);
y= new char[length+1];
strcpy(y,x);
}
You can see in the above example that the constructor builds a string type
object from a char* type variable x. The variables length and y are data
members of string class. Once this constructor is defined in the string class
it can be used for conversion from char* type to string type. Let us see
another example shown below:
string str1, str2;
char* s1= “ABC”;
char* s2= “PQR”;
str1= string( s1);
str2= s2;
The statement str1=string(s1) converts s1 from char* type to string type and
then assigns the string type value to the object str1. The statement str2=s2
performs the same function by invoking the function implicitly.
2. Class to basic type
The overloaded casting operator in C++ allows us to convert class type data
to basic types.
Manipal University Jaipur B2114 Page No.: 146
Object Oriented Programming – C++ Unit 6

The overloaded casting operator has the general form:


operator typename()
{
function statements
…….
……….
}
This function converts a class type data to typename. For example the
operator double () converts a class object to type double, the operator int()
converts a class type object to type int, and so on.
Let us see the following conversion function:
vector :: operator double()
{
double sum = 0;
for(int i=0; i<size; i++)
sum=sum + v[i] * v[i];
return sqrt(sum);
}
By this function the vector is converted to the corresponding scalar
magnitude. The magnitude of the vector is calculated by the square root of
the sum of the squares of its components. You can use operator double as
follows:
double length = double(v1);
Or double length = v1;
Where v1 is a vector of object type. Both the statements have similar effect.
The casting operator is called by the compiler when it comes across the
statement that requires the conversion of a class type to a basic type.
The casting operator should meet the following condition:
 It must be a class member.
 It must not specify a return type.
 It must not have any arguments.

Manipal University Jaipur B2114 Page No.: 147


Object Oriented Programming – C++ Unit 6

3. One class to another class type


You have studied the data conversion techniques from a basic to class type
and a class to basic type. In this section, you are going to study the process
to convert one class type data to another class type.
Consider the example:
objA = objB; //objects of different types
Here objA is an object of class A and objB is an object of class B. The class
B type data is converted to class A type data and then the converted value
is assigned to objA. B is the source class and A is the destination class as
conversion takes place from class B to class A.
The conversion between objects of different classes can be performed by
either a conversion function or by a constructor. To decide which form is to
be used depends upon where you want the type-conversion function to be
located i.e. either in the source or destination class. You are already aware
that the casting operator function i.e. operator typename() converts a class
object of which it is a member to typename. The typename can be a buit-in
type or a user-defined type. Typename indicates the destination class in
case of conversions between objects. Therefore, when a class needs to be
converted, we can use a casting operator function (i.e. source class). The
conversion takes place in the source class and the result is stored in the
destination class object.
Now let us consider a single-argument constructor function, which serves as
an instruction for converting the argument’s type to the class type of which it
is a member. This shows that the argument belongs to the destination class
and is passed to the destination class for conversion. Then it becomes
necessary to place the conversion constructor in the destination class.
These two approaches are explained in figure 6.2.

Manipal University Jaipur B2114 Page No.: 148


Object Oriented Programming – C++ Unit 6

Figure 6.2: Conversion between objects

Self Assessment Questions


11. ___________ is defined as the process of converting one predefined
data type to another.
12. The overloaded _______ operator in C++ allows us to convert class
type data to basic types.

6.6 Summary
 Operator overloading allows defining new meaning for normal C++
operators and specifies how it can be used with the user defined classes.
 Overloading should be used only to imply default meanings to avoid
confusion in its usage.
 Not all operators can be overloaded. C++ enables the programmer to
overload most operators to be sensitive to the context in which they are
used.
 The compiler generates the appropriate code based on the operator's
use. Operator overloading contributes to C++'s extensibility.
 Operator overloading provides the same concise expressions for user-
defined types that C++ provides with its rich collection of operators that
work on built-in types.
 The precedence and associativity of an operator cannot be changed by
overloading.

Manipal University Jaipur B2114 Page No.: 149


Object Oriented Programming – C++ Unit 6

 Type conversion is defined as the process of converting one predefined


data type to another.
 Three situations may arise in data conversion between incompatible
types.
 These are - conversion from basic to class type, conversion from class
type to basic type and conversion from one class type to another class
type.

6.7 Terminal Questions


1. Create a class string that stores a string value. Overload ++ operator
which converts the characters of the string to uppercase (toupper library
function of ctype.h can be used).
2. Overload += operator for the string class which should allow statements
like s1+=s2. This should concatenate strings s1 and s2 and store the
result in s1.
3. Illustrate, with the help of an example, the procedure to overload a unary
operator.
4. Explain, with the help pf an example, the process to overload a binary
operator.
5. Define type conversion and explain different types of type conversions.

6.8 Answers
Self Assessment Questions
1. True
2. True
3. operator
4. No
5. Same as class datatype
6. False
7. scope resolution operator
8. True
9. Integer or Boolean values
10. True
11. Type Conversion
12. Castings

Manipal University Jaipur B2114 Page No.: 150


Object Oriented Programming – C++ Unit 6

Terminal Questions
1. //string.cpp
# include<iostream.h>
# include<ctype.h>
# include<string.h>
# include<conio.h>
class string
{ char str[25];
public:
string()
{ strcpy(str, "");}
string(char ch[])
{ strcpy(str, ch);}
void display()
{ cout<<str;}
string operator ++()
{string temp;
int i;
for(i=0;str[i]!='\0';i++)
temp.str[i]=toupper(str[i]);s
temp.str[i]='\0';
return temp;
}
};
void main()
{ clrscr();
string s1="hello", s2;
s2=s1++;
s2.display();
getch();
}

Manipal University Jaipur B2114 Page No.: 151


Object Oriented Programming – C++ Unit 6

2. //stringar.cpp
# include<iostream.h>
# include<ctype.h>
# include<string.h>
# include<conio.h>
class string
{ char str[25];
public:
string()
{ strcpy(str, "");}
string(char ch[])
{ strcpy(str, ch);}
void display()
{ cout<<str;}
void operator +=(string s2)
{int i,l,j;
l=strlen(str);
for(i=l,j=0; s2.str[j]!='\0'; i++,j++)
str[i]=s2.str[j];
str[i]='\0';
}
};
void main()
{ clrscr();
string s1="hello", s2="world";
s1+=s2;
s1.display();
getch();
}
3. In case of overloading of unary operators, the calling operand can be
either left or right of the operator as in case of increment and decrement
operators. While defining the operator functionality for the class, the
keyword operator is used. Refer section 6.3 for more details.
Manipal University Jaipur B2114 Page No.: 152
Object Oriented Programming – C++ Unit 6

4. In binary operator overloading, one operand is the object of the class


invoking the function is passed implicitly to the member operator
function. And the other operand is passed as an argument, which can
be passed either by value or by reference. Refer section 6.4 for more
details.
5. Type conversion is defined as the process of converting one predefined
data type to another. Three situations that arise in data conversion
between incompatible types are - conversion from basic to class type,
conversion from class type to basic type and conversion from one class
type to another class type. Refer section 6.5 for more details.

References:
 Object Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
 Object-Oriented Programming using C++, by Satchidananda Dehuri,
Alok Kumar Jagadev, Amiya Kumar Rath. PHI Learning Pvt. Ltd.

Manipal University Jaipur B2114 Page No.: 153


Object Oriented Programming – C++ Unit 7

Unit 7 Inheritance
Structure:
7.1 Introduction
Objectives
7.2 Inheritance in C++
7.3 Public, Private and Protected Inheritance
7.4 Types of Inheritance
7.5 Function Overriding
7.6 Multiple Inheritance
7.7 Constructors in derived classes
7.8 Summary
7.9 Terminal Questions
7.10 Answers

7.1 Introduction
In the previous unit you studied about operator overloading and type
conversions. In this unit you are going to study the concept of inheritance.
You will learn about types of inheritance and multiple inheritances. The
method by which new classes called ‘derived classes’ are created from the
exiting classes called ‘base classes’ is known as ‘inheritance’. The derived
classes have all the features of the base class and the programmer can
choose to add new features specific to the newly created derived class. For
example, you can create a base class called ‘employee’, and define the
derived classes as manager, supervisor, accountant etc. All of these derived
classes have all the features of their base class (employee), and yet differ
because they have some more specific features added.
Objectives:
After studying this unit you should be able to:
 explain the concept of inheritance
 discuss base and derived classes
 describe public, private and protected inheritance
 discuss function overriding
 discuss the different types of inheritance
 explain multiple inheritances
 explain constructors in derived classes

Manipal University Jaipur B2114 Page No.: 154


Object Oriented Programming – C++ Unit 7

7.2 Inheritance in C++


Inheritance is a very powerful feature of object-oriented programming. It
allows reuse of code without modifying the original code. It also provides
flexibility to the programmer to make modifications to the program without
altering the original code which saves debugging and programming time
and effort.
Inheritance feature enables distribution of class libraries which allows the
programmer to use the standard code developed by some other company.
Inheritance is the process of creating new classes known as derived classes
from the existing or base class. The features of the base class or parent
class are said to be inherited by the derived class or child class. The child
class has all the functionality of the parent class, and has additional
functionalities of its own.
As you know, the class data members are declared in the private section of
class definition. Member function of the derived class cannot access the
private data members of the base class. So the data members of the base
class should be declared as ‘protected’ since they will be inherited by
another class. The protected access specifier makes the data members
inaccessible outside that class. But the protected data members of the base
class can be accessed by the ‘members and friends’ function of that base
class, and members and friends of any class derived from the base class.
Derived class member functions can refer to public and protected member
functions of the base class. The accessibility of base class members is also
dependent on the type of inheritance, private or public. The public
inheritance is commonly used which is shown in the program
inheritance.cpp discussed next. The types of inheritance are discussed in
the sections follow.
Advantages of Inheritance:
Reusability:
Inheritance helps the code to be reused in many situations. The base class
is defined, and once it is compiled, it need not be reworked. Using the
concept of inheritance, the programmer can create as many derived classes
from the base class as needed while adding specific features to each
derived class as needed.

Manipal University Jaipur B2114 Page No.: 155


Object Oriented Programming – C++ Unit 7

Saves Time and Effort:


The above concept of reusability achieved by inheritance saves the
programmer‘s time and effort. Since the main code written can be reused in
various situations as needed, it leads to increase in program structure which,
in turn, results in greater reliability.

7.3 Public, Private and Protected Inheritance


A derived class can be defined as follows:
class derived_classname: access specifier baseclassname
{
Members of derived class
};
The access specifer can be public, private or protected.
Access specifier public:
When we derive a class using public base class access specifier, all
inherited public members of the base class will become public members of
the derived class. All inherited protected members of the base class will
become protected members of the derived class. All inherited private
members will remain private to the base class, and cannot be accessed by
the member functions of the derived class.
Access specifier protected:
When you derive a class using a protected base class access specifier, then
all the inherited public and protected members of the base class will
become protected members of the derived class. And all the private
members of the base class cannot be accessed by the member functions of
the derived class.
Access specifier private:
When you derive a class using a private base class access specifier, all
inherited public and protected members of the base class will become
private members of the derived class. All the private members of the base
class cannot be accessed by the member functions of the base class.
The following program implements the inheritance. The class manager is
inherited from the class employee.
//inheritance.cpp
# include<iostream.h>

Manipal University Jaipur B2114 Page No.: 156


Object Oriented Programming – C++ Unit 7

# include<string.h>
# include<conio.h>
class employee
{
protected:
int empno;
char ename[25];
public:
employee()
{ empno=0;
strcpy(ename,"");
}
employee(int n, char ch[25])
{ empno=n;
strcpy(ename,ch);
}
void display()
{cout<<"Emp Code:"<<empno;
cout<<"Name:"<<ename;
}
};
class manager: public employee
{
protected:
float basic;
float hra;
public:
manager():employee()
{ basic=0.0; hra=0.0;}
manager(int n, char ch[25],float i, float j): employee(n,ch)
{ basic=i; hra=j;}
void display()
{ employee ::display();
cout<<"Basic"<<basic<<endl;
cout<<"HRA"<<hra<<endl;
}
};
Manipal University Jaipur B2114 Page No.: 157
Object Oriented Programming – C++ Unit 7

void main()
{
clrscr();
employee e1(106,"amit");
manager m1(205,"pawan",40000.00,5000.00);
e1.display();
m1.display();
getch();
}
As you can see, in the above program, there is a class employee having
data member’s empcode and ename. These are declared as protected data
members so that they can be inherited by the derived class. The employee
class contains two constructors and a member function named ‘display’.
We have derived the manager class form the class employee using the
following statement:
class manager: public employee
Here public is a keyword which specifies that the class is derived publically
from the class employee. You will study the types of inheritance in the next
section. The derived manager class will have inherited data members
i.e. ename and empcode of the base class employee. It also contains its
own data members i.e. basic and hra.
The derived manager class also contains the constructors and a member
function named as ‘display’. In the class manager also, we have defined
constructors and a member function display. While initializing the data
members of the manager class, the respective members of the parent class
will also have to be initialized. The constructors of the parent class are
invoked by the following statements: manager(): employee()
manager(int n,char ch[25],float i, float j): employee(n,ch)
You can also assign default values to the members.
While displaying the contents of the manager class, respective members of
the parent class are also displayed. The display function of the base class is
invoked in ‘the display function’ of the derived class. This is done by the
following statement:
employee::display()

Manipal University Jaipur B2114 Page No.: 158


Object Oriented Programming – C++ Unit 7

As you can see, the class name, followed by the scope resolution operator,
is used to refer the function name belong to the class. When both the base
class and the derived class have a function with the same name, the
object.functionname statement with the base class object will always access
function defined in the base class as the base class does not know anything
about the derived classes. If the object is a derived class object, then the
function defined in the derived class will be invoked. This feature is known
as function overriding. If the function is not defined in the derived class, then
the object will access the function in the parent class.
Self Assessment Questions
1. The derived class object can access ____ members of the parent class.
2. The derived class member functions can access _____________
members of the parent class.
3. Inheritance allows ___________ of the program code.

7.4 Types of Inheritance


It is possible that a class inherits its properties from more than one class or
from more than one level. On this basis the inheritance is classified as
follows:
1. Single Inheritance
2. Multiple Inheritance
3. Multi-level Inheritance
4. Hierarchical Inheritance
5. Hybrid Inheritance
1. Single Inheritance
As you already know, inheritance is a process of deriving a new class from
an existing base class. When only one class is derived from a single base
class, then the inheritance is known as single inheritance.

Vehicle
Base class

Taxi
Derived class
Figure 7.1: Single inheritance

Manipal University Jaipur B2114 Page No.: 159


Object Oriented Programming – C++ Unit 7

In the above figure 7.1 vehicle is the base class and the taxi is the derived
class, which describes the vehicle of a special type.
2. Multiple Inheritance
The derived class can also have multiple parents, which is known as
multiple inheritance. Here the child - or the derived class - has two or more
parent classes as depicted in figure 7.2. The child class inherits all the
properties of all its parents. Multiple inheritance is implemented in a similar
way as single inheritance except that both the parent names have to be
specified while defining the class.

Figure 7.2: Multiple Inheritance

3. Multi-level Inheritance
When a class is derived from the derived class it is known as multilevel
inheritance. In such case, the grandchild class inherits all the properties of
the child and the parent classes as shown in figure 7.3.

Shape
Base or parent class

Rectangle
Child class

Rounded Rectangle
Grandchild class
Figure 7.3: Multi-level Inheritance

4. Hierarchical Inheritance
Many programming problems are cast into hierarchy when certain features
of one level are shared by many others below that level. The example of the

Manipal University Jaipur B2114 Page No.: 160


Object Oriented Programming – C++ Unit 7

hierarchical classification of students in university is shown in figure 7.4


below.

Figure 7.4: Hierarchical Inheritance example

5. Hybrid Inheritance
If we apply more than one type of inheritance to design a problem, then it is
known as hybrid inheritance. Here, a new class can be created from
multiple and multi-level classes, or from the multiple and hybrid classes. The
figure 7.5 shows an example of hybrid inheritance using multiple and multi-
level inheritance.

Figure 7.5: Example of hybrid inheritance

As you can see in the above figure, the child may inherit features from the
grandparents, father and mother. Here inheriting the features of grandparent

Manipal University Jaipur B2114 Page No.: 161


Object Oriented Programming – C++ Unit 7

father and grandparent mother is called multi-level inheritance, and


inheriting the features of father and mother is called multiple inheritance.
You can see in the above example that the manager class is derived from
both the student and the employee class. This is useful in instances where
you want to create an employee whose educational qualifications need not
be stored in the separate class.
Self Assessment questions
4. When the derived class has more than one parent, it is known as
____________.
5. In __________ inheritance, objects of derived class cannot access
public member functions of the base class.
6. A class can be derived further from the derived class. (True/ False)

7.5 Function Overriding


If a class is inherited in the derived class, and if one of the functions of the
base class is again defined in the derived class, then that function is said to
be overridden and this procedure is known as function overriding.
Requirements of function overriding
 Inheritance should be present.
 The function which is overridden should have the same definition in both
the derived and base class, i.e. the function should have the same name,
return type and parameter list.

Manipal University Jaipur B2114 Page No.: 162


Object Oriented Programming – C++ Unit 7

The figure 7.6 shows an example of function overriding.

Figure 7.6: Function overriding in C++

Accessing the Overridden Function in Base Class from Derived Class


If you want to access base class’ overridden function in derived class, then
use base class name, and then the scope resolution operator ( : ), and
finally, the name of the overridden function. For example, as shown in
figure 7.6, if you want to access get_data() function of base class from
derived class, then you should use the statement:
A::get_data(); // calls get_data() function of class A.
Example of function overriding
class A
{
public:
void show()
{
cout << “base class”;
}

Manipal University Jaipur B2114 Page No.: 163


Object Oriented Programming – C++ Unit 7

};
class B: public A
{
public:
void show ()
{
cout<< “ derived class”;
}
};
void main()
{
A obj1; //object of base class
B obj2; //object of derived class
obj1.show(); // calls the function show defined in base class A
obj2.show(); // calls the function show defined in derived class B
}
Self Assessment Questions
7. ________ is the process in which a class is inherited in the derived
class and the one of the functions of the base class is again defined in
the derived class.
8. The function which is overridden can have different definitions in both
the derived and the base classes. (True/False)

7.6 Multiple Inheritance


You have already studied the concept of multiple inheritance in the previous
section. In this section we will study this concept in detail along with the
ambiguities that arise in this type of inheritance. Multiple Inheritance is the
process of inheriting a class from more than one parent class. This would be
required in several instances where you would like to have the
functionalities of several classes. This is also extensively used in class
libraries. To derive from more than one base class, you separate each base
class by commas in the class designation as shown below:
class Derived : [virtual] [access_type] base1, [virtual] [access_type]
base2,……. [virtual] [access_type] baseN
{
…………
};

Manipal University Jaipur B2114 Page No.: 164


Object Oriented Programming – C++ Unit 7

Here base1, base2, baseN are direct bases of Derived, and each of them
should have a distinct name.
An access_type can be private, public or protected, and follows the same
access rules as single inheritance.
The keyword ‘virtual’ is optional, and specifies a sharable base.
Member functions or data that have the same name in base1, base2 or
baseN are potential ambiguities.
Here are several examples of multiple inheritance declarations:
class A : public B, public C { ….. };
Class A derives publically from base classes B and C like single inheritance.
class D: public E, private F, public G{…..};
Class D derives publically from E and G and privately from F. This
derivation makes D a subtype pf E and G and not a subtype of F. C
class X: Y, Z {….};
Class X derives privately from both y and Z by default as no access
specifier is mentioned.
class M: virtual public N, virtual public p {….};
Here N and P are virtual bases of M. which we will discuss in unit 8.
Let us implement a program where there are two classes namely ‘student’
and ‘employee’. We shall derive a class manager from the above two
classes and see how member functions and constructors are implemented
in multiple inheritance:
//multiple.cpp
# include<iostream.h>
# include<string.h>
# include<conio.h>
class student
{protected:
char qual[6]; // highest degree earned
int percent; // percentage score in the last degree
public:
student()

Manipal University Jaipur B2114 Page No.: 165


Object Oriented Programming – C++ Unit 7

{strcpy(qual, “”); percent=0;}


student(char ch[6], int p)
{strcpy(qual, ch); percent=p;}
void display()
{cout<<endl<<”Qualification”<<qual;
cout<<endl<<”Score”<<percent;
}} ;
class employee {
protected:
int empno;
char ename[25];
public:
employee()
{empno=0;
strcpy(ename,"");
}
employee(int n, char ch[25])
{empno=n;
strcpy(ename,ch);
}
void display()
{cout<<endl <<"Emp Code:"<<empno;
cout<<endl <<"Name:"<<ename;
}
};
class manager: public employee, public student
{
protected:
float basic;
float hra;
public:
manager():employee(),student()
{basic=0.0; hra=0.0;}
manager(int n,char ch[25], char ch1[6], int p, float i, float j): employee(n,ch),
student(ch1,p)
{basic=i; hra=j;}
void display()
Manipal University Jaipur B2114 Page No.: 166
Object Oriented Programming – C++ Unit 7

{ employee::display();
student::display();
cout<<endl <<"Basic"<<basic;
cout<<endl <<"HRA"<<hra;
}
};
void main()
{
clrscr();
manager m1(205, “pawan”, “MBA”, 80, 40000.00, 5000.00);
m1.display();
getch();
}
As you can see in the above program, both the parent class and
constructors are called by the constructors of derived class. This is because
every object of the derived class has its own copy of parent data members.
Therefore, their initializations too is required. The parent class member
functions are invoked using the scope resolution operator as shown in the
display function of the manager class.
The output of the above program will be:
Emp Code:205
Name:pawan
Qualification MBA
Score 80
Basic 40000
HRA 5000
Ambiguity in multiple Inheritance
There are several types of ambiguities that might arise in the process of
implementation of multiple inheritance. Let us suppose that there are two
parent classes P and Q. And class R is the derived class of P and Q.
Suppose that there is a function ‘func1()’ defined in both the parent classes
P and Q, but this func1() has not been defined in the child class. When the
child class object (obj) tries to access the function func1() through a
statement obj.func1(), there is compiler error. The reason is that this
statement is ambiguous for the compiler as it will not be able to find out

Manipal University Jaipur B2114 Page No.: 167


Object Oriented Programming – C++ Unit 7

which parent’s f1() function is called. The ambiguity can be resolved by


prefixing the parent class name followed by scope resolution operator
before the function name. The following statement would resolve the
ambiguity.
obj.P::func1();
This statement tells the compiler to use the function func1() of parent
class P. Another solution would be to introduce a dummy function func1() in
Class R, and invoke the applicable parent functions.
Another common ambiguity that arises is in the case of diamond inheritance.
The situation when both parent classes are derived from a single parent is
known as diamond inheritance. The situation is shown in figure 7.7.

Figure 7.7: Diamond Inheritance

class X
{protected:
int a;};
class Y: public parent
{ };
class Z: public parent
{ };
class P: public X, public Y
{ public:
int f1()
return a; //ambiguous
};

Manipal University Jaipur B2114 Page No.: 168


Object Oriented Programming – C++ Unit 7

Let us consider a situation where there is a parent class X having a


protected data member a. Two child classes X and Z are derived publically
from parent class X.
Class P is derived publically from base classes X and Y. There arises an
ambiguity when grandchild P tries to access the data member of parent
class X. The ambiguity arises when classes Y and Z are derived from X:
each inherits a copy of X called sub-object, and inherits an own copy of the
parent data. The ambiguity arises for the grandchild in resolving which copy
of the child class subobject is to be accessed.
The solution for this is virtual base class. In this, the common base class is
made virtual base class while declaring direct or intermediate base class.
For example:
By making classes Y and Z as virtual classes, the two classes will share a
common subobject, and will result in resolving the ambiguity as shown
below.
class X
{protected:
int a;};
class Y: virtual public X
{};
class Z: virtual public X
{};
class P: public Y, public Z
{ public:
int f1()
return a; //only one copy of the parent
};
Self Assessment Questions
9. _________ is the process of inheriting a class from more than one
parent class.
10. In multiple inheritance, when a class is derived from more than one
base class, each base class is separated by commas in the class
definition. (True/False)
11. The situation where both parent classes are derived from a single
parent is known as ___________.
Manipal University Jaipur B2114 Page No.: 169
Object Oriented Programming – C++ Unit 7

7.7 Constructors in Derived Classes


You already know that constructors play an important role in initializing the
objects. One thing you should note is that, as long as no base class object
takes any argument, the derived class need not have a constructor function.
But there is a constructor in any base class with one or more arguments.
Then it is compulsory for the derived class to have a constructor and pass
the arguments to the base class constructors. In inheritance, we create
objects using the derived class. Thus, it makes sense for the derived class
to pass arguments to the base class constructor. When the constructors are
present in both the derived and the base classes, the base class constructor
is executed first, and then the constructor in the derived class is executed.
In the case of multiple inheritance, the base classes are constructed in the
order in which they appear in the declaration of the derived class. Similarly,
in a multi-level inheritance, the constructors will be executed in the order of
inheritance.
Since it is the responsibility of the derived classes to provide initial values to
its base classes, when a derived class object is declared, we supply initial
values that are required by all the classes together. For such situations C++
has a special argument passing mechanism.
In these situations, the constructor of the derived class receives the entire
list of values as its arguments, and passes them on to the base class in the
order in which they are declared in the derived class. The base constructors
are called and executed before executing the statements in the body of the
derived constructors. The general form of defining a derived constructor is
as follows:
Derived-constructor (Arglist1, Arglist2,….. AglistN, Arglist(D)
base1(arglist1),
base2(arglist2),
……..
……..

baseN(arglistN),
{
Body of derived constructor
}

Manipal University Jaipur B2114 Page No.: 170


Object Oriented Programming – C++ Unit 7

The header line of the derived-constructor function contains two parts


separated by colon( : ). The declaration of the arguments is provided by the
first part which is passed to the derived constructor. The second part lists
the function calls to the base constructors.
base1(arglist1), base2(arglist2)…. Are function calls to the base
constructors base1(), base2(),…. And the arglist1, arglist2….etc. denotes
actual parameters that are passed to the constructor of the base class.
Arglist1 to Arglist N are the argument declarations for the base constructors
base1 to base N. ArglistD provides the parameters that are necessary to
initialize the members of the derived class.
For example:
D(int a1, int a2, float b1, float b2, int d1):
A(a1, a2), //call to constructor A
B(b1, b2) //call to constructor B
{
d=d1; //executes its own body
}
Here A(a1, a2) invokes the base constructor A(), and B(b1, b2) invokes
another base constructor B(). The constructor D() supplies the values for
these four arguments. D() may be invoked as follows:
………….
D objD(5, 12, 2.5, 7.54, 30)
………….
These values are assigned to various parameters by the constructor D() as
follows:
5 -> a1
12 -> a2
2.5 -> b1
7.54 -> b2
30 -> d1
The constructors of the virtual base classes are invoked before any non-
virtual base classes. If there are multiple virtual base classes, they are
invoked in the order in which they are declared. Any non-virtual bases are
then constructed before the derived class constructor is executed.

Manipal University Jaipur B2114 Page No.: 171


Object Oriented Programming – C++ Unit 7

The following program demonstrates how the constructors are implemented


when the classes are inherited.
#include<iostream.h>
class alpha
{
int x;
public:
alpha(int i)
{
x=i;
cout << “” alpha initialized”;
}
void show_x(void)
{
cout << “x=” << x \n”;
}
};
class beta
{
float y;
public:
beta(float j)
{
y=j;
cout<< “beta initialized”;
}
void show_y(void)
{
cout << “y=” << y << “\n”;
}
};
class gamma (int a, float b, int c, int d): alpha(a), beta(b)
{
m=c;
n=d;
cout << “gamma initialized\n”;
}
Manipal University Jaipur B2114 Page No.: 172
Object Oriented Programming – C++ Unit 7

void show_mn(void)
{
cout<< “m = “ << m << “\n” << “n=” << n << “\n”;
}
};
void main()
{
gamma g(5, 10, 75, 20, 30)
cout << “\n”;
g.show_x();
g.show_y();
g.show_mn();
}
The output of the program will be:
beta initialized
alpha initialized
gamma initialized
x=5
y=10.5
m=20
n=30
Self Assessment Questions
12. In the case of __________ the base classes are constructed in the
order in which they appear in the declaration of the derived class.
13. The constructors of the virtual base classes are invoked before any
non-virtual base classes. (True/False)

7.8 Summary
 Inheritance allows creating a class known as derived class from a class
known as base class, and inheriting all the properties of the parent class
allows programs to be reused without rewriting entire code.
 The members that can be inherited have to be declared using protected
access specifier. There can be several levels of inheritance and the
derived class can be inherited from multiple parents as well.
 Inheritance helps the code to be reused in many situations and this
concept of reusability saves the programmer’s time and effort.

Manipal University Jaipur B2114 Page No.: 173


Object Oriented Programming – C++ Unit 7

 A derived class can be defined as follows:


class derived_classname: access specifier baseclassname
{
Menmbers of derived class
};
Inheritance can be public, private or protected, depending on the access
specifier in the above declaration.
 Inheritance is classified as follows: Single Inheritance, Multiple
Inheritance, Multi-level Inheritance, Hierarchical Inheritance and Hybrid
Inheritance.
 Multiple Inheritance is the process of inheriting a class from more than
one parent class.
 If there is a constructor in any base class with one or more arguments,
then it is compulsory for the derived class to have a constructor, and
pass the arguments to the base class constructors.
 In the case of multiple inheritance, the base classes are constructed in
the order in which they appear in the declaration of the derived class.
Similarly, in a multilevel inheritance, the constructors will be executed in
the order of inheritance.

7.9 Terminal Questions


1. Write the output of the following program
# include <iostream.h>
# include<conio.h>
class A {
public:
A() {cout<<"Null Constructor for A" <<endl;}
};
class B: public A {
public:
B() {cout<<"Null Constructor for B" <<endl;}
B(int x) {cout<< "Int constructor for B"<<endl;}
};
class C: public B {
public:
C() {cout<<"Null Constructor for C" <<endl;}

Manipal University Jaipur B2114 Page No.: 174


Object Oriented Programming – C++ Unit 7

C(int x) : B(x){cout<< "Int constructor for C"<<endl;}


};
void main()
{
clrscr();
A a;
B b;
B bobj(5);
C c;
C cobj(1);
getch();
}
2. Write the output of the following program
# include <iostream.h>
# include<conio.h>
class A {
public:
A() {cout<<"Null Constructor for A" <<endl;}
~A() {cout<< "Destructor for A"<<endl;}
};
class B: public A {
public:
B() {cout<<"Null Constructor for B" <<endl;}
~B() {cout<< "Destructor for B"<<endl;}
};
class C: public B {
public:
C() {cout<<"Null Constructor for C" <<endl;}
~C() {cout<< "Destructor for C"<<endl;}
};
void main()
{
C c;
getch();
}

Manipal University Jaipur B2114 Page No.: 175


Object Oriented Programming – C++ Unit 7

3. Explain public, private and protected inheritance with examples.


4. List and explain different types of inheritance.
5. Describe the ambiguities of multiple inheritance.
6. Explain function overriding with the help of an example.
7. Explain how to use constructors in derived classes.

7.10 Answers
Self Assessment Questions
1. public
2. public and protected
3. reusability
4. Multiple Inheritance
5. Private Inheritance
6. True
7. Function overriding
8. False
9. Multiple inheritance
10. True
11. Diamond Inheritance
12. Multiple Inheritance
13. True

Terminal Questions
1. Output is:
Null Constructor for A
Null Constructor for A
Null Constructor for B
Null Constructor for A
Int Constructor for B
Null Constructor for A
Null Constructor for B
Null Constructor for C
Null Constructor for A
Int Constructor for B
Int Constructor for C

Manipal University Jaipur B2114 Page No.: 176


Object Oriented Programming – C++ Unit 7

2. Output is
Null Constructor for A
Null Constructor for B
Null Constructor for C
Destructor for C
Destructor for B
Destructor for A
3. A derived class can be defined as follows:
class derived_classname: access specifier baseclassname
{
Members of derived class
};
The access specifer can be public, private or protected. Depending on
the access specifier, the inheritance can be public, private or protected.
(Refer section 7.3 for more details).
4. The different types of inheritance are: Single Inheritance, Multiple
Inheritance, Multi-level Inheritance, Hierarchical Inheritance, and Hybrid
Inheritance. (Refer section 7.4 for more details).
5. There are several types of ambiguity that might arise during the
implementation of multiple inheritance. Let us suppose that there are
two parent classes P and Q. And class R is the derived class of P and Q.
Suppose further that there is a function func1() defined in both the
parent classes P and Q, but func1() has not been defined in the child
class. When the child class object (obj) tries to access the function
func1() through a statement obj.func1(), there is a compiler error. The
reason is that this statement is ambiguous for the compiler, as it will not
be able to find out which parent’s f1() function is called. Another
common ambiguity that arises is in the case of diamond inheritance.
(Refer section 7.6 for more details).
6. If a class is inherited in the derived class, and one of the functions of the
base class is again defined in the derived class, then that function is
said to be overridden, and this procedure is known as function overriding.
(Refer section 7.5 for more details).
7. If there is a constructor in any base class with one or more arguments,
then it is compulsory for the derived class to have a constructor and
Manipal University Jaipur B2114 Page No.: 177
Object Oriented Programming – C++ Unit 7

pass the arguments to the base class constructors. In inheritance, we


create objects using the derived class. When the constructors are
present in both the derived and the base class, the base class
constructor is executed first and then the constructor in the derived class
is executed. (Refer section 7.7 for more details).

References:
 Object-Oriented C++ Programming, First edition, by Hirday Narayan
Yadav. Firewall Media.
 Interfacing with C++: Programming Real-World Applications,
by Jayantha Katupitiya, Kim Bentley. Springer Science & Business
Media.
 Object-oriented Programming with C++ - Sixth Edition,
by E Balagurusamy. Tata McGraw-Hill Education.
 http://www.programiz.com/

Manipal University Jaipur B2114 Page No.: 178


Object Oriented Programming – C++ Unit 8

Unit 8 Polymorphism and Virtual Functions

Structure:
8.1 Introduction
Objectives
8.2 Introduction to polymorphism
8.3 Types of polymorphism
8.4 Function overloading
8.5 Introduction to Virtual Functions
Pure Virtual Functions
8.6 Function Overloading v/s Function Overriding
8.7 Summary
8.8 Terminal Questions
8.9 Answers

8.1 Introduction
In the previous unit you have learnt about inheritance and its types. You
have also studied in detail the concept of multiple inheritance. In this unit
you are going to study polymorphism and virtual functions. Polymorphism
refers to the ability to call different functions by using only one type of
function call. The special type of functions which can be re-defined in
derived classes are known as virtual functions. Virtual functions are special
member functions of a class which may be re-defined in the derived classes.
It is used to give specific meaning to the base class member function with
respect to the derived class. Virtual functions can be thought of as a
function name reserved in the base class which may be re-defined in the
derived classes as per the need so that every derived class has the same
function that performs specific (as redefined in the derived class) action.
Objectives:
After studying this unit you should be able to:
 discuss polymorphism
 explain types of polymorphism
 discuss function overloading
 describe virtual functions
 explain pure virtual functions
 compare function overloading and function overriding
Manipal University Jaipur B2114 Page No.: 179
Object Oriented Programming – C++ Unit 8

8.2 Introduction to Polymorphism


Polymorphism means same content but different forms. The origin of the
word polymorphism comes from two Greek words’ poly (many) and
morphos (form), together meaning multiform. In C++, by the concept of
polymorphism the same program code can call different functions of
different classes. For example let us consider a situation where you want to
create a base class shape and want to derive classes such as rectangle,
circle, and triangle from it. Let us suppose that all these classes have a
member function named draw which draws the object on the screen. It will
be easy if there is a common code so that you can draw all the shapes
mentioned above using the same code and the shape to be drawn is
decided at runtime. The code is shown below:
Shape *ptrarr[100]
for (int j=0;j<n;j++)
ptrarr[j]->draw();
This is a very desirable capability by which totally different functions are
executed by the same function call. If the ptrarr is pointing to a rectangle, a
rectangle is drawn. If it is pointing to a circle, a circle is drawn.
This is exactly what polymorphism is. However, we have to fulfill several
conditions to implement this approach. The first condition is that all the
classes i.e. rectangle, circle and triangle should be derived from a single
class. The second condition is that you should declare draw function as
virtual in the base class (in the shape class). Once you write application by
using the polymorphism concept, then it can easily be extended, providing
new objects that conform to the original interface. It is unnecessary to
recompile original programs by adding new types. To exhibit the new
changes along with the old application, only re-linking is required. This is the
achievement of C++ object-oriented programming. In programming
language, there has always been a need for adding and customizing. By
using polymorphism in C++ time and effort is reduced and future
maintenance is also made easy.
The advantages of polymorphism are:
 Helps in reusability of code.
 Provides easier maintenance of applications.
 Helps in achieving robustness in applications.

Manipal University Jaipur B2114 Page No.: 180


Object Oriented Programming – C++ Unit 8

Program to demonstrate polymorphism


Program poly1.cpp
#include <iostream.h>
// a base class declaration and the implementation part
class vehicle
{
int wheels;
float weight;
public:
void message(void) // first message
{
cout<<"Vehicle message, from vehicle, the base class\n";}
}
};
// a derived class declaration and implementation part
class car : public vehicle
{
int passenger_load;
public:
void message(void) // second message
{
cout<<"Car message, from car, the vehicle derived class\n";
}

};
class truck: public vehicle
{
int passenger_load;
float payload;
public:
int passengers(void)
{
return passenger_load;
}
};
class boat: public vehicle

Manipal University Jaipur B2114 Page No.: 181


Object Oriented Programming – C++ Unit 8

{
int passenger_load;
public:
int passengers(void)
{
return passenger_load;
}
void message (void) // third message
{
cout<<”Boat message, from boat, the vehicle derived class\n”;
}
};
// the main program
int main()
{
vehicle unicycle;
car sedan_car;
truck trailer;
boat sailboat;
unicycle.message();
sedan_car.message();
trailer.message();
sailboat.message();
// base and derived object assignment
unicycle = sedan_car;
unicycle.message();
// system(“pause”);
return 0;
}
The output of the program is:
Vehicle message, from vehicle, the base class
Car message, from car, the vehicle derived class
Vehicle message, from vehicle, the base class
Boat message, from boat, the vehicle derived class
Vehicle message, from vehicle, the base class

Manipal University Jaipur B2114 Page No.: 182


Object Oriented Programming – C++ Unit 8

Self Assessment Questions


1. ________ enables the same program code to call different functions of
different classes.
2. Polymorphism in C++ reduces time, effort and by this makes future
maintenance easy. (True/False)

8.3 Types of Polymorphism


There are two levels at which polymorphism can be achieved. These are:
1. Compile time polymorphism
2. Run time polymorphism
We will discuss these two briefly.
1. Compile time polymorphism
It is achieved through function overloading and operator overloading. You
have already studied operator overloading in unit 6 and you will study
function overloading in next section. In operator overloading the member
functions of the same name but different arguments help the compiler to link
the appropriate function definition to a specific function call during compile
time. This type of binding is known as static or early binding. Early binding
simply means that an object is bound to its function call at compile time.
Hence, the polymorphism achieved through function overloading is called
compile-time polymorphism.
2. Run-time polymorphism
This type of polymorphism is achieved through virtual functions. You will
study virtual functions in the coming section of this unit. In this type of
polymorphism binding or linking of a function definition to a specific function
call is done during run-time. Hence, the polymorphism achieved through
virtual functions is called run-time polymorphism.
At run time, when it is known objects of which class 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, this process is
termed as late binding. It is also known as dynamic binding because the
selection of the appropriate function is dome dynamically at run time.
Dynamic binding is one of the powerful features of C++. This requires the
use of pointers to objects (already discussed in unit 4).

Manipal University Jaipur B2114 Page No.: 183


Object Oriented Programming – C++ Unit 8

The following figure shows the levels of polymorphism.

Figure 8.1: Achieving polymorphism

Self Assessment Questions


3. There are two types of polymorphism and these are _________ and
_______ polymorphism.
4. __________ polymorphism is achieved through function overloading
and operator overloading.
5. __________ polymorphism is achieved through virtual functions.
6. In operator overloading, the member functions of the same name but of
different arguments help the compiler to link the appropriate function
definition to a specific function call during compile time. This type of
binding is known _______.
7. Dynamic binding requires the use of pointers to objects. (True/False)

8.4 Function Overloading


In C++ when a function has multiple declarations of the same function name
in the same scope, it is called function overloading. These declarations
differ in the type and number of arguments in the argument list. When an
overloaded function is called, the types of actual arguments are compared
with types of formal arguments. Thus, a correct function is selected.
Overloaded functions enable programmers to supply different semantics for
a function, depending on the types and number of arguments. The example
of function overloading is shown below. In this program the function area is
overloaded to calculate the area of circle, rectangle and triangle.

Manipal University Jaipur B2114 Page No.: 184


Object Oriented Programming – C++ Unit 8

#include<iostream.h>
#include<stdlib.h>
#include<conio.h>
#define pi 3.14
class Areacalculate
{
public:
void area(int); //circle
void area(int,int); //rectangle
void area(float,int,int); //triangle
};
void Areacalculate::area(int a)
{
cout<<"Area of Circle:"<<pi*a*a;
}
void Areacalculate::area(int a,int b)
{
cout<<"Area of rectangle:"<<a*b;
}
void Areacalculate::area(float t,int a,int b)
{
cout<<"Area of triangle:"<<t*a*b;
}
void main()
{
int ch;
int a,b,r;
clrscr();
fn obj;
cout<<"\n\t\tFunction Overloading";
cout<<"\n1.Area of Circle\n2.Area of Rectangle\n3.Area of
Triangle\n4.Exit\n:”;
cout<<”Enter your Choice:”;
cin>>ch;

Manipal University Jaipur B2114 Page No.: 185


Object Oriented Programming – C++ Unit 8

switch(ch)
{
case 1:
cout<<"Enter Radious of the Circle:";
cin>>r;
obj.area(r);
break;
case 2:
cout<<”Enter Sides of the Rectangle:”;
cin>>a>>b;
obj.area(a,b);
break;
case 3:
cout<<"Enter Sides of the Triangle:";
cin>>a>>b;
obj.area(0.5,a,b);
break;
case 4:
exit(0);
}
getch();
}
The output of the above program is:
Function Overloading
1. Area of Circle
2. Area of Rectangle
3. Area of Triangle
4. Exit
Enter Your Choice: 2
Enter the Sides of the Rectangle: 5 5
Area of Rectangle is: 25
1. Area of Circle
2. Area of Rectangle
3. Area of Triangle
4. Exit
Enter Your Choice: 4

Manipal University Jaipur B2114 Page No.: 186


Object Oriented Programming – C++ Unit 8

8.5 Introduction to Virtual Functions


Virtual means appearing like something while in reality it is something else.
Virtual function is a member function that you expect to be redefined in
derived classes. When you refer to a derived class object using a pointer or
a reference to the base class, you can call a virtual function for that object
and execute the derived class's version of the function. A virtual function is
a function that must be overridden. That means it is declared in the base
class using virtual keyword and its functionality is redefined by its derived
classes.
As mentioned earlier, polymorphism refers to the property by which objects
belonging to different classes are able to respond to the same message, but
in different forms. An essential requirement of polymorphism is the ability to
refer to objects without any regard to their classes. This necessitates the
use of single pointer variable to refer to the objects of different classes. Here
we use pointer to base class to refer all the derived objects. But it is found
that the pointer of base class, even when it is made to contain the address
of derived class, always executes the function in the base class. The
contents of the pointer are ignored by the compiler and it chooses the
member function that matches the type of the pointer. You may wonder how
can one achieve polymorphism? It is achieved using virtual functions.
When the same function name is used in both base and derived classes,
then the base class function is declared as virtual using the virtual keyword
before the declaration of the function. When the function is declared as
virtual then C++ can determine which function is to be used at run time
based on the type of the 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, you can execute different versions of virtual functions.
Let us consider that there is a base class named as base and two classes
derv1 and derv2 are derived publicly from class base. Suppose that you
want to create a pointer that points to the objects of any of the derived class
objects. If the pointer to derv1 is created then it will point to derv1 only. If
you try to assign any other object to the pointer then it is not accepted by
the compiler. The solution to this is to create pointer to the base class.
// objectptr.cpp

Manipal University Jaipur B2114 Page No.: 187


Object Oriented Programming – C++ Unit 8

# include <iostream.h>
class base
{
public:
void show()
{
cout<<“base”<<endl;
}
};
class derv1:public base
{
public:
void show()
{
cout<<“derv1”<<endl;
}
};
class derv2: public base
{
public:
void show()
{
cout<<“derv2”<<endl;
}
};
void main()
{
derv1 dv1;
derv2 dv2;
base *ptr;
ptr=&dv1;
ptr->show();
ptr=&dv2;
ptr->show();
}

Manipal University Jaipur B2114 Page No.: 188


Object Oriented Programming – C++ Unit 8

Surprisingly, the output of the above program will be:


base
base
You can see in the program above that even though the pointer is assigned
the address of the derived class, the base class function is executed by the
compiler. Then as already been discussed, you have to make the base
class function virtually to get the desired result. In the program shown below
the show() function of the base class is made virtual by prefixing it with
virtual keyword.
//virtual.cpp
# include <iostream.h>
class base
{
public:
virtual void show() // virtual function
{
cout<<“base”<<endl;
}
};
class derv1:public base
{
public:
void show()
{
cout<<“derv1”<<endl;
}
};
class derv2: public base
{
public:
void show()
{
cout<<“derv2”<<endl;

Manipal University Jaipur B2114 Page No.: 189


Object Oriented Programming – C++ Unit 8

}
};
void main()
{
derv1 dv1;
derv2 dv2;
base *ptr;
ptr=&dv1;
ptr->show();
ptr=&dv2;
ptr->show();
}
By declaring the base class function as virtual, we now get the output as:
derv1
derv2
As you can observe, the compiler decides which class function is to be
called during runtime depending on the contents in the pointer. This is
known as late binding or dynamic binding.
8.5.1 Pure virtual functions
Most of the times, the idea behind declaring a function (in the base class)
virtual, is to stop its execution. The base class function is used very rarely to
perform any task. Its role is only to serve as a placeholder. Then you may
question why it is required to define (in detail) virtual functions? This leads
to the idea of pure virtual functions or do-nothing functions. A pure virtual
function is virtual function with no definition. You can declare a function as
pure virtual by the following syntax:
virtual <return type> <function name> = 0;
here virtual is the keyword.
function name is the name of the function that is to be made purely virtual.
return type is the type of the data that virtual function returns.
For example: virtual void move() = 0;
Note that the function is initialized to zero. Here the assignment operator ‘=’
has nothing to do with the assignment i.e. the value zero is not assigned to

Manipal University Jaipur B2114 Page No.: 190


Object Oriented Programming – C++ Unit 8

anything. It is just to inform the compiler that the function will be pure and
does not have any body.
You should note that no code is associated with this function. But what
implementation it has done on the class in which it is declared? This class
has a function, which cannot be executed. Hence, it is not possible for you
to declare any object of this class. In other words the class becomes an
abstract base class. The main objective of the abstract base class is to
provide some traits to the derived classes and to create base pointer
required for achieving run time polymorphism.
Let us see an example program:
#include <iostream,h>
class Exforsys
{
public:
virtual void example()=0; //Denotes pure virtual Function Definition
};
class Exf1:public Exforsys
{
public:
void example()
{
cout << "Welcome";
}
};
class Exf2:public Exforsys
{
public:
void example()
{
cout << "To Training";
}
};

void main()
{
Exforsys* arra[2];
Manipal University Jaipur B2114 Page No.: 191
Object Oriented Programming – C++ Unit 8

Exf1 e1;
Exf2 e2;
arra[0]=&e1;
arra[1]=&e2;
arra[0]->example();
arra[1]->example();
}
Output of the above program is:
WelcomeTo Training
In the above program example() is a pure virtual function and has no body
and it is declared with notation =0. Exf1 and Exf2 are the two derived
classes which are derived from the base class Exforsys. The pure virtual
function example() takes up new definition. A list of pointers to the base
class is defined in the main function. Here e1 and e2 are the objects of
derived classes Exf1 and EXf2.
Two objects named e1 and e2 are defined for derived classes Exf1 and
Exf2. The address of the objects e1 and e2 are stored in the array pointers
which are then used for accessing the pure virtual function example()
belonging to both the derived class EXf1 and EXf2.
Normally the virtual functions are declared in a base class and redefined in
the derived class. The base class version of the function is not always used
to perform the specific job or task, i.e. in case where the base class may be
abstract with no possibility of declaration of an object, there is no sense in
defining the virtual function in a base class. The actual function should be
implemented or defined in each of the derived class. The base class
function should just act as a placeholder to be overridden by the derived
class versions. And it is not invoked by itself directly. To be more precise, a
class having pure virtual function cannot be used to instantiate objects of its
own. Hence, there is an error in the above program.
Self Assessment Questions
8. When a function has multiple declarations of the same function name
in the same scope, it is called _________.

Manipal University Jaipur B2114 Page No.: 192


Object Oriented Programming – C++ Unit 8

9. When the same function name is used in both base and derived
classes, then the base class function is declared as virtual using the
_______ keyword.
10. No code is associated with pure virtual functions. (True/ False).

8.6 Function Overloading v/s Function Overriding


You have already studied function overriding in the previous unit and
function overloading in this unit. Now let us compare both the techniques.
 In both the techniques, same function name is used. But different
parameters are passed in function overloading whereas the number of
parameters passed to the function are same in function overriding.
 The function overloading may have different return type but in function
overriding the return type of base and derived member function is the
same.
 Function overloading is a method that allows defining multiple member
functions with the same name but different signatures. The signature
means the function name, number and types of parameters it accepts.
Whereas, overriding is the process that allows the derived class to
redefine the behavior of member functions which the derived class
inherits from a base class. The signatures of both base class member
function and derived class member function are the same; however the
implementation and therefore the behavior will differ.
 Overloaded functions are in same scope whereas overridden functions
are in different scope.

8.7 Summary
 Polymorphism means same content but different forms. By the concept
of polymorphism the same program code can call different functions of
different classes.
 There are two levels at which polymorphism can be achieved. These
are:
o Compile time polymorphism – It is achieved through function
overloading and operator overloading and
o Run time polymorphism – This type of polymorphism is achieved
through virtual functions.

Manipal University Jaipur B2114 Page No.: 193


Object Oriented Programming – C++ Unit 8

 In C++, when a function has multiple declarations of the same function


name in the same scope, it is called function overloading. These
declarations differ in the type and number of arguments in the argument
list.
 Virtual function is a member function that you expect to be redefined in
derived classes. When you refer to a derived class object using a
pointer or a reference to the base class, you can call a virtual function
for that object and execute the derived class's version of the function.
Virtual function is a member function that you expect to be redefined in
derived classes. A pure virtual function is virtual function with no
definition. It can be declared as follows: virtual <return type> <function
name> = 0.

8.8 Terminal Questions


1. Imagine a publishing company markets books and CD-ROMS. Create a
class called publication which stores titles and price of publications.
Derive two classes: book which adds a page count and CD-ROM which
adds playing time in minutes. Each of the three classes should have a
getdata() and putdata() function to get its data from the user and display
the data respectively. Write a main program that creates an array of
pointers to publication and in a loop, ask the user for data for book or
cdrom. When user has finished entering data, display all the data.
2. Describe the concept of polymorphism.
3. Describe the types of polymorphism.
4. Explain function overloading with an example.
5. Explain the concept of virtual function.
6. Discuss pure virtual functions.
7. Write the output of the following program:
#include <iostream.h>
class Shape
{
protected:
int width, height;
public:
Shape(int a=0, int b=0)

Manipal University Jaipur B2114 Page No.: 194


Object Oriented Programming – C++ Unit 8

{
width = a;
height = b;
}
virtual int area()
{
cout << ”Parent class area :” <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);

// store the address of Rectangle


shape = &rec;
Manipal University Jaipur B2114 Page No.: 195
Object Oriented Programming – C++ Unit 8

// call rectangle area.


shape->area();

// store the address of Triangle


shape = &tri;
// call triangle area.
shape->area();

return 0;
}
8. Write the ouptput of the following program:
#include<iostream.h>
class X
{
public:
void virtual display()=0; //pure virtual function
};
class Y : public X //class Y publically inherits class X
{
public:
void display()
{
cout<< “ ABC” << endl;
}
};
int main()
{
X *xptr;
X objx; //error
Y objy;
Xptr = &objy;
Xptr -> display();
return 0;
}
9. Compare function overloading and function overriding.

Manipal University Jaipur B2114 Page No.: 196


Object Oriented Programming – C++ Unit 8

8.9 Answers
Self Assessment Questions
1. Polymorphism
2. True
3. Run-time, compile-time
4. Compile time
5. Run-time
6. Static or early binding
7. True
8. Function overloading
9. Virtual
10. True
Terminal Questions
1. //publish.cpp
# include <iostream.h>
#include<conio.h>
class publication
{ protected:
char title[80];
float price;
public:
virtual void getdata()
{ cout<<endl<<”enter title:”;
cin>>title;
cout<<endl<<”enter price”;
cin>>price;
}
virtual void putdata()
{
cout<< endl<<”Title”<<title;
cout<<endl<<”Price”<<price;
}
};
class book: public publication
{
private:

Manipal University Jaipur B2114 Page No.: 197


Object Oriented Programming – C++ Unit 8

int pages;
public:
void getdata()
{ publication::getdata();
cout<<endl<<”enter number of pages”;
cin>>pages;
}
void putdata()
{
publication::putdata();
cout<< endl<<”Number of pages”<<pages;
}
};
class cdrom: public publication
{
private:
float time;
public:
void getdata()
{ publication::getdata();
cout<<endl<<”enter playing time:”;
cin>>time;
}
void putdata()
{
publication::putdata();
cout<< endl<<”Playing time”<<time;
}
};
void main()
{
publication * ptr[10];
book* bptr;
cdrom* cptr;
char ch;
int n=0;
do
Manipal University Jaipur B2114 Page No.: 198
Object Oriented Programming – C++ Unit 8

{
cout<<”Enter data for book or cdrom(b/c)”;
cin>>ch;
if (ch==’b’)
{
bptr= new book;
bptr->getdata();
ptr[n++]=bptr;
}
else
{cptr=new cdrom;
cptr->getdata();
ptr[n++]=cptr;
}
cout<<” enter another (y/n)”;
cin>>ch;
}while (ch==’y’);
for(int j=0;j<n;j++)
ptr[j]->putdata();
getch();
}.
2. Polymorphism means the same content but different forms. The origin of
the word polymorphism comes from two Greek words’ poly (many) and
morphos (form), together meaning multiform. In C++, by the concept of
polymorphism the same program code can call different functions of
different classes. Refer section 8.2 for more details.
3. There are two levels at which polymorphism can be achieved. These
are:
Compile time polymorphism - It is achieved through function overloading
and operator overloading Run-time polymorphism – This type of
polymorphism is achieved through virtual functions. Refer section 8.3
for more details.
4. In C++ when a function has multiple declarations of the same function
name in the same scope, it is called function overloading. These
declarations differ in the type and number of arguments in the argument
list. Refer section 8.4 for more details.

Manipal University Jaipur B2114 Page No.: 199


Object Oriented Programming – C++ Unit 8

5. Virtual means to appear like something while in reality it is something


else. Virtual function is a member function that you expect to be
redefined in derived classes. When you refer to a derived class object
using a pointer or a reference to the base class, you can call a virtual
function for that object and execute the derived class's version of the
function. Refer section 8.5 for more details.
6. Most of the times, the idea behind declaring a function (in the base
class) virtual, is to stop its execution. The base class function is used
very rarely to perform any task. Its role is only to serve as a placeholder.
Then the question may arise as to why it is required to define (in detail)
virtual functions? This leads to the idea of pure virtual functions or do-
nothing functions. A pure virtual function is virtual function with no
definition. Refer section 8.5 for more details.
7. Output is :
Rectangle class area
Triangle class area.
8. Output is :
ABC.
9. In both the techniques same function name is used. But different
parameters are passed in function overloading whereas the number of
parameters passed to the function are same in function overriding.
Refer section 8.6 for more details.

References:
 Oriented Programming With C++, by Subhash K U. Pearson Education
India.
 Data Structures and Algorithms, first edition, by A. A. Puntambekar.
Technical Publications.

Manipal University Jaipur B2114 Page No.: 200


Object Oriented Programming – C++ Unit 9

Unit 9 Files and Streams


Structure:
9.1 Introduction
Objectives
9.2 Introduction to files and streams
9.3 Character and String input and output to files
9.4 Command Line Arguments and Printer Output
9.5 Preprocessor Directives
The #define Preprocessor
Conditional Compilation
Predefined C++ Macros
9.6 Summary
9.7 Terminal Questions
9.8 Answers

9.1 Introduction
In the previous unit you studied about polymorphism and its types. You also
studied about function overloading and its types. In this unit you are going to
learn the ways to handle files in C++ and to process input and output
operations, and get an idea of preprocessor directives in C++. You are also
going to study the procedure to pass arguments from command line prompt.
You are already using files to store your program. The files can also be
used to store input for a program or to receive output from a program.
These files used for program input-output are the same files that you used
to store your programs. The file streams allow you to write programs that
handle file and keyboard inputs as well as file and screen outputs in a
unified way. In C++, fstream class is used to perform file processing. Unlike
the FILE structure, fstream is a complete C++ class with constructors, a
destructor and overloaded operators. To perform file processing, you can
declare an instance of an fstream object. If you do not yet know the name of
the file you want to process, you can use the default constructor.

Objectives:
After studying this unit, you should be able to:
 explain the way file input-output is handled in C++
 describe the read-and-write operation of string content to a file
 describe the methods to transfer output to printer
 discuss preprocessor directives

Manipal University Jaipur B2114 Page No.: 201


Object Oriented Programming – C++ Unit 9

9.2 Introduction to files and streams in C++


File input and output in C++ is completely handled by predefined file and
stream-related classes. The cin and cout statements, which we were using
for transfer of input from keyboard, and that of output to display screen, are
also predefined objects of these predefined stream classes.
The declarations of these stream classes are contained in the header file
‘iostream.h’ which you have been using in your programs. Similarly, the
declarations for classes used for disk I/O is provided in header file fstream.h.
Let us first understand what ‘a stream’ is. A stream is a flow of characters. If
the flow is into your program, then it is called ‘input stream’, and if the flow is
out of your program, then it is called ‘output stream’. Your program will take
input from the keyboard if input stream flows from the keyboard. And the
program will take output from the file if the input stream flows from a file.
Similarly, an output stream can go to the screen or to a file. You have
already been using streams in your programs. The cin is the inuput stream
connected to the keyboard, and the cout is the output stream connected to
the screen.
The stream classes are organized in a hierarchical manner. But an overview
of how they are organized will provide an excellent example of inheritance,
and will help us understand files and streams in a better way.
The following figure 9.1 shows a portion of stream class hierarchy in C++
which we will be using in our programs in this unit.

Figure 9.1: Stream classes in C++

Manipal University Jaipur B2114 Page No.: 202


Object Oriented Programming – C++ Unit 9

As you can see in figure 9.1, all the stream classes are inherited from the
ios class. It provides support for formatted and unformatted I/O operations.
It contains many constants and member functions that can be used by all
other input and output classes. All constants and functions that are
necessary for handling input and output operations are present in this ios
class. istream (input stream) class is derived from ios class, and all the
necessary functions for input handling are present in it. It provides facilities
for formatted and unformatted input. Besides, it contains pointer to a buffer
object, i.e. streambuf object. Some functions that are defined in this class
are get(), getline(), read() and overload extraction operators (>>).
ostream (output stream) class is also derived from ios class, and performs
all types of output related functions like put(), write(). It provides facilities for
formatted output. The overload insertion operator (<<) is defined in this
class.
iostream (input/output) stream class inherits the properties of istream and
ostream class through multiple inheritance, and hence, contains all the input
and output functions.
streambuf class provides the interface to physical devices through buffers.
Three classes - istream_withassign, ostream_withassign, iostream with
assign are inherited from istream, ostream, iostream respectively, which add
assignment operators to these classes. cout is a predefined object of the
ostream_withassign class. cin is an object of the istream_withassign class.
The ifstream class is used for input files and it is inherited from classes
istream and fstreambase. Similarly, class ostream is used for output files,
and is derived from classes- ostream and fstreambase. Files used for both
input output operations are inherited from the class - fstream. The class
fstream is inherited from both iostream and fstreambase. The classes
fstream, ifstream and ofstream are declared in the fstream.h header file.
The file fstream.h also includes iostream.h, so the programs using fstream.h
need not explicitly include iostream.h.
Self Assessment Questions
1. cin is a predefined object of _____________ class.
2. cout is a predefined object of ____________ class.
3. All the stream classes are inherited from _________class.

Manipal University Jaipur B2114 Page No.: 203


Object Oriented Programming – C++ Unit 9

9.3 Character and String input and output to files


In this section you will study the ways to read characters and strings from
the text file, and to write it to the text file with the help of a few programs.
To write characters to a file, you need to create an object of ofstream class.
The put() function should be used with the object to write the data to the file.
The put() function writes one character at a time. The syntax of the put()
function is as follows:
objectname.put(character variable)
The following program shows the use of put() function:
#include<fstream.h>
# include<string.h>
void main()
{
ofstream outfile(“test.txt”);
char str[ ]=“hello world”;
for (int j=0;j<strlen(str);j++)
outfile.put(str[j]);
}
In the program shown above, the object named ‘outfile of ofstream class’ is
created. The constructor of the ofstream class is invoked and the object
outfile is assigned the text file named ‘test.txt’. In the output directory,
specified in the compiler, a text file is created. And if there exists a file with
the same name, then the file is overwritten. The contents of the string str is
written to the file test.txt. It is to be noted that we have included fstream.h
header file. Since the insertion operator (<<) is overloaded in the ostream
class (of stream is derived from ostream), it can be used along with the
ofstream object to write text directly to the file. The following program shows
that:
#include<fstream.h>
void main()
{
ofstream outfile(“example.txt”);

Manipal University Jaipur B2114 Page No.: 204


Object Oriented Programming – C++ Unit 9

outfile<<“Welcome\n”;
outfile<<“See you\n”;
}
You need to create an object of ifstream class to read data from file. To read
the data from the file, you have to use the function ‘get()’ or ‘getline()’. The
‘get()’ function also reads one character at a time. The following is the
syntax of the ‘get()’ function.
objectname.get(character variable)
Here the objectname is an object of ifstream class and the character to be
read from the file is stored in a variable.
The following is the program to show how to read character from file. The
program shown below reads the contents of the file character by character,
and displays the character on computer screen.
#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char ch;
clrscr();
while (infile) // infile becomes 0 when eof condition is reached
{infile.get(ch);
cout << ch;}
getch();}
You can observe in the above program that the end of file (eof) condition is
checked using the object name. You can also use eof() function to check
this condition. The eof() function returns non-zero value when an end of file
is encountered, and returns zero when reading the file.
The getline() function is also used to read contents from a file. But unlike
get() function it reads the contents line by line. The program below shows
the use of getline function.

Manipal University Jaipur B2114 Page No.: 205


Object Oriented Programming – C++ Unit 9

#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char buffer[80];
clrscr();
while (!infile.eof()) //returns nonzero value when eof condition is reached
{infile.getline(buffer,80);
cout << buffer;}
getch();}
The extraction operator (>>) can be used with ifstream object to read the
text as this operator is overloaded in the istream class. (ifstream is derived
from istream). However, it reads one word at a time. The following program
shows the same:
#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
char buffer[25];
clrscr();
while (infile) //infile becomes 0 when eof condition is reached
{infile>>buffer;
cout << buffer;
}
getch();
}
In these programs, while reading contents from the file, we have presumed
that the files are existing on the disk. But it would be a good practice if you
apply a check to find whether the file to be read exists on the disk or not.

Manipal University Jaipur B2114 Page No.: 206


Object Oriented Programming – C++ Unit 9

Many such status checks are contained in ios class. In the program shown
below, the check applied reports an error if the file doesn’t exist.
#include<fstream.h>
#include <conio.h>
void main()
{
ifstream infile("test.txt");
if (!infile) // check for error while opening the file
cout<<”Cannot open file”;
else
{
char buffer[25];
clrscr();
while (infile) //infile becomes 0 when eof condition is reached
{infile>>buffer;
cout << buffer;}
}
getch();}

Self Assessment Questions:


4. To write characters to a file, you need to create an object of
__________ class.
5. You need to create an object of ________ class to read data from file.
6. The put() function writes _____ character at a time to the files.
7. The ________ function reads contents from a file, line by line.
8. The _______ function returns non-zero value when an end of file is
encountered.

9.4 Command Line Arguments and Printer Output


You have already studied that when a program is compiled and linked, then
an executable file is produced by the compiler. And when the program runs,
the execution of programs begins from the main() function. Till now we have
declared the main function either as void main() or as int main(). This

Manipal University Jaipur B2114 Page No.: 207


Object Oriented Programming – C++ Unit 9

version of main doesn’t take any arguments. But many a time, programs
need some kind of input to work with. For example, you are writing a code to
count the number of words in a text file.
The user has to have some way of telling the program which file to open. To
do this, you may take this approach:
int main()
{
using namespace std;
cout << "Enter the name of the file: ";
char strFilename[255];
cin >> strFilename; // open file and process it
}
The major problem associated with this approach is that every time the file
runs, the program waits for the user to enter the input. It indicates that
execution of the program cannot be automated easily. For example, if you
want to execute this program on 600 files per week, then the program will
not proceed. Instead, it will wait until you enter the name of the file every
time it is executed.
Command line arguments
For programs that have minimal and/or optional inputs, command line
arguments offer a great way to make programs more modular. The optional
string arguments that are given by the user to a program during execution
are known as ‘command line arguments’. The operating system passes
these arguments to the program, and the program uses them as input.
Programs are normally run by invoking them by name. To run a program
you have to type the name of the program on the command line. For
example, to run the executable file “WordCount” that is located in the root
directory of the C:\ drive on a Windows machine, you could type:
C:\\>WordCount
To pass the command line arguments to the program ‘WordCount’, you
have to list the command line arguments after the executable name. The
example is shown below:
C:\\>WordCount Myfile.txt

Manipal University Jaipur B2114 Page No.: 208


Object Oriented Programming – C++ Unit 9

You can see in the above statement that when the program named
‘WordCount’ is executed, Myfile.txt will be passed to it as a command line
argument. It is possible for a program to have a number of command line
arguments. For example:
C:\\>WordCount Myfile.txt Myotherfile.txt
This also works for other command line operating systems, such as Linux
(though your prompt and directory structure will undoubtedly vary).
If a program is run from an IDE (Integrated Development Environment) then
some way should be provided by IDE to enter command line arguments. For
example, in Microsoft Visual Studio 2005, right click on your project in the
solution explorer, and then choose properties. Open the “Configuration
Properties” tree element, and choose “Debugging”. In the right pane, there
is a line called “Command Arguments”. You can enter your command line
arguments there for testing, and they will be automatically passed to your
program when you run it.
Now you have already studied the way to provide command line arguments
to a program. The next thing you have to study is to access them from
within our C++ program. To achieve this task, we use some other form of
the main program that we have used in our programs till now. We have to
pass two arguments in the main function i.e. argc and argv. The names of
the arguments are by convention. The example is as follows:
int main(int argc, char *argv[])
argc is an argument containing the number of arguments passed to the
program. argc will always be at least 1, because the first argument is always
the name of the program itself! The value of argc will be incremented by 1
each time the user provides the command line argument. Each command
line argument the user provides will cause argc to increase by 1.
The actual arguments are stored in argv. Although the declaration of argv
looks intimidating, argv is really just an array of C-style strings. The length of
this array is argc. Let’s write a short program to print the value of all the
command line parameters:

Manipal University Jaipur B2114 Page No.: 209


Object Oriented Programming – C++ Unit 9

#include <iostream>
int main(int argc, char *argv[])
{
using namespace std;
cout << "There are " << argc << " arguments:" << endl;
// Loop through each argument and print its number and value
for (int nArg=0; nArg < argc; nArg++)
cout << nArg << " " << argv[nArg] << endl;
return 0;
}

If we provide the following command line argument - “Myfile.txt” to the


program, the output will be:
There are 3 arguments:
C:\\WordCount
Myfile.txt
100
The name of the running program is always the argument 0. The two
command-line parameters are argument 1 and 3. Going back to our
previous example, let us go ahead and partially write WordCount so that it
uses command line arguments instead of asking the user for input.
Command line arguments are useful whenever we want to pass arguments
while the program is executing. The following is one more example which
shows the implementation of command line arguments, and simply displays
them.
//comline.cpp
# include <iostream.h>
void main(int argc, char* argv[])
{
cout<<endl<<”argc= ”<<argc;
for (int j=0;j<argc;j++)

Manipal University Jaipur B2114 Page No.: 210


Object Oriented Programming – C++ Unit 9

cout<<endl<<”Argument ”<<j<<”= ”<<argv[j];


}
If you invoke the above program with the statement
C:/tc> ABC EFG PQR XYZ
Then the output will be as follows
argc= 4
Argument0= c:/tc/comline.exe
Argument1= ABC
Argument2= EFG
Argument3= PQR
You can see in the program above that the number of the arguments
including the name of the file is contained in argc variable. The strings
passed to the program along with the path of the executable program is
contained in the argv variable. You can refer them by their index number.
Now we will study how data can be sent to the printer. It is similar to sending
data to a disk file seen in the last section. The program uses filenames
predefined in DOS for various hardware devices. PRN or LPT1 is the
filename for the printer which is connected to the first parallel port. LPT2,
LPT3 and so on can be used if the printer is connected to the second, the
third parallel ports respectively.
The following program prints a test message to the printer
//printtest.cpp
# include<fstream.h>
void main()
{ ofstream prnfile(“PRN”);
prnfile<<”This is a test print page”;
}
As you can see in the program above, an ofstram class object has been
created and the printer file name has been associated with it and the
contents have been saved to the object. As you can see, the code and the
way we direct the contents to a stream do not differ. Whether it is sending

Manipal University Jaipur B2114 Page No.: 211


Object Oriented Programming – C++ Unit 9

contents to display screen or printer or disk file, the syntax remains the
same. That is the beauty of stream class organization hierarchy.
Self Assessment Questions
9. The optional string arguments that are given by the user to a program
during execution are known as ____________.
10. _______ variable contains the number of arguments passed to the
program.
11. _______ variable contains the actual arguments passed to the program.

9.5 Preprocessor Directives


There are some instructions given to the compiler to preprocess the
information before the actual compilation begins. These instructions are
known as preprocessor directives. All preprocessor directives begin with #,
and only white-space characters may appear before a preprocessor
directive on a line. The preprocessor directives do not end with semicolon.
You are familiar with the #include directive. The purpose of this macro is to
include a header file into the source file.
So many directives are supported by C++: #include, #define, #if, #else, #line,
etc are only a few to name. Let us study a few important directives in detail.

9.5.1 The #define Preprocessor


The symbolic constants are created by #define directive. These symbolic
constants are known as macros. The syntax to declare macros are:
#define macro-name replacement-text
When this statement appears in a file, then the macro name in the program
is replaced with the replacement text before the program is compiled. For
example:
#include <iostream.h>
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}

Manipal University Jaipur B2114 Page No.: 212


Object Oriented Programming – C++ Unit 9

Now let us preprocess this code to see the result, assuming that we have
the source code file. We will compile this file with –E option and save the
result in result.p file. Now, if you check the result.p file, you will see that it
has lots of information, and at the bottom of the file, you will find the value
replaced as follows:
$gcc -E test.cpp > test.p
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
Function-Like Macros
You can use #define to define a macro which will take argument as follows:
#include <iostream.h>
#define MIN(a,b) ( ((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
cout <<"The minimum is " << MIN(i, j) << endl;
return 0;
}
The output of the above program will be:
The minimum is 30
9.5.2 Conditional Compilation
C++ provides the facility to compile the selective portions of our program’s
source code. This can be performed by using some directives. This
procedure is known as conditional compilation.
The conditional preprocessor construct is much like the if selection structure.
Consider the following preprocessor code:
#ifndef NULL
#define NULL 0

Manipal University Jaipur B2114 Page No.: 213


Object Oriented Programming – C++ Unit 9

#endif
You can compile a program for debugging purpose, and can turn
‘debugging’ on or off using a single macro as follows:
#ifdef DEBUG
cerr <<"Variable x = " << x << endl;
#endif
This causes the cerr statement to be compiled in the program if the
symbolic constant DEBUG has been defined before directive #ifdef DEBUG.
You can use #if 0 statement to comment out a portion of the program as
follows:
#if 0
code prevented from compiling
#endif
The following example illustrates the above concept:
#include <iostream.h>
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* This is commented part */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;

Manipal University Jaipur B2114 Page No.: 214


Object Oriented Programming – C++ Unit 9

#endif
return 0;
}
The output of the above program will be:
Trace: Inside main function
The minimum is 30
Trace: Coming out of main function
9.5.3 Predefined C++ Macros
C++ provides a number of predefined macros. Table 9.1 shows the
predefined macros provided by C++.
Table 9.1: Predefined macros
Macro Description
An integer that gives the current line number of the program when
_LINE__
it is being compiled.
A string that gives the current file name of the program when it is
__FILE__
being compiled.
This contains a string of the form month/day/year that is the date
__DATE__
of the translation of the source file into object code.
This contains a string of the form ‘hour:minute:second’ that is the
__TIME__
time at which the program was compiled.

The example to show the usage of the above macros is as follows:


#include <iostream>
using namespace std;
int main ()
{
cout << "Value of __LINE__ : " << __LINE__ << endl;
cout << "Value of __FILE__ : " << __FILE__ << endl;
cout << "Value of __DATE__ : " << __DATE__ << endl;
cout << "Value of __TIME__ : " << __TIME__ << endl;
return 0;
}

Manipal University Jaipur B2114 Page No.: 215


Object Oriented Programming – C++ Unit 9

The output of the above program is as follows:


Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 01 2015
Value of __TIME__ : 18:52:48

Self Assessment Questions


12. ____________are the instructions given to the compiler to preprocess
the information before actual compilation begins.
13. The symbolic constants are created by #define directive, and are
known as macros. (True/False).
14. _______ macro is a string that gives the current file name of the
program when it is being compiled.

9.6 Summary
 A stream is a flow of characters. If the flow is into your program then it is
called input stream, and if the flow is out of your program then it is called
output stream.
 The stream classes are organized in a hierarchical manner.
 ofstram class is used to write characters to a file.
 If stream class is used to read data from a file.
 The optional string arguments that are given during execution by the user
to a program are known as command line arguments.
 argc is an interger type argument containing the number of arguments
passed to the program. argv contains the actual arguments passed to the
program.
 There are some instructions given to the compiler to preprocess the
information before actual compilation begins. These instructions are
known as preprocessor directives. All preprocessor directives begin with
#, and only white-space characters may appear before a preprocessor
directive on a line.
 The symbolic constants are created by #define directive. These symbolic
constants are known as macros.

Manipal University Jaipur B2114 Page No.: 216


Object Oriented Programming – C++ Unit 9

 C++ provides the facility to compile the selective portions of our


program’s source code. This can be performed by using some directives.
This procedure is known as conditional compilation.

9.7 Terminal Questions


1. Write a program that opens a text file named sample.txt and then prints
the contents to the printer.
2. Write a program that will be called mtype.cpp, which imitates the type
command of the DOS. The user should be able to specify the name of
the text file along with mtype which is read, and the contents are
displayed on the screen.
3. Define streams. List and explain all the stream classes in C++.
4. Explain how to use command line arguments with the help of an
example.
5. Write a note on ‘preprocessor directives’.

9.8 Answers
Self Assessment Questions
1. istream_withassign
2. ostream_withassign
3. ios
4. ofstream
5. ifstream
6. one
7. getline()
8. eof()
9. command line arguments
10. argc
11. argv
12. Preprocessor directives
13. True
14. __FILE__

Manipal University Jaipur B2114 Page No.: 217


Object Oriented Programming – C++ Unit 9

Terminal Questions
1. //file2prn.cpp
# include<fstream.h>
void main()
{
char ch;
ifstream infile;
infile.open("sample.txt");
ofstream outfile;
outfile.open("PRN");
while(infile.get(ch))
{ outfile.put(ch);
}
}
2. //mytype.cpp
# include<fstream.h>
# include<process.h>
void main(int argc, char* argv[])
{ if (argc!=2)
{ cerr<<“\nFormat: mytype filename”;
exit(-1);
}
char ch;
ifstream infile;
infile.open(arg[1]);
if (!infile)
{ cerr<<“cannot open”<<argv[1];
exit(-1);
}
while(infile)
{infile.get(ch);
cout<<ch;}
}

Manipal University Jaipur B2114 Page No.: 218


Object Oriented Programming – C++ Unit 9

3. A stream is a flow of characters. If the flow is into your program then it is


called input stream, and if the flow is out of your program, then it is
called output stream. The stream classes are organized in a hierarchical
manner. For more details refer section 9.2.
4. For programs that have minimal and/or optional inputs, command line
arguments offer a great way to make programs more modular. The
optional string arguments that are given by the user to a program during
execution are known as command line arguments. For more details refer
section 9.4.
5. There are some instructions given to the compiler to preprocess the
information before the actual compilation begins. These instructions are
known as preprocessor directives. All preprocessor directives begin with
#, and only white-space characters may appear before a preprocessor
directive on a line. For more details refer section 9.5.

References:
 Object Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
 Problem Solving with C++, 6/e, By Savitch, Pearson Education India.
 C++ for Engineers and Scientists, By Gary Bronson, Cengage Learning.
 http://enggedu.com/
 http://www.tutorialspoint.com

Manipal University Jaipur B2114 Page No.: 219


Object Oriented Programming – C++ Unit 10

Unit 10 Standard Input and Output


Structure:
10.1 Introduction
Objectives
10.2 Understanding the C++ iostream hierarchy
Standard Input/Output Stream Library
Organization
Elements of the iostream Library
10.3 Basic Programming using Streams
Basic Stream Concepts
Your Very First Program
Reading a File
10.4 Formatted console I/O Operations
ios Class Functions and Flags
Managing output with Manipulators
10.5 Summary
10.6 Terminal Questions
10.7 Answers

10.1 Introduction
In the previous unit you studied about files, streams, command line
arguments and preprocessor directives. In this unit you are going to study
I/O stream hierarchy and simple programs using these streams. You are
also going to learn the methods to format the output of the programs
In C++, I/O is done with "streams." An input stream such as cin is a source
of data that can be read into variables. An output stream such as cout is a
place where data can be sent for display, storage, or communication. A file
is a collection of data saved on a disk drive. Data in a file differs from data in
variables because a file can exist before the program is run and can persist
after the program ends. To read data from a file or to save data in a file, a
program just has to use the right type of stream.
Objectives:
After studying this unit you should be able to:
 explain C++ iostream library and its organization
 describe programming using I/O streams

Manipal University Jaipur B2114 Page No.: 220


Object Oriented Programming – C++ Unit 10

 explain ios class functions and flags


 discuss manipulators

10.2 Understanding the C++ iostream Library


The iostream library is an object-oriented library that provides input and
output functionality using streams.
10.2.1 Standard Input/Output Stream Library
A stream is sequence of bytes. It is a continuous flow of data elements that
are transmitted or intended for transmission in a defined format. It works
either as a source from where the data can be obtained or as a destination
for the output sent. Source stream that provides data to the program is
called input stream. Destination stream that receives output from program is
called output stream. A stream can basically be represented as a source or
destination of characters of indefinite length. Figure 10.1 depicts the I/O
stream library structure.

Figure 10.1: Stream library

To operate with streams we have at our disposal the standard iostream


library which provides us the following elements:
 Basic class templates – The base of the iostream library is the
hierarchy of class templates. Most of the functionality of the library in the
type independent way is provided by the class templates. There are two
template parameters in class templates i.e. the char type(charT) and
traits. The char type describes the type of elements to be manipulated
and traits parameter provides additional characteristics specific for that
type of elements. In the class hierarchy the class templates have the

Manipal University Jaipur B2114 Page No.: 221


Object Oriented Programming – C++ Unit 10

same name as their char type instantiations but they have the prefix
basic in their names. For example, the class template which istream is
instantiated from is called basic_istream, the one from which fstream is
instantiated is called basic_fstream, and so on. The ios_base is an
exception which is by itself is type-independent.
 Class template instantiations – The library contains two standard sets
of instantiations of the complete iostream class template hierarchy i.e.
narrow oriented which manipulates the elements of char type and wide
oriented that manipulates the wchar_t type elements. The few narrow
oriented classes are ios, istream and ofstream. The names of narrow
oriented classes and relationship amongst them is shown in figure 10.1.
The wide oriented instantiation classes has the same naming
convention as narrow oriented instantiation only difference is that in
wide oriented instantiation the name of classes and objects are prefixed
with character ‘w’. For example wios, wistream, wostream.
 Standard objects – Many objects that performs standard input and
output operations are declared in <iostream> library. These are of two
types i.e. narrow oriented objects and wide oriented objects. Example of
narrow oriented objects are – cin, cout, cerr and clog. And wide oriented
objects are declared as win, wout, wcerr and wclog.
 Types – The iostream classes barely use fundamental types on their
member's prototypes. They generally use defined types that depend on
the traits used in their instantiation. For the default char and wchar_t
instantiations, types - streampos, streamoff and streamsize are used to
represent positions, offsets and sizes, respectively.
 Manipulators – The global functions that are used in conjunction with
insertion (<<) and extraction (>>) operators performed on iostream
objects are known as manipulators. The formatting settings and
properties of streams are modified by manipulators. Examples of
manipulators are- endl, hex and scientific.
10.2.2 Organization
The library and its hierarchy of classes are split in different files:
 As you have observed in the programs that we don’t include <ios>,
<istream>, <ostream>, <streambuf> and <iosfwd> files directly in the

Manipal University Jaipur B2114 Page No.: 222


Object Oriented Programming – C++ Unit 10

programs. They describe the base classes of the hierarchy and are
automatically included by other header files of the library that contain
derived classes.
 <iostream> It contains the declarations of the objects that
performstandard input and output operations(including cin and cout).
<fstream> the file stream classes (like the template basic_ifstream or
the class ofstream) as well as the internal buffer objects used with these
(basic_filebuf) are defined in this file. These classes manipulate the files
using streams.
 <sstream>: The classes which are defined in file manipulates string
objects as if they were streams.
 <iomanip> Declares some standard manipulators with parameters to be
used with extraction and insertion operators to modify internal flags and
formatting options.
10.2.3 Elements of the iostream Library
Classes

ios_base Base class with type-independent members for the


standard stream classes
ios_base Base class with type-dependent members for the
standard stream classes
istream Input stream
ostream Output Stream
iostream Input/Output Stream
ifstream Input file stream class
ofstream Output file stream
fstream Input/output file stream class
istringstream Input string stream class
ostringstream Output string stream class
stringstream Input/output string stream class
tsreambuf Base buffer class for streams
filebuf File stream buffer
stringbuf String stream buffer

Manipal University Jaipur B2114 Page No.: 223


Object Oriented Programming – C++ Unit 10

Objects
Cin Standard input stream
Cout Standard output stream
Cerr Standard output stream for errors
Clog Standard output stream for logging

Types
Fpos Stream position class template
Streamoff Stream offset type
Streampos Stream position type
Streamsize Stream size type

Manipulators
Boolalpha Alphanumerical bool values
Dec Use decimal base
Endl Insert newline and flush
Ends Insert null character
Fixed Use fixed-point notation
Flush Flush stream buffer
Hex Use hexadecimal base
Internal Adjust field by inserting characters at an internal
position
Left Adjust output to the left
Noboolalpha No alphanumerical bool values
Noshowbase Do not show numerical base prefixes
Noshowpoint Do not show decimal point
Noshowpos Do not show positive signs
Noskipws Do not skip whitespaces
Nounitbuf Do not force flushes after insertions
Nouppercase Do not generate upper case letters
Oct Use octal base
Resetiosflags Reset format flags
Right Adjust output to the right
Scientific Use scientific notation
Setbase Set basefield flag
Setfill Set fill character

B2114 Page No.: 224


Object Oriented Programming – C++ Unit 10

Setiosflags Set format flags


Setprecision Set decimal precision
Setw Set field width
Showbase Show numerical base prefixes
Showpoint Show decimal point
Showpos Show positive signs
Skipws Skip whitespaces
Unitbuf Flush buffer after insertions
Uppercase Generate upper-case letters
Ws Extract whitespaces

Self Assessment Questions


1. The _______ library is an object-oriented library that provides input and
output functionality using streams.
2. A _________ continuous flow of data elements that are transmitted or
intended for transmission in a defined format.
3. The base of the iostream library is the hierarchy of _________.
4. clog stands for____________.

10.3 Basic Programming using Streams


10.3.1 Basic Stream Concepts
In C++, the file stream classes are designed with the idea that a file should
simply be viewed as a stream or array of uninterpreted bytes. For
convenience, the "array" of bytes stored in a file is indexed from zero to len-
1, where len is the total number of bytes in the entire file.
Each open file has two "positions" associated with it:
 The current reading position, which is the index of the next byte that will
be read from the file. This is called the "get pointer" since it points to the
next character that the basic get method will return.
 The current writing position, which is the index of the byte location
where the next output byte will be placed. This is called the "put pointer"
since it points to the location where the basic put method will place its
parameter.
These two file positions are independent, and either can point anywhere
at all in the file.
Manipal University Jaipur B2114 Page No.: 225
Object Oriented Programming – C++ Unit 10

Creating Streams
The streams need to be created before they are used in the programs. The
statements to create streams are similar to the variable declaration. These
statements are written at the top of the program with variable declaration.
The example to create a stream is shown below:
ifstream in_stream;
ofstream out_stream;
Before we can use an input or output stream in a program, we must create
it. Statements to create streams look like variable declarations, and are
usually placed at the top of programs or function implementations along with
the variable declarations. So for example the statements
ifstream in_stream; This statement creates a stream called "in_stream"
belonging to the class (like type) "ifstream" (input-file-stream).
ofstream out_stream;- This statement creates a stream called "out_stream"
belonging to the class "ofstream" (output-file-stream).
However, the analogy between streams and ordinary variables (of type "int",
"char", etc.) can't be taken too far. We cannot, for example, use simple
assignment statements with streams (e.g. we can't just write "in_stream1 =
in_stream2").
Connecting and Disconnecting Streams to Files
Consider that a file named “test.txt” exists shown in figure 10.2. The
diagrammatic representation of this file is shown below:

Figure 10.2: test.txt

Having created a stream, we can connect it to a file using the member


function "open(...)". The function "open(...)" has a different effect for
ifstreams than for ofstreams (i.e. the function is polymorphic).
To connect the ifstream "in_stream" to the file "test.txt", we use the following
statement:
in_stream.open("Test.txt");
Manipal University Jaipur B2114 Page No.: 226
Object Oriented Programming – C++ Unit 10

This connects "in_stream" to the beginning of "test.txt". Diagrammatically,


we end up in the following situation as shown in figure 10.3.
(program)

Figure 10.3: opening input stream

To connect the ofstream "out_stream" to the file "test.txt", we use an


analogous statement:
out_stream.open("Test.txt");
Although this connects "out_stream" to "test.txt", it also deletes the previous
contents of the file, ready for new input. Diagrammatically, we end up as
shown in figure 10.4.
(program)

Figure 10.4: opening output stream

To disconnect, connect the ifstream "in_stream" to whatever file it is


connected to, we write:
in_stream.close();

Manipal University Jaipur B2114 Page No.: 227


Object Oriented Programming – C++ Unit 10

Diagrammatically, the situation changes from that of Figure 10.3 to figure


10.5:
(program)

Figure. 10.5: closing an input stream

The statement:
out_stream.close();
has a similar effect, but in addition, the system will "clean up" by adding an
"end-of-file" marker at the end of the file. Thus, if no data has been output to
"Test.txt" since "out_stream" was connected to it, we change from the
situation in Figure 10.4 to figure 10.6.
(program)

Figure 10.6: closing an output stream

In this case, the file "Test.txt" still exists, but is empty.

Manipal University Jaipur B2114 Page No.: 228


Object Oriented Programming – C++ Unit 10

10.3.2 Your Very First Program


The first program, will create a file, and put some text into it.
#include <fstream>
using namespace std;
int main() {
ofstream SaveFile("cpp-home.txt");
SaveFile << "Hello World, from www.cpp-home.com and Loobian!";
SaveFile.close();
return 0;
}
The above program will create cpp-home.txt file and will write the sentence -
Hello World, from www.cpp-home.com and Loobian into it. The file named
cpp-home.txt will be created in the directory from where we execute the file
containing the program.
Here is what every line means:
#include <fstream>
You need to include this file in order to use C++’s functions for File I/O. In
this file, are declared several classes, including ifstream, ofstream and
fstream, which are all derived from istream and ostream.
ofstream SaveFile(“cpp-home.txt”);
 ofstream means “output file stream”. The handle for a stream to write in
a file is created by it of the handle. You can pick whatever you want.
 (“cpp-home.txt”); - It opens the file named cpp-home.txt. The file will be
created of it doesn’t already exist. This file is placed in the directory from
where we are executing the program. ofstream is a class. So, an object
of this class is created by the following statement -ofstream
SaveFile(“cpp-home.txt”);. Whatever arguments we have mentioned in
the brackets are passed to the constructor. So, to summarize: we create
an object from class ofstream, and we pass the name of the file we want
to create, as an argument to the class’ constructor.

Manipal University Jaipur B2114 Page No.: 229


Object Oriented Programming – C++ Unit 10

SaveFile << “Hello World, from www.cpp-home.com and Loobian!”;


This statement writes the text in cpp-home.txt file. As you already know that
SaveFile is a handle to the opened file stream. So, as you can see in
statement above you have to write the handle name, and write the text in
inverted commas after <<. Sometimes if it required to pass variable instead
of text then you should just pass it as a regular use of the cout <<. For
example, SaveFile << variablename;
SaveFile.close();
You should close the stream when you finish using it. The above statement
closes the stream. SaveFile is an object from class ofstream, and this class
(ofstream) has a function namd close that closes the stream. So, to close
the stream you need to write the name of the handle, dot and close(). Once
you have closed the file, you can’t access it anymore, until you open it
again.
That’s the simplest program, to write in a file.
10.3.3 Reading a File
You saw how to write into a file. Now, when we have cpp-home.txt, we will
read it, and display it on the screen. But let’s first look at one of the simplest
and a most effective technique.
#include <fstream.h>
void main()
{ //the program starts here
ifstream OpenFile("cpp-home.txt");
char ch;
while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}
OpenFile.close();
}

Manipal University Jaipur B2114 Page No.: 230


Object Oriented Programming – C++ Unit 10

You should already know what the first line is. Hence, we shall move to next
important statement.
ifstream OpenFile(“cpp-home.txt”);
ifstream means “input file stream”. In the previous program, it was ofstream,
which means “output file stream”. The previous program is to write a file,
that’s why it was “output”. But this program is to read from a file, that’s why it
is “input”. OpenFile is the object from class ifstream, which will handle the
input file stream. And in the inverted commas, is the name of the file to
open.
Note that there is nothing to check whether the file exists. This will be
covered in a short while.
char ch;
An explanation for this statement is redundant.
while(!OpenFile.eof())
As you have already studied, when the end of the file is encountered then
the function eof() returns a non-zero value. So we use a while loop that will
run until the end of file is encountered. So, we will get through the whole file,
so that we can read it.
OpenFile.get(ch);
OpenFile is the object from class ifstream. This class contains the get()
function. So, as long as we have an object we can use this function. The
get() function extracts a single character from the stream and returns it. In
the program shown above the get() function takes the variable name as
parameter in which the character which is read is placed. So, after calling
OpenFile.get(ch) it will read one character from the stream OpenFile, and
will put this character into the variable ch. This function if called second time
will read the next character. It will not read the same character again and
every time we loop, we read one character and put it into ch.
cout << ch;
Explanation for this statement is redundant.
OpenFile.close();
As we have opened the file stream, we need to close it. Use the close()
function, to close it. Just as in the previous program.
Manipal University Jaipur B2114 Page No.: 231
Object Oriented Programming – C++ Unit 10

When you compile and run this program, the output will be:
Hello World, from www.cpp-home.com and Loobian!
Self Assessment Questions
5. A_________ is a stream or array of uninterpreted bytes.
6. The statements to create streams are written at the top of the program
with variable declaration. (True/False).
7. The statement ifstream in_stream; creates a stream called "in_stream"
belonging to the class "ifstream". (True/False).

10.4 Formatted Console I/O Operations


C++ provides various console I/O functions for formatting the outputs.
Formatting means displaying the outputs in a readable and comprehensible
manner. Formatting of outputs can be achieved in two ways as mentioned
below:
1. Using ios class functions and flags
2. Using Manipulators
10.4.1 ios Class Fucntions and Flags
The ios class contains many member functions that would help us to format
the output in a number of ways. The most important ones among them are
shown in table 10.1 below:

Table 10.1: ios format functions


Function Task
width() It specifies the required field size for displaying an output value
precision() It specifies the number of digits to be displayed after the decimal
point of a float value
fill() It specifies a character that is used to fill the unused portion of a
field.
self() It specifies the format flags that can control the form of output
display(like left justification and right justification)
unself() It clears the flags specified

The special functions that can be included in I/O statements to alter the
format parameters of a stream are known as manipulators. Table 10.2
shows some of important manipulator functions that are used frequently.

Manipal University Jaipur B2114 Page No.: 232


Object Oriented Programming – C++ Unit 10

The header file iomapin should be included in the program to access these
manipulators.

Table 10.2: Manipulators


Manipulators Equivalent ios function
setw() width()
setprecision() precesion()
setfill() fill()
setiosflags() setf()
resetiosflags() unsetf()

In addition to these functions supported by the C++ library, it is possible to


create our own manipulator functions to provide any special output formats.
We will discuss, in this section, how to use the predefined formatting
functions and how to create new ones.
Now we will study ios format functions one by one
1. Defining field Width: width()
You can use width() function to define the width of a field necessary for
the output of an item. Because it is a member function, you have to use
an object to invoke it. The example is shown below:
cout.width(w);
Here w is the filed width(number of columns). The output will be printed
in the field of w characters wide at the right end of the filed. The width()
function can specify the field width for only one item i.e. the item that
follows immediately. It will revert back to the default after printing one
item
For example:
cout.width(5);
cout<<543<<12<<”\n”;
The result of the above statement will be:
5 4 3 1 2

Manipal University Jaipur B2114 Page No.: 233


Object Oriented Programming – C++ Unit 10

The value 543 is printed right-justified in the first five columns. The
specification width(5) does not retain the setting for printing the number
12. This can be improved as follows:
cout.width(5);
cout<<543;
cout.width(5);
cout<<12<<”\n”;
The result of the above statement will be:
5 4 3 1 2

2. Setting Precision: precision()


The floating numbers are printed with six digits after decimal point by
default. But you can also explicitly specify the number of digits to be
printed after decimal while printing floating point numbers. You can
achieve this by using precision member function. The syntax is as
follows:
cout.precision(d);
Here d is the number of digits to the right of the decimal point.
For example:
cout.precision(3);
cout<<sqrt(2)<<”\n”;
cout<<3.14159<<”\n”;
cout<<2.50032<<”\n”;
The output of the above statements will be:
1.141 (truncated)
2.142 (rounded to the nearest zeros)
2.5 (no trailing zeros)
We can set different values to different precision as follows:
cout.precision(3);
cout<<sqrt(2)<<”\n”;
cout.precision(5);
cout<<3.14159;<<”\n”;

Manipal University Jaipur B2114 Page No.: 234


Object Oriented Programming – C++ Unit 10

3. Filling and Padding: fill()


Many of the times we print the values using much larger field widths than
required by the values. And by default the unused spaces of field are
filled with white spaces. You can fill this unused portion of field by some
desired characters. It is used in the following form:
cout.fil(ch);
Here ch represents the character to used to fill the unused spaces. The
example is shown below:
cout.fill(‘*’);
cout.widht(10);
cout<<5250<<”\n”;
The result of the above statements will be:
* * * * * * 5 2 5 0

This kind of padding is used in the financial institutions like banks while
printing cheques so that one can change the amount easily.
4. Formatting Flags, Bit-fields and self()
You have studied that when the function width is used, the value is
printed right-justified by default in the field width created. But usually we
print the text left-justified. The self() function of ios class is used to
perform this task. The self function can be used as follows:
cout.self(arg1, arg2);
The arg1 is the formatting flags defined in the ios class. The formatting
flag specifies the format action required for the output. Another ios
constant, arg2, known as bit field specifies the group to which the
formatting flag belongs. The table 10.3 shows the bit fields, flags and
their format actions. There are three bit fields and each has a group of
format flags which are mutually exclusive. Examples:
cout.self(ios::left, ios::adjustfield);
cout.self(ios::scientific, ios::floatfield);
It should be noted that the first argument should be one of the group
members of the second argument.

Manipal University Jaipur B2114 Page No.: 235


Object Oriented Programming – C++ Unit 10

Table 10.3: Flags and bit fields for self() function


Format required Flag(arg1) Bit-field(arg2)
Left-justified output ios::left ios::adjustfield
Right-justified output ios::right ios::adjustfield
Padding after sign or base Ios::internal ios::adjustfield
Scientific notation ios::scientific ios::floatfield
Fixed point notation ios:fixed ios::floatfield
Decimal base ios::dec ios::basefield
Octal base ios::oct ios::basefield
Hexadecimal base ios::hex ios::basefield

Let us consider the following code:


cout.fill(‘*’);
cout.self(ios::left, ios::adjustfield);
cout.width(15);
cout<<”table 1”<<”\n”;
The output will be:
T A B L E 1 * * * * * * * *

5. Displaying trailing zeros and plus sign


If the following numbers 10.75, 25.00 and 15.50 are printed using field
width of eight positions, with two digits precision, then the output will be
as follows:
1 0 . 7 5
2 5
1 5 . 5
It is to be noted that the trailing zeros in the second and third items have
been truncated. But there are many situations in which we need to print
the trailing zeros like the list of prices of items, employees’ salary
statement. So the self() function with the flag ios::showpoint can be used
as a single argument to achieve this task. For example:
cout.self(ios::showpoint)

Manipal University Jaipur B2114 Page No.: 236


Object Oriented Programming – C++ Unit 10

This statement will print the trailing zeros and trailing decimal points.
Under default precision, the value 3.25 will be displayed as 3.250000 as
the default precision assumes a precision of six digits.
Similarly, we can print a plus sign before a positive nume3 using the
following statement:
cout.self(ios::showpos); //show + sign
For example consider the following statements:
cout.self(ios::showpint);
cout.self(ios::showpos);
cout.precision(3);
cout.slef(ios::fixed, ios::floatfield);
cout.self(ios::internal, ios::adjustfield);
cout.width(10);
cout<<275.5<<”\n”;
The output of the above statements will be:
+ 2 7 5 . 5 0 0

10.4.2 Managing output with Manipulators


Manipulators are the functions which are used to manipulate the output
formats and are provided in header file iomapin. They provide the same
features as that of the ios member functions and flags. The most commonly
used manipulators are shown in table 10.4 below. Their meaning and
equivalents are also shown in the table. You have to include the file iomapin
in the program to access these manipulators.
Table 10.4: Manipulators and their meanings
Manipulator Meaning Equivalent
setw(int w) Set the field width to w width()
setprecision(int d) Set the floating point precision to d precision()
setfill(int c) Set the fill character to c fill()
setiosflags(long f) Set the format flag f setf()
resetiosflags(long f) Clear the flag specified by f. unsetf()
endl Insert new line and flush the stream “\n”

Manipal University Jaipur B2114 Page No.: 237


Object Oriented Programming – C++ Unit 10

Some examples of manipulators are as follows:


cout << setw(10) << 12345;
The above statement prints the value 12345 right-justified in a field width of
10 characters. To make the output left-justified, the statement can be
modified as follows:
cout << setw(10) << setiosflags(ios::left) << 12345;
We can format two or more outputs by one statement. For example:
cout << setw(5) << setprecision(2) << 1.2345 << setw(10) <<
setprecision(4) << sqrt(2) << setw(15) << setiosflags(ios::scientific) <<
sqrt(3) << endl;
The above statement will print all the three values in one line with the field
size 5, 10 and 15 respectively. You can see that each output is controlled by
different sets of format specifications.
It is possible to jointly use the manipulators and the ios functions in a
program. The following segment of code is valid:
cout.self(ios::showpoint);
cout.self(ios::showpos);
cout << setprecision(4);
cout << setiosflags(ios::scientific);
cout<<setw(10) << 123.45678;
The difference in the way manipulators are implemented as compared to the
ios member functions is that the ios function returns previous format state
which can be used later, if necessary. Whereas, the manipulator does not
return the previous format state. If you want to save the old format states,
you should use trhe ios member fucntions rather than the manipulators.
Example: cout.precision(2); //previous state
int p=cout.precision(4); //current state
When we execute the above statements, it is observed that p will hold the
value of 2(previous state) and the new format state will be 4. The previous
format state can be restored as follows:
cout.precision(p); //p=2

Manipal University Jaipur B2114 Page No.: 238


Object Oriented Programming – C++ Unit 10

Self Assessment Questions


8. Formatting of outputs can be achieved in two ways these are
__________ and ___________.
9. The _________ is used function to define the width of a field necessary
for the output of an item.
10. _________ are the functions which are used to manipulate the output
formats and are provided in header file ________.
11. ________ function specifies a character that is used to fill the unused
portion of a field.
12. The resetios flags(long f) clears the flag specified by f. (True/False).

10.5 Summary
 A stream is a sequence of bytes. It is a continuous flow of data elements
that are transmitted or intended for transmission in a defined format. It
works either as a source from where the data can be obtained or as a
destination for the output sent.
 To operate with streams we have to our disposal the standard iostream
library which provides us the following elements: Basic class templates,
Class template instantiations, Standard objects, Types, Manipulators.
 In C++, the file stream classes are designed with the idea that a file
should simply be viewed as a stream or array of uninterpreted bytes.
 The current reading position, which is the index of the next byte that will
be read from the file.
 The current writing position, which is the index of the byte location where
the next output byte will be placed.
 The streams need to be created before they are used in the programs.
The statements to create streams are similar to the variable declaration.
 The streams need to be created before they are used in the programs.
The statements to create streams are similar to the variable declaration.
These statements are written at the top of the program with variable
declaration.
 C++ provides various console I/O functions for formatting the outputs.
Formatting means displaying the outputs in more readable and

Manipal University Jaipur B2114 Page No.: 239


Object Oriented Programming – C++ Unit 10

comprehensible manner. Formatting of outputs can be achieved in two


ways i.e. using ios class functions and flags and using Manipulators.
 The ios class contains many member functions that would help us to
format the output in a number of ways. The most important ones among
them are :width(), precision(), fill(), self(), unself()
 Manipulators are the functions which are used to manipulate the output
formats and are provided in header file iomapin.

10.6 Terminal Questions


1. Explain the standard Input/Output iostream library.
2. List and explain the elements of iostream library.
3. Discuss in detail the basic stream concepts.
4. Discuss the process involved in reading a file with the help of an
example.
5. Explain all the ios functions used for formatting output with examples.
6. Explain that how manipulators are used to manage the output.

10.7 Answers
Self Assessment Questions
1. Iostream
2. Stream
3. Class templates
4. Standard output stream for logging
5. File
6. True
7. True
8. using ios class functions, flags and manipulators
9. width()
10. manipulators , iomapin
11. fill()
12. True

Manipal University Jaipur B2114 Page No.: 240


Object Oriented Programming – C++ Unit 10

Terminal Questions
1. A stream is sequence of bytes. It is a continuous flow of data elements
that are transmitted or intended for transmission in a defined format. It
works either as a source from where the data can be obtained or as a
destination for the output sent. For more details refer section 10.2.
2. Classes, objects and types are the major division under elements of
iostream library. For more details refer section 10.2.
3. In C++, the file stream classes are designed with the idea that a file
should simply be viewed as a stream or array of uninterpreted bytes. For
more details refer section 10.3.
4. The first program, will create a file, and put some text into it.
#include <fstream>
using namespace std;
int main() {
ofstream SaveFile("cpp-home.txt");
SaveFile << "Hello World, from www.cpp-home.com and Loobian!";
SaveFile.close();
return 0;
}
The above program will create cpp-home.txt file and will write the
sentence -Hello World, from www.cpp-home.com and Loobian into it.
For more details refer section 10.3.2.
5. The ios class contains many member functions that would help us to
format the output in a number of ways. The important ios class format
functions are as follows: width(), precision(), fill(), self(), unself(). For
more details refer section 10.4.1.
6. Manipulators are the functions which are used to manipulate the output
formats and are provided in header file iomapin. They provide the same
features as that of the ios member functions and flags.
For more details refer section 10.4.2.

Manipal University Jaipur B2114 Page No.: 241


Object Oriented Programming – C++ Unit 11

Unit 11 Files
Structure:
11.1 Introduction
Objectives
11.2 Managing I/O Streams
Opening and closing a file
Checking for Failures with File Commands
11.3 Checking the I/O Status - Flags
11.4 Dealing with Binary Files
11.5 Some Useful Functions
11.6 Summary
11.7 Terminal Questions
11.8 Answers

11.1 Introduction
In the previous unit, you studied iostream hierarchy, standard IO stream
library and its organization. You also studied the methods to format the
output of the programs. In this unit you are going to study different methods
of opening and closing a file, methods to check I/O status. You will also
learn to deal with binary files. In C++, the file stream classes are designed
with the idea that a file should simply be viewed as a stream or an array of
uninterrupted bytes. For convenience, the "array" of bytes stored in a file is
indexed from zero to len-1, where len is the total number of bytes in the
entire file. You can open a file stream object if you can supply a file name
along with an I/O mode parameter to the constructor when declaring an
object. Binary file is a file of any length that holds bytes with values in the
range 0 to 0xff (0 to 255). These bytes have no other meaning.
Objectives:
After studying this unit, you should be able to:
 describe opening and closing of files in different modes
 describe the ways to check the I/O status
 explain binary files
 discuss the important functions pertaining to files

Manipal University Jaipur B2114 Page No.: 242


Object Oriented Programming – C++ Unit 11

11.2 Managing I/O Streams


In this section, we will discuss some useful functions. We will also see how
to open a file to read and write simultaneously. We will also explore other
ways to open a file and check if the opening was successful or not.
11.2.1 Opening and closing a file
For opening a file you have to create a file stream and link it to a filename.
You can define a filename using ifstream, ofstream and fstream classes.
These classes are contained in the header file fstream. Selection of classes
which you are going to use depends on the purpose, i.e., whether you want
to write data to the files or to read data from the files. There are two ways to
open a file. These are:
1. Using the constructor function of the class
2. Using the member function open() of the class.
1. Opening file using constructors
You already know that a constructor initializes an object when it is created.
Here to initialize the file stream object, a filename is used. The following
steps are required to do this:
Create a file stream object to manage the stream using appropriate class.
That is, to create input stream, use ifstream class, and use ofstream class to
create output stream.
Use any desired filename to initialize the object.
For example, the statement below opens the filename “results” for output:
ofstream outfile(“results”); //output only
The outfile is created as an ofstream object that manages the output
stream. This object can be any valid C++ name. The file ‘results’ is also
opened by this statement. and this attaches it to the output stream outfile.
Similarly, the statement shown below declares infile as an ifstream object
and attaches it to the data for reading (input).
iftream in file(“data”); //input only
The following statements can be there in the program:
outfile << “total”;
outfile << sum;
infile << number;
infile << string;

Manipal University Jaipur B2114 Page No.: 243


Object Oriented Programming – C++ Unit 11

You can also use the same file for reading and writing the data as shown in
the example below:
Program1
…………..
………….
ofstream outfile(“salary”); // the outfile is created and “salary’ is
connected to it
…………..
………….
Program2
…………..
………….
ifstream infile(“salary”); //infile is created and ‘salary” is
connected to
it.
When the stream object expires, then connection with the first file is closed
automatically. As you can observe from the above statements, when
program1 terminates, the salary file is disconnected from the outfile stream.
When the program2 is terminated a similar action is taken.
We can use one program instead of two programs (one for writing data and
another for reading data). For example:
………….
………….
outfile.close(); //disconnects salary from outfile and connects
to infile
ifstream infile(“salary”);
…………
…………
infile.close(); //disconnect salary form infile
You can observe that even though one program is used, two filestream
objects are created. One is an outfile to put data to the file, and another, an
infile to get data from the file. The statement outfile.close(); disconnects the
file from the output stream outfile. Note that the object outfile continues to
exist, and later the salary file can again be connected to outfile or to any

Manipal University Jaipur B2114 Page No.: 244


Object Oriented Programming – C++ Unit 11

other stream. In the example shown above we have connected the salary
file to the infile stream to read data.
The program below uses a single file for both writing and reading the data.
First it takes data from the keyboard, and writes it to the file. The file is
closed once the writing is completed. The program again opens the same
file, reads the information present in the file and displays it on the screen.
// Program to create file with single constructor
#include<iostream.h>
#include<fstream.h>
int main()
{
ofstream outf(“ file1”); //connects ifile1 to outf
cout<< “Enter item name:”;
char name[30]; //get name from keyboard and write it to file
named file1
cin>> name;
outf << name << “\n”;
cout << “Enter item cost:”;
float cost;
cin>> cost; // input the value of cost
outf << cost << “\n”; //write to file file1
outf.close(); //disconnect file named file1 from outf
ifstream inf(“file1”); // connect file named file1 to inf
inf >> name; // read name from file1
inf >> cost; // read cost from file named file1
cout << “\n”;
cout << “Item name:” << name << “\n”;
cout << Item cost :” << cost << “\n”;
inf.close(); //disconnect file named file1 from inf
return 0;
}
The output of the above program will be:
Enter item name: Book
Enter item cost: 200
Item name: Book
Item cost: 200
Manipal University Jaipur B2114 Page No.: 245
Object Oriented Programming – C++ Unit 11

2. Opening a file using open() function


As mentioned earlier, the open() function can be used to open multiple files
that use the same stream object. For example, sometimes we want to
process a set of files sequentially. Then we create a single filestream object,
and use it to open each file in turn. This can be done as follows: file-
stream-class stream-object;
stream-object.open (“filename”);
Example:
ofstream outfile; // create stream (for output)
outfile.opne(“data1”); //connect stream to data1
………..
………….
outfile.close(); //disconnect stream from data1
outfile.open(“data2”); //connect stream to data2
………….
………....
outfile.close(); //disconnect stream from data2
…………..
………….
The above program opens two files in sequence for writing data. It is to be
noted that the first file is closed before opening the second file. This is
required to be done because stream can be connected to only one file at a
time.
The files can also be opened in the following way:
The program below illustrates the way to work with multiple files.
//Creating files with open() function
#include<iostream.h>
#include<fstream.h>
int main()
{
ofstream fout; //create output stream object
fout.open(“country”); //connect “country” to it
fout<< “India \n”;
fout << “USA\n”;
fout << “UK\n”;

Manipal University Jaipur B2114 Page No.: 246


Object Oriented Programming – C++ Unit 11

fout.close(); //disconnect “country”


fout.open(“capital”); //connect capital
fout <<“Delhi\n”;
fout << “Washington\n”;
fout << “London\n”;
fout.close(); //disconnect “capital”
//Reading the files
cons tint N=80; //size of line
char line[N];
ifstream fin; //create input strea,
fin.open(“country”); //connect “country” to it
cout << “contents of country file\n”;
while(fin) //check end-of-file
{
fin.close(line,N); //read a line
cout << line; //display it
}
fin.close();
fin.open(“capital”); //connects “capital”
cout << “\n contents of capital file \n”;
while (fin)
{
fin.getline(line, N);
cout << lie;
}
fin.close();
return 0;
}
The output of the above program will be:
Contents of country file
India
USA
Uk
Contents of capital file
Delhi
Washington
London

Manipal University Jaipur B2114 Page No.: 247


Object Oriented Programming – C++ Unit 11

Sometimes it is required to use two or more files in the program


simultaneously. For an example, we may require to merge two files into a
third sorted file. This means, both the sorted files should be kept open for
reading and third one should be kept open for writing. In such cases, it is
needed to create two separate input streams for handling the two input files
and one output stream for handling the output file.
We have used ifstream and ofstream constructors and the open() function to
create new files as well as to open the existing files. You can note that in
both the methods only one argument has been used, and that is the name
of the file. However, these functions can take two arguments, the second
one being for specifying the file mode. The syntax of open() function that
accepts two arguments is as follows:
stream-object.open(“filename”, mode);
The second argument, i.e. mode, describes the purpose for which the file is
opened. Then the question may arise in your mind as to how we opened the
files without providing the second argument in the previous examples.
The prototype of these class member functions contains default values for
the second argument, and therefore, they use the default in the absence of
the actual values. The following are the default values:
ios::in for ifstream meaning open for reading only.
ios::out for ofstream meaning open for writing only.
The file mode parameter can take one (or more) of such constants defined
in the class ios. The table 11.1 shows the file mode parameters.
Table 11.1: File mode parameters
ios::in Open file to read
ios::out Open file to write
ios::app All the date you write, is put at the end of the file. It calls
ios::out
ios::ate All the date you write, is put at the end of the file. It does not
call ios::out
ios::trunk Deletes all previous content in the file. (empties the file)
ios::nocreate If the file does not exists, opening it with the open() function
gets impossible.
ios::noreplace If the file exists, trying to open it with the open() function,
returns an error.
ios::binary Opens the file in binary mode.

Manipal University Jaipur B2114 Page No.: 248


Object Oriented Programming – C++ Unit 11

In fact, all these values are int constants from an enumerated type. But, for
making your life easier, you can use them as you see them in the table.
Here is an example for the method to use the open modes:
#include <fstream.h>
void main() {
ofstream SaveFile("file1.txt", ios::ate);
SaveFile << "That's new!\n";
SaveFile.close();
}
As you see in the table, using ios::ate writes at the end of the file. If it wasn’t
used, the file would have been overwritten. So, if file1.txt has this text:
Hi! This is test from www.cpp-home.com!
running it will add “That’s new!” to it; so it will look this way:
Hi! This is test from www.cpp-home.com! That’s new!
If you want to set more than one open mode, just use the OR operator (|)
this way:
ios::ate | ios::binary
Using different open modes helps make file handling an easy job. Having
the liberty to choose a combination of these, in the same way, comes very
handy in using streams effectively, and to the requirements of the project.
Moving on to something more intriguing and important, we can create a file
stream handle, which you can use to read/write file at the same time. Here
is how it works:
fstream File(“cpp-home.txt”, ios::in | ios::out);
In fact, that is only the declaration. The code line above creates a file stream
handle, named File. As you know, this is an object from class fstream.
When using fstream, you should specify ios::in and ios::out as open modes.
This way, you can read from the file, and write in it, at the same time,
without creating new file handles. Well, of course, you can only read or
write. Here is the code example:
#include <fstream.h>
void main()

Manipal University Jaipur B2114 Page No.: 249


Object Oriented Programming – C++ Unit 11

{
fstream File("test.txt", ios::in | ios::out);
File << "Hi!"; //put “Hi!” in the file
static char str[10]; //when using static, the array is automatically
//initialized, and very cell NULLed
File.seekg(ios::beg); //get back to the beginning of the file
//this function is explained a bit later
File >> str;
cout << str << endl;
File.close();
}
Let us now understand the above program:
fstream File(“test.txt”, ios::in | ios::out);
This line, creates an object from class fstream. At the time of execution, the
program opens the file test.txt in read/write mode. This means that you can
read from the file and put data into it at the same time.
File << “Hi!”;
This statement writes Hi! in the file named test.txt
static char str[10];
This makes a char array with 10 cells. The word static initializes the array
when at the time of creation.
File.seekg(ios::beg);
To understand this statement, consider the following statement:
while(!OpenFile.eof()) // here OpenFile is a stream-object
{
OpenFile.get(ch);
cout << ch;
}
This is ‘a while loop’ that will loop until you reach the end of the file. But how
does the loop know if the end of the file is reached? The answer is; when
you read the file, there is something like an inside-pointer (current
reading/writing position) that shows where you are, with the reading (and
writing, too). Every time you call OpenFile.get(ch), it returns the current

Manipal University Jaipur B2114 Page No.: 250


Object Oriented Programming – C++ Unit 11

character to the ch variable, and moves the inside-pointer one character


after that, so that the next time this function is called, it returns the next
character. And this repeats, until you reach the end of the file.
Going back to the code line, the function seekg() will put the inside-pointer
to a specific place (specified by you). One can use:
 ios::beg – to put it in the beginning of the file
 ios::end – to put it at the end of the file
Or you can also set the number of characters to go back or after. For
example, if you want to go 5 characters back, you should write:
File.seekg(-5);
If you want to go 40 characters after, just write:
File.seekg(40);
It is imperative to mention that the seekg() function is overloaded, and it can
take two parameters, too. The other version is this one:
File.seekg(-5, ios::end);
In this example, you will be able to read the last 4 characters of the text,
because:
 You go to the end (ios::end)
 You go 5 characters before the end (-5)
Why do you read 4 but not 5 characters? One character is lost, because the
last thing in the file is neither a character nor white space. It is just position
(i.e., end of file).
Why was this function used in the program above? After putting “Hi!” in the
file, the inside-pointer was set after it, i.e., at the end of the file. And as we
want to read the file, there is nothing that can be read at the end. Hence, we
have to put the inside-pointer at the beginning. And that is exactly what this
function does.
File >> str;
This line looks similar to cin >>. In fact, it has much to do with it. This line
reads a word from the file, and puts it into the specified array. For example,
if the file has this text:
Hi! Do you know me?

Manipal University Jaipur B2114 Page No.: 251


Object Oriented Programming – C++ Unit 11

Using File >> str, will put just “Hi!” to the str array. And, as what we put in
the file was “Hi!” we don’t need to use a while loop, that takes more time to
code. That’s why this technique was used. By the way, in the while loop for
reading that has been used so far, the program reads the file, character by
character. But you can read it word by word, this way:
char str[30]; //the word can’t be more than 30 characters long
while(!OpenFile.eof())
{
OpenFile >> str;
cout << str;
}
You can also read it line by line, this way:
char line[100]; //a whole line will be stored here
while(!OpenFile.eof())
{
OpenFile.getline(line,100); //where 100 is the size of the array
cout << line << endl;
}
It is recommended that you use the line-by-line one, or the first technique
that was mentioned, i.e., the one which reads char-by-char. The one that
reads word-by-word is not a good option since it will not read the new line.
So if you have a new line in the file, it will not display it as a new line, but will
append the text to the existing one. But using getline() or get() will show you
the file just as it is.
11.2.2 Checking for Failure with File Commands
Now, we will see how to check whether the file opening was successful or
not. In fact, there are a few good ways to check it thus, and we will learn
some of them. Notice that where there is X, it can be either “o”, or “i”, or
nothing (it will then be fstream object).
Example 1: The most usual way
Xfstream File(“cpp-home.txt”);
if (!File)
{
cout << “Error opening the file! Aborting…\n”;

Manipal University Jaipur B2114 Page No.: 252


Object Oriented Programming – C++ Unit 11

exit(1);
}
Example 2: If the file is created, return an error
ofstream File("unexisting.txt", ios::nocreate);
if(!File)
{
cout << “Error opening the file! Aborting…\n”;
exit(1);
}
Example 3: Using the fail() function
ofstream File("filer.txt", ios::nocreate);
if(File.fail())
{
cout << “Error opening the file! Aborting…\n”;
exit(1);
}
You can see a function fail() in the above example. A non-zero value is
retuned by this function if any I/O occurs. There is an interesting fact that
needs to be mentioned here. Say, you have created a file stream, but you
have not opened a file, as in the following way:
ifstream File; //it could also be ofstream
This way, we have a handle, but we still have not opened the file. If you
want to open it later, it can be done with the open() function (which has
already been covered in this chapter). But if anywhere in your program, you
need to know whether currently there is an opened file, you can check it
with the function is_open(). It retunrs 0 (false) if the file is not opened, and 1
(true) if there is an opened file. For example:
ofstream File1;
File1.open("file1.txt");
cout << File1.is_open() << endl;
The code above, will return 1 as we open a file (on line 2). But the code
below will return 0, because we do not open a file, but just create a file
stream handle:
ofstream File1;
cout << File1.is_open() << endl;

Manipal University Jaipur B2114 Page No.: 253


Object Oriented Programming – C++ Unit 11

Self Assessment Questions


1. There are two ways to open a file. These are__________ and
___________.
2. The function of _________ is to put at the end of the file all the date we
write.
3. The function seekg() will put the inside-pointer to a specific place
[True/False].
4. The __________ function can be used to open multiple files that use
the same stream object.

11.3 Checking the I/O Status – Flags


The Input/Output system in C++ holds information about the result of every
I/O operation. The current status is kept in an object from type iostate, which
is an enumerated type (just like open_mode) defined by ios that has the
values described in table 11.2:
Table 11.2: Error-Status flags
Goodbit No errors( no flags set, value=0)
Eofbit End of file has been reached
Failbit Non-fatal I/O error
Badbit Fatal I/O error

There are two ways to receive information about the I/O status. One of them
is by calling the function rdstate() which is a member of ios. It returns the
current status of the error-flags (the above mentioned). For example, the
goodbit is returned by the function rdstate() if no errors are encountered.
The other way to check the I/O status is by using any of the following
functions:
bool bad();
bool eof(); //Read until the end of the file has been reached
bool fail(); / /Check if the file opening was successful
bool good();
The function bad() returns true, if the badbit is set. The fail() function returns
true if the failbit is set. The good() function returns true if there are no errors
(the goodbit bit is set). And the eof() function returns true if the end of the
file has been reached (the eofbit is set.).

Manipal University Jaipur B2114 Page No.: 254


Object Oriented Programming – C++ Unit 11

Once an error has occurred, it might need to be cleared before your


program continues. To do this, you have to use the ios member function
clear() whose prototype is as follows:
void clear(iostate flags=ios::goodbit);
If flags is goodbit (as it is by default) as error flags are cleared. Otherwise,
you can set flags to the desirable settings.
Some examples to show the use of flags are given below:
Example 1: Simple status check
//Replace FileStream with the name of the file stream handle
if (FileStream.rdstate() == ios::eofbit)
cout << "End of file!\n";
if (FileStream.rdstate() == ios::badbit)
cout << "Fatal I/O error!\n";
if (FileStream.rdstate() == ios::failbit)
cout << "Non-fatal I/O error!\n";
if (FileStream.rdstate() == ios::goodbit)
cout << "No errors!\n";
Example 2: The clear() function
#include <fstream.h>
void main() {
ofstream File1("file2.txt"); //create file2.txt
File1.close();
//this will return error, because ios::noreplace is used
//open_mode, which returns error if the file already exists.
ofstream Test("file2.txt", ios::noreplace);
//The error that the last line returned is ios::failbit
if (Test.rdstate() == ios::failbit)
cout << "Error...!\n";
//set the current status to ios::goodbit
Test.clear(ios::goodbit);
//check if it was set correctly
if (Test.rdstate() == ios::goodbit)
cout << "Fine!\n";
Test.clear(ios::eofbit); //set it to ios::eofbit. Useless.
//and check again if it is this flag indeed
Manipal University Jaipur B2114 Page No.: 255
Object Oriented Programming – C++ Unit 11

if (Test.rdstate() == ios::eofbit)
cout << "EOF!\n";
Test.close();
}
Self Assessment Questions
5. The function bad() returns true, if the badbit flag is set. (True/False).
6. ______________ function returns the current status of the error-flags.

11.4 Dealing with Binary Files


Although it is best to work with formatted files, sometimes we need to work
with unformatted files, i.e. binary files, too. They have the same look as your
program, and they are much different from what comes after using the <<
and >> operators. The functions that give you the possibility to write/read
unformatted files are get() and put(). To read a byte, you can use get(), and
to write a byte, put().
get() and put() both take one parameter, a char variable or character. If you
want to read/write whole blocks of data, then you can use the read() and
write() functions. Their prototypes are:
istream &read(char *buf, streamsize num);
ostream &write(const char *buf, streamsize num);
For the read() function, buf should be an array of chars, where the read
block of data will be put. For the write() function, buf is an array of chars,
where the data you want to save in the file is. For both the functions, num is
a number that defines the amount of data (in symbols) to be read/written.
If you reach the end of the file, before you have read “num” symbols, you
can see how many symbols were read by calling the function gcount(). This
function returns the number of read symbols for the last unformatted input
operation. And, before going to the code examples, we must take note that
if you want to open a file for binary read/write, you should pass ios::binary in
an open mode.
Now, let us see some code examples so that you can see how stuff works.
Example 1: Using get() and put()
#include <fstream.h>
void main() {

Manipal University Jaipur B2114 Page No.: 256


Object Oriented Programming – C++ Unit 11

fstream File("test_file.txt",ios::out | ios::in | ios::binary);


char ch;
ch='o';
File.put(ch); //put the content of ch to the file
File.seekg(ios::beg); //go to the beginning of the file
File.get(ch); //read one character
cout << ch << endl; //display it
File.close();
}
Example 2: Using read() and write()
#include <fstream.h>
#include <string.h>
void main() {
fstream File("test_file.txt",ios::out | ios::in | ios::binary);
char arr[13];
strcpy(arr,"Hello World!"); //put Hello World! into the array
File.write(arr,5); //put the first 5 symbols into the file- "Hello"
File.seekg(ios::beg); //go to the beginning of the file
static char read_array[10]; //I will put the read data, here
File.read(read_array,3); //read the first 3 symbols- "Hel"
cout << read_array << endl; //display them
File.close();
}
Self Assessment Questions
7. The functions that allow you to write/read unformatted files are get()
and put().
8. To read a block of data from the file _______________ function is
used.

11.5 Some useful functions


 tellg() –function is used to get the current position of the input pointer in
the file. This function returns an integer type value.
#include <fstream.h>
void main()
{

Manipal University Jaipur B2114 Page No.: 257


Object Oriented Programming – C++ Unit 11

//if we have "Hello" in test_file.txt


ifstream File("test_file.txt");
char arr[10];
File.read(arr,10);
//this should return 5, as Hello is 5 characters long
cout << File.tellg() << endl;
File.close();
}
 tellp() – this is the same as tellg() but is used when we write in a file.
This function is used to get the current position of the output pointer in
the file.
 seekp() – You have already studied seekg() function which is used to
move the input pointer to a specified location. Similarly, seekp() function
is used to move the output pointer to a specified location. seekp()
function can be used in the same way as seekg() function.
 ignore() – Used when reading a file. If you want to ignore certain
number of characters, this function can be used to extract and discard
them from the input stream. In fact, you can use seekg() instead, but the
ignore() function has one advantage: you can specify a delimiter rule,
where the ignore() function will stop. The syntax of ignore() is as follows:
stream_obj.ignore(int count, delimiter);
Here the ignore() function will continue to extract and discard the
characters from the input stream until the count characters are
discarded or the character specified by the delimiter is encountered.
For example:
ignore(5,h);
Here ignore() function contains two arguments i.e. an integer value 5
and a character value h. So the ignore function continues to ignore
characters until either 5 characters have been discarded or the
character h is found.
 getline() –The getline() function is used for the read operation. This
function can be used to read the contents of the file line by line from an

Manipal University Jaipur B2114 Page No.: 258


Object Oriented Programming – C++ Unit 11

input stream, but it can be set to stop reading if it met a certain symbol.
Here is how you should pass the parameters to it:
getline(array, array_size, delim);
And here is a code example:
#include <fstream.h>
void main() {
//if we have "Hello World" in test_file.txt
Ifstream File("test_file.txt");
static char arr[10];
/*read, until one of these happens:
1) You have read 10
2) You met the letter "o"
3) There is a new line
*/
File.getline(arr, 10, 'o');
cout << arr << endl; //it should display "Hell"
File.close();
}
 peek() – This function will return the next character from an input file
stream, but unlike get() function, it won’t move the inside-pointer. get(),
for example, returns the next character in the stream, and after that, it
moves the inside-pointer, so that the next time you call the get()
function, it will return the next character, but not the same one. Using
peek() will return a character, but it won’t move the cursor. So, if you call
the peek() function twice in succession, it will return the same character.
The syntax to use the peek() function is as follows:
stream_obj.peek();
In the above syntax peek() function will return the next character or eof if
the end of the file is reached.
Consider the following code example:
#include <fstream.h>
void main()
{
//if we have "Hello World" in test_file.txt
ifstream File("test_file.txt");
char ch;
Manipal University Jaipur B2114 Page No.: 259
Object Oriented Programming – C++ Unit 11

File.get(ch);
cout << ch << endl; //should display "H"
cout << char(File.peek()) << endl; //should display "e"
cout << char(File.peek()) << endl; //should display "e" again
File.get(ch);
cout << ch << endl; //should display "e" again
File.close();
}
The peek() function actually returns the ASCII code of the char, but not
the char itself. So, if you want to see the character itself, you have to call
it the way shown above.
 remove()
The files can be removed by calling the remove function which has the
following specification:
#include<stdio.h>
int remove(const char *filename);
The remove() function deletes a file whose name is the string pointed to
by fname. If successful, it returns zero, or else, it returns a non-zero
value. If fname is open, i.e. if it is associated with a stream and this
association has not been broken, then the behavior of remove is not
defined.
Let us see the following example:
/* remove example: remove myfile.txt */
#include <stdio.h>
int main ()
{
if( remove( "myfile.txt" ) != 0 )
perror( "Error deleting file" );
else
puts( "File successfully deleted" );
return 0;
}
If the file myfile.txt exists before the execution and the program has write
access to it, the file would be deleted and the following message would
be displayed to stdout:

Manipal University Jaipur B2114 Page No.: 260


Object Oriented Programming – C++ Unit 11

File successfully deleted


Otherwise, a message similar to this would be written to stderr:
Error deleting file: No such file or directory
 putback() – The putback() function is a member of istream.
It attempts to decrease the current location in the stream by one
character, making the last character extracted from the stream once
again available to be extracted by input operations. Here is a code
example:
#include <fstream.h>
void main() {
//test_file.txt should have this text- "Hello World"
ifstream File("test_file.txt");
char ch;
File.get(ch);
cout << ch << endl; //it will display "H"
File.putback(ch);
cout << ch << endl; //it will again display "H"
File.get(ch);
cout << ch << endl; //it will display "H" again
File.close();
}
 flush() –Whenever you perform a write operation on a file, the contents
are not written directly, but are saved in a buffer (storage space).
And when the buffer gets filled, then the data is put in the real file (on
your disk). Then the buffer is emptied, and so on. But if you want to save
the data from the buffer, even if the buffer is still not full, use the flush()
function. Just call it this way- FileHandle.flush(). Consequently, the data
from the buffer will be put in the physical file, and the buffer will be
emptied.
The syntax of the flush() function is as follows:
stream_obj.flush();

Manipal University Jaipur B2114 Page No.: 261


Object Oriented Programming – C++ Unit 11

Self Assessment Questions


9. _________ function is used to get the current position of the input
pointer in the file.
10. _________ function is used to ignore certain amount of characters
from the input stream.
11. _________function decreases the current location in the stream by one
character, making the last character extracted from the stream once
again available to be extracted by input operations.
12. The peek() function will return the next character from an input file
stream, but like get() function, it will move the inside-pointer.
(True/False)

11.6 Summary
 This unit focusses on how to manage the file to operate using I/O
streams. This chapter has discussed comprehensively the C++ streams.
Various examples provided throughout this chapter illustrate the use of
these streams.
 For opening a file you have to create a file stream, and it is to be linked
to a filename. You can define a filename using ifstream, ofstream and
fstream classes. These classes are contained in the header file fstream.
 There are two ways to open a file. They are: using the constructor
function of the class, and using the member function open() of the class.
 The open() function is used to open multiple files that use the same
stream object.
 There are two ways to receive information about the I/O status. One of
them is by calling the function rdstate(). And the other way to check the
I/O status is by using any of the following functions: bool bad(), bool
eof(), bool fail() and bool good().
 The functions that give you the possibility to write/read unformatted files
are get() and put(). To read a byte, you can use get(), and to write a
byte, use put().
 Some useful functions in c++ are: tellg(), tellp(), seekp(), ignore()
 getline(), peek(), remove(), putback() and flush().

Manipal University Jaipur B2114 Page No.: 262


Object Oriented Programming – C++ Unit 11

11.7 Terminal Questions


1. Explain the types of methods to open a file.
2. Discuss the methods to check whether the file opening was successful
or not.
3. Discuss ‘on file I/O flags’.
4. Elaborate the concept of binary files.
5. List and discuss some important functions of file operations.

11. 8 Answers
Self-Assessment Questions
1. using constructor function of the class, using member function open() of
the class.
2. ios::app
3. True
4. open()
5. True
6. rdstate()
7. get() and put()
8. read()
9. tellg()
10. ignore()
11. putback()
12. Flase

Terminal Questions
1. There are two ways to open a file. These are: using the constructor
function of the class, and using the member function open() of the class.
For more details refer section 11.2.1.
2. The most usual way is:
Xfstream File(“cpp-home.txt”);
if (!File)
{
cout << “Error opening the file! Aborting…\n”;
exit(1);
For more details refer section 11.2.2.

Manipal University Jaipur B2114 Page No.: 263


Object Oriented Programming – C++ Unit 11

3. The Input/Output system in C++ holds information about the result of


every I/O operation. The current status is kept in an object from type
iostate, which is an enumerated type (just like open_mode) defined by
ios. For more details refer section 11.3.
4. Although it is best to work with formatted files, sometimes we need to
work with unformatted files, i.e. binary files, too. They have the same
look as your program, but it is much different from what comes after
using the << and >> operators. For more details refer section 11.4.
5. tellg(), tellp() etc. are some of the functions that reflect the position of the
current pointer in flags. For more details refer section 11.5.

Manipal University Jaipur B2114 Page No.: 264


Object Oriented Programming – C++ Unit 12

Unit 12 Class Templates

Structure:
12.1 Introduction
Objectives
12.2 Class Templates
Implementing a class template
Class template with multiple parameters
12.3 Function Templates
Implementing function templates
Using template functions
Function templates with multiple parameters
Overloading Function Templates
12.4 Template Instantiation
12.5 Class Template Specialization
Template class partial specialization
12.6 Template Function Specialization
12.7 Template Parameters
12.8 Static Members and Variables
12.9 Templates and Friends
12.10 Templates and Multiple – File Projects
12.11 Summary
12.12 Terminal Questions
12.13 Answers

12.1 Introduction
In the previous unit you have studied the methods to open and close files
along with the methods to check whether a file opening was successful or
not. You have also studied the I/O status flags, binary files and some very
useful functions in C++. In this unit you are going to study in detail about the
templates in C++. Template in C++ is newly added concept that enables us
to define generic classes and functions and hence provides support for
generic programming. Generic programming is an approach where generic
types are used as parameters in algorithms so that they work for variety of
suitable data types and data structures. We can use templates to create
family of class and functions. For example, a class template for an array will

Manipal University Jaipur B2114 Page No.: 265


Object Oriented Programming – C++ Unit 12

enable us to create arrays of various data types. Similarly, a template for a


function, let us say add() can be defined, that will enable us to create
various versions of function add() to multiply int, float and double type
values.
Objectives:
After studying this unit you should be able to:
 define templates, and the types of templates available in C++.
 describe how templates are dealt with by the C++ compiler.
 describe the scenarios in which templates are useful.
 discuss in detail the in-depths of template programming.
 discuss C++ programming using templates.

12.2 Class Templates


A template can be considered a kind of macro. When we define an object of
a specific type for actual use, the definition of template for that class is
substituted with the required data type. Since the template is defined with a
parameter that would be replaced by a specified data type at the time of
actual use of the class or function, the templates are sometimes called
parameterized classes or functions.
Consider a vector class defined as follows:
class vector
{
int *v;
int size;
public:
vector(int m)
{
v= new int[size = m];
for(int i=0; i<size; i++)
v[i]=0;
}
vector (int *a) //create a vector from an array
{
for( int i=0; i<size ; i++)
v[i]= a[i];

Manipal University Jaipur B2114 Page No.: 266


Object Oriented Programming – C++ Unit 12

}
int operator*(vector &y) //scalar product
{
int sum=0;
for( int i=0; i<size; i++)
sum= sum + this-> v[i] * y . v[i];
return sum;
}
};
The vector class can store an array of int numbers and perform the scalar
product of two int vectors as shown below:
int main()
{
int x[3] = {1, 2, 3};
int y[3] = {4, 5, 6};
vector v1(3); //creates a null vector of three integers
vector v2(3);
v1 = x; //creates v1 from the array x
v2= y;
int R = v1 * v2;
cout << “R = “ << R;
return 0;
}
Now let’s assume that we want to define a vector that can store an array of
float values. This can be done by replacing the appropriate int declarations
with float in the vector class. This means that the complete class needs to
be redefined.
This helps us define a vector class with the data type as a parameter and
then use this class to create a vector of any data type instead of defining a
new class every time. This can be achieved by using the templates.
12.2.1 Implementing a Class Template
As it has already been mentioned, the templates allow us to define generic
classes. It is a simple process to create a generic class using a template
with anonymous type. The general format of class template is as follows:

Manipal University Jaipur B2114 Page No.: 267


Object Oriented Programming – C++ Unit 12

class classname
{
//class member specification with anonymous type T wherever
appropriate.
………….
};
For example, the definition of vector class is given below:
template<class T>
class vector
{
T* v; //type T vector
int size;
public:
vector(int m)
{
v= new T [ size = m];
for (int i=0; i<size; i++)
v[i]=0;
}
vector (T *a)
{
for(int i=0; i<size; i++)
v[i] = a[i];
}
T operator* (vector &y)
{
T sum = 0;
for (int i =0; i<size ; i++)
sum = sum + this -> v[i] * y. v[i];
return sum;
}
The class template definition is similar to an ordinary class definition except
the prefix template<class T> and the use of type T. This prefix tells the
compiler that a template is to be declared and T is used as a type name in
declarations. Thus vector has become a parameterized class with type T as
its parameter. T can be substituted with any data type including the user-
Manipal University Jaipur B2114 Page No.: 268
Object Oriented Programming – C++ Unit 12

defined types. Now it is possible to create vectors holding different data


types.
For example
vector <int> v1(10); //10 element int vector
vector <float> v2(25); // 25 element float vector
A template class is a class created from a class template. The object of a
template class is defined by using the following syntax:
classname<type> objectname(arglist);
This is a process of creating a specific class from a class template and it is
called instantiation. The error analysis will be performed by the compiler
only when instantiation takes place. Hence, it is advised to create and
debug an ordinary class before converting it into a template.
The following program shows the use of a vector class template for
performing the scalar product of int type vectors. #include<iostream>
using namespace std;
const size = 3;
template <class T>
class vector
{
T* v; //type T vector
public:
vector()
{
v = new T[size];
for (int i=0; i<size; i++)
v[i] = 0;
}
vector (T* a)
{
for (int i=0; i<size; i++)
v [i] = a[i];
}
T operator*(vector &y)
{

Manipal University Jaipur B2114 Page No.: 269


Object Oriented Programming – C++ Unit 12

T sum =0;
for (int i=0; i<size; i++)
sum = sum + this -> v[i] * y.v[i];
return sum;
}
};

int main()
{
int x[3] = {1, 2, 3};
int y[3] = {4, 5, 6};
vector <int> v1;
vector <int> v2;
v1 = x;
v2 = y;
int R = v1 * v2;
cout << “R =” << R << “\n”;
return 0;
}
The output of the above program will be:
R = 32
The following program shows the use of a vector class template for
performing the scalar product of float type vectors.
#include<iostream>
using namespace std;
const size = 3;
template <class T>
class vector
{
T* v; //type T vector
public:
vector()
{
v = new T[size];
for (int i=0; i<size; i++)

Manipal University Jaipur B2114 Page No.: 270


Object Oriented Programming – C++ Unit 12

v[i] = 0;
}
vector (T* a)
{
for (int i=0; i<size; i++)
v [i] = a[i];
}
T operator*(vector &y)
{
T sum =0;
for (int i=0; i<size; i++)
sum = sum + this -> v[i] * y.v[i];
return sum;
}
};
int main()
{
float x[3] = {1.1, 2.2, 3.3};
int y[3] = {4.4, 5.5, 6.6};
vector <float> v1;
vector <float> v2;
v1 = x;
v2 = y;
int R = v1 * v2;
cout << “R =” << R << “\n”;
return 0;
}
The output of the above program will be:
R = 38.720001

12.2.2 Class Templates with Multiple Parameters


It is possible to use more than one generic data type in a class template.
They are declared as comma-separated list within the template specification
as shown below:
template< class T1, class T2,…..>
class classname

Manipal University Jaipur B2114 Page No.: 271


Object Oriented Programming – C++ Unit 12

{
………
……….
body of the class
…………
};

The program below shows the use of template class with two generic data
types.
#include<iostream>
using namespace std;
template< class T1, class T2>
class demo
{
T1 a;
T2 b;
}
public:
Test(T1 x, T2 y)
{
a=x;
b=y;
}
void show()
{
cout << a << “ and “ << b << “\n”;
}
};
int main()
{
demo <float, int> d1 (1.11, 567);
demo <int, char> d2 (200, ‘A’);
d1.show();
d2.show();
return 0;
}

Manipal University Jaipur B2114 Page No.: 272


Object Oriented Programming – C++ Unit 12

The output of the above program will be:


1.11 and 456
200 and A
Self Assessment Questions
1. ________ enables us to define generic classes and functions and
hence provides support for generic programming.
2. The class template definition is similar to an ordinary class definition
except the prefix ___________.

12.3 Function Templates


In C++, we can create functions that use variable types. These function
templates serve as an outline or pattern for a group of functions that differ in
the types of parameters they use. A group of functions that are generated
from the same template is often called a family of functions. In a function
template, at least one parameter is generic, or parameterized, it means that
one parameter can stand for any type number of C++ types. You can write a
single function template definition. Based on the argument types provided in
calls to the function, the compiler automatically instantiates separate object
code functions to handle each type of call appropriately.
12.3.1 Implementing Function Templates
The template definition should have the following information:
 the keyword template
 a left angle bracket (<)
 a list of generic types, separated with comas if more than one type is
needed
 a right angle bracket (>)
Each generic type in the list of generic types has two parts:
 the keyword class
 an identifier that represents the generic type
The general format of a function template is as follows:
template < class T>
retruntype function name (arguments of type T)
{
//body of function with type T wherever appropriate
}
Manipal University Jaipur B2114 Page No.: 273
Object Oriented Programming – C++ Unit 12

The function template is similar to class template. We must use the template
parameter T as and when necessary in the function body and in its
argument list.
Function templates are implemented like regular functions, except they are
prefixed with the keyword template. Here is a sample with a function
template.
#include <iostream>
using namespace std;
//max returns the maximum of the two elements
template <class T>
T max(T a, T b)
{
return a > b ? a : b;
}

Using the keyword class in the template definition does not


necessarily mean that T stands for a programmer-created class
type, but it may. Despite the keyword-class, T can represent a
simple scalar type such as int. T is simply a placeholder for the type
that will be used at each location in the function definition where T
appears.
12.3.2 Using Template Functions
As mentioned earlier you can use the function templates as regular
functions. When the compiler sees an instantiation of the function template,
for example: the call max(10, 15) in function main, the compiler generates a
function max(int, int). Similarly, the compiler generates definitions for
max(char, char) and max(float, float) in this case.
#include <iostream>
using namespace std;
//max returns the maximum of the two elements
template <class T>
T max(T a, T b) {
return a > b ? a: b;
}
void main() {

B2114 Page No.: 274


Object Oriented Programming – C++ Unit 12

cout << "max(10, 15) = " << max(10, 15) << endl;
cout << "max('k', 's') = " << max('k', 's') << endl;
cout << "max(10.1, 15.2) = " << max(10.1, 15.2) << endl;
}
Output:
max(10, 15) = 15
max('k', 's') = s
max(10.1, 15.2) = 15.2
12.3.3 Function templates with multiple parameters
Multiple parameters are supported by function templates. We can write a
function that compares three parameters and returns the largest of the
three. For example, in the program code shown below the function template
named findLargest(), returns the largest amongst the three parameters.
template <class T>
T findLargest(T x, T y, T z)
{
T max;
if( x > y)
max= x;
else
max = y;
if ( z> max)
max = z;
return max;
}
The three parameters are passed in the findLargest() function in the above
code. A temporary variable max is declared within this function. The data
type of max variable is the same as that of the function parameters. i.e., if
the three integers are passed to the function, then max is also an integer; if
three doubles are passed, then max is also of type double. If the first
parameter x passed to the findLargest() is larger than the second parameter
y, then x s assigned to max otherwise y is assigned to max. Then if the third
parameter z is larger than max, then z is assigned to max. And finally value
of max is returned. The variables x, y, z and max may be of any type for
which the greater than (>)operator and the assignment (+) operator have

Manipal University Jaipur B2114 Page No.: 275


Object Oriented Programming – C++ Unit 12

been defined, but x, y, z and max must be of the same type because they
are all defined to be the same type named T.
12.3.4 Overloading Function Templates
Like ordinary functions it is possible to overload function templates. In this
section, we are going to discuss overloading when the templates are
involved. That is, you can have many function definitions with the same
function name so that when that name is used in function call, the C++
compiler decides which of the functions to be called.
Let us see the following program to understand the overloading of function
templates,
//maximum of two int values
int const& max (int const& a, int const& b)
{
return a < b ? b : a;
}
//maximum of two values of any type
template <typename>
T const& max (T const& a, T const& b)
{
return a < b ? b:a;
}
//maximum of three values of any type
template<typename T>

T const& max (T const& a, T const& b, T const& c)


{
return :: max (:: max (a, b), c);
}

int main()
{
max(4, 5, 6); //calls the template for three arguments
max(8.1, 9,.1); //calls max<double> (by argument detection)
max (‘c’, ‘d’); // calls max<char> (by argument detection)
max(7,42) //calls the nontemplate for two ints
max< > (7, 42); //class max<int> (by argument deduction
Manipal University Jaipur B2114 Page No.: 276
Object Oriented Programming – C++ Unit 12

max<double>(7, 42); // calls max<double> (no argument detection)


max (‘c’, 55.5); //calls the non-template of two ints
}
As you can see in this example, a non-template function can coexist with a
template function that has the same name and can be instantiated with the
same type. All other factors being equal, the overload resolution process
normally prefers this non-template over one generated from the template.
The call of the following function is under this rule.
max(7, 42) //both int values match the non-template function
However, If the template can generate a better match, that template is
selected.
This can be illustrated by the following function calls:
max (8.1, 9.1) // calls the max<double> (by argument detection)
max (‘c’, ‘d’) //class the max<char> (by argument detection)
It is also possible to specify explicitly an empty template argument list. This
syntax indicates that only templates may resolve a call, but all the template
parameters should be deduced from the call arguments:
max<>(7,42) //calls max <int> (by argument detection).
In the function call max (‘c’, 55.5) both the arguments will be converted into
int by automatic type conversion. Because the automatic type conversion is
not considered for templates but is considered for ordinary functions.
Self Assessment Questions
3. The _________ serves as an outline or pattern for a group of functions
that differs in the types of parameters they use.
4. Like ordinary functions it is possible to overload function templates.
(True/ False).

12.4 Template Instantiation


When the compiler generates a class, function or static data members from
a template, it is referred to as template instantiation.
 When a class is generated from a class template, it is called a
generated class.

Manipal University Jaipur B2114 Page No.: 277


Object Oriented Programming – C++ Unit 12

 When a function is generated from a function template, it is called a


generated function.
 When a static data member is generated from a static data member
template, it is called a generated static data member.
The compiler generates a class, function or static data members from a
template when it sees an implicit instantiation or an explicit instantiation of
the template.
1. Consider the following sample. This is an example of implicit
instantiation of a class template.
template <class T>
class Z
{
public:
Z() {};
~Z() {};
void f(){};
void g(){};
};
int main() {
Z<int> zi; //implicit instantiation generates class Z<int>
Z<float> zf; //implicit instantiation generates class Z<float>
return 0;
}
2. Consider the following sample. This sample uses the template class
members Z<T>::f() and Z<T>::g().
template <class T>
class Z {
public:
Z() {};
~Z() {};
void f(){};
void g(){};
};
int main() {
Z<int> zi; //implicit instantiation generates class Z<int>

Manipal University Jaipur B2114 Page No.: 278


Object Oriented Programming – C++ Unit 12

zi.f(); //and generates function Z<int>::f()


Z<float> zf; //implicit instantiation generates class Z<float>
zf.g(); //and generates function Z<float>::g()
return 0;
}
This time in addition to the generating classes Z<int> and Z<float>, with
constructors and destructors, the compiler also generates definitions for
Z<int>::f() and Z<float>::g(). The compiler does not generate definitions
for functions, nonvirtual member functions, class or member class that
does not require instantiation. In this example, the compiler did not
generate any definitions for Z<int>::g() and Z<float>::f(), since they were
not required.
3. Consider the following sample. This is an example of explicit
instantiation of a class template.
template <class T>
class Z {
public:
Z() {};
~Z() {};
void f(){};
void g(){};
};
int main() {
template class Z<int>; //explicit instantiation of class Z<int>
template class Z<float>; //explicit instantiation of class Z<float>
return 0;
}
4. Consider the following sample. Will the compiler generate any classes in
this case? The answer is NO.
template <class T>
class Z {
public:
Z() {};
~Z() {};
void f(){};

Manipal University Jaipur B2114 Page No.: 279


Object Oriented Programming – C++ Unit 12

void g(){};
};
int main() {
Z<int>* p_zi; //instantiation of class Z<int> not required
Z<float>* p_zf; //instantiation of class Z<float> not required
return 0;
}
This time the compiler does not generate any definitions! There is no
need for any definitions. It is similar to declaring a pointer to an
undefined class or structure.
5. Consider the following sample. This is an example of implicit
instantiation of a function template.
//max returns the maximum of the two elements
template <class T>
T max(T a, T b)
{
return a > b ? a : b;
}
void main() {
int I;
I = max(10, 15); //implicit instantiation of max(int, int)
char c;
c = max('k', 's'); //implicit instantiation of max(char, char)
}
In this case the compiler generates functions max(int, int) and max(char,
char). The compiler generates definitions using the template function
max.
6. Consider the following sample. This is an example of explicit
instantiation of a function template.
template <class T>
void Test(T r_t) {
}
int main() {
//explicit instantiation of Test(int)
template void Test<int>(int);

Manipal University Jaipur B2114 Page No.: 280


Object Oriented Programming – C++ Unit 12

return 0;
}
In this case the compiler would generate function Test(int). The compiler
generates the definition using the template function Test.
7. If an instantiation of a class template is required, and the template
declared but not defined, the program is ill-formed.
template <class T> class X ;
int main() {
X<int> xi;
return 0;
}
8. Instantiating virtual member functions of a class template that does not
require instantiation is implementation defined. For example, in the
following sample, virtual function X<T>::Test() is not required, VC5.0
generates a definition for X<T>::Test.
template <class T>
class X {
public:
virtual void Test() {}
};
int main() {
X<int> xi; //implicit instantiation of X<int>
return 0;
}
In this case the compiler generates a definition for X<int>::Test, even if it
is not required.
Self Assessment Questions
5. A class generated from a class template is called ________________.
6. Instantiating virtual member functions of a class template that does not
require instantiation is implementation defined. (True/False)

12.5 Class Template Specialization


In some cases it is possible to override the template-generated code by
providing special definitions for specific types. This is called template

Manipal University Jaipur B2114 Page No.: 281


Object Oriented Programming – C++ Unit 12

specialization. The following example defines a template class


specialization for template class stream.
#include <iostream>
using namespace std;
template <class T>
class stream
{
public:
void f()
{ cout << "stream<T>::f()"<< endl;}
};
template <>
class stream<char>
{
public:
void f() { cout << "stream<char>::f()"<< endl; }
};
int main()
{
stream<int> si;
stream<char> sc;
si.f();
sc.f();
return 0;
}
Output:
stream<T>::f()
stream<char>::f()
In the above example, stream<char> is used as the definition of streams of
chars; other streams will be handled by the template class generated from
the class template.
12.5.1 Template Class Partial Specialization
You may want to generate a specialization of the class for just one
parameter, for example
//base template class

Manipal University Jaipur B2114 Page No.: 282


Object Oriented Programming – C++ Unit 12

template<typename T1, typename T2>


class X {
};
//partial specialization
template<typename T1>
class X<T1, int> {
};
int main() {
// generates an instantiation from the base template
X<char, char> xcc ;
//generates an instantiation from the partial specialization
X<char, int> xii ;
return 0 ;
}
A partial specialization matches a given actual template argument list if the
template arguments of the partial specialization can be deduced from the
actual template argument list.

12.6 Template Function Specialization


As already mentioned in sub-unit 12.5, in some cases it is possible to
override the template-generated code by providing special definitions for
specific types using template specialization. The following example
demonstrates a situation where overriding the template generated code
would be necessary:
#include <iostream>
using namespace std;
//max returns the maximum of the two elements of type T,
//where T is a class or data type for which operator> is defined.
template <class T>
T max(T a, T b)
{
return a > b ? a : b;
}
int main() {
cout << "max(10, 15) = " << max(10, 15) << endl ;
cout << "max('k', 's') = " << max('k', 's') << endl ;
Manipal University Jaipur B2114 Page No.: 283
Object Oriented Programming – C++ Unit 12

cout << "max(10.1, 15.2) = " << max(10.1, 15.2) << endl ;
cout << "max(\"Aladdin\", \"Jasmine\") = " << max("Aladdin",
"Jasmine") << endl ;
return 0 ;
}
Output:
max(10, 15) = 15
max('k', 's') = s
max(10.1, 15.2) = 15.2
max("Aladdin", "Jasmine") = Aladdin
Not quite the expected results! Why did that happen? The function call
max("Aladdin", "Jasmine") causes the compiler to generate code for
max(char*, char*), which compares the addresses of the strings! One can
use template specializations to correct special cases like these or to provide
more efficient implementations for certain types. The above example can
be rewritten with specialization as follows:
#include <iostream>
#include <cstring>
using namespace std;
//max returns the maximum of the two elements
template <class T>
T max(T a, T b) {
return a > b ? a : b ;
}
// Specialization of max for char*
template <>
char* max(char* a, char* b) {
return strcmp(a, b) > 0 ? a : b ;
}
int main() {
cout << "max(10, 15) = " << max(10, 15) << endl ;
cout << "max('k', 's') = " << max('k', 's') << endl ;
cout << "max(10.1, 15.2) = " << max(10.1, 15.2) << endl ;

Manipal University Jaipur B2114 Page No.: 284


Object Oriented Programming – C++ Unit 12

cout << "max(\"Aladdin\", \"Jasmine\") = " << max("Aladdin", "Jasmine")


<< endl ;
return 0 ;
}
Output:
max(10, 15) = 15
max('k', 's') = s
max(10.1, 15.2) = 15.2
max("Aladdin", "Jasmine") = Jasmine

Self Assessment Questions


7. ___________ is to override the template-generated code by providing
special definitions for specific types.

12.7 Template Parameters


1. C++ templates allow one to implement a generic Queue<T> template
that has a type parameter T. T can be replaced by actual types, for
example, Queue<Customers>, and C++ will generate the class
Queue<Customers>. For example,
template <class T>
class Stack{
};
Here T is a template parameter, also referred to as type-parameter.
2. In C++ it is allowed to specify a default template parameter, so the
definition could now look like:
template <class T = float, int elements = 100> Stack { ....};
Then a declaration such as
Stack<> mostRecentSalesFigures;
would instantiate (at compile time) a 100 element Stack template class
named mostRecentSalesFigures of float values; this template class
would be of type Stack<float, 100>.
Note, C++ also allows non-type template parameters. In this case,
template class Stack has an int as a non-type parameter. Once a default
parameter is declared all subsequent parameters must have defaults.

Manipal University Jaipur B2114 Page No.: 285


Object Oriented Programming – C++ Unit 12

3. Default arguments cannot be specified in a declaration or a definition of


a specialization. For example,
template <class T, int size>
class Stack {
};
//defined as a non-template class
template <class T, int size = 10>
class Stack<int, 10> {
};
int main() {
Stack<float,10> si;
return 0;
}
4. A type-parameter defines its identifier to be a type-name in the scope of
the template declaration, and cannot be re-declared within its scope
(including nested scopes). For example,
template <class T, int size>
class Stack {
int T;
void f()
{
char T; //error type-parameter re-defined.
}
};
class A {};
int main() {
Stack<A,10> si;
return 0;
}
5. The value of a non-type-parameter cannot be assigned to or have its
value changed. For example,
template <class T, int size>
class Stack {

Manipal University Jaipur B2114 Page No.: 286


Object Oriented Programming – C++ Unit 12

void f()
{
size++ ; //error change of template argument value
}
};
int main() {
Stack<double,10> si ;
return 0 ;
}
6. A template-parameter that could be interpreted as either a parameter-
declaration or a type-parameter, is taken as a type-parameter. For
example,
class T {};
int i;
template <class T, T i>
void f(T t) {
T t1 = i; //template arguments T and i
::T t2 = ::i; //globals T and i
}
int main() {
f('s');
return 0 ;
}
Self Assessment Questions
8. C++ allows you to specify a default template parameter. (True/False)
9. __________________________ cannot be specified in a declaration
or a definition of a specialization.

12.8 Static Members and Variables


1. Each template class or function generated from a template has its own
copies of any static variables or members.
2. Each instantiation of a function template has its own copy of any static
variables defined within the scope of the function. For example,
template <class T>
class X {

Manipal University Jaipur B2114 Page No.: 287


Object Oriented Programming – C++ Unit 12

public:
static T s;
};
int main() {
X<int> xi ;
X<char*> xc ;
}
Here X<int> has a static data member s of type int and X<char*> has a
static data member s of type char*.
3. Static members are defined as follows:
#include <iostream>
using namespace std;
template <class T>
class X {
public:
static T s;
};
template <class T> T X<T>::s = 0 ;
template <> int X<int>::s = 3 ;
template <> char* X<char*>::s = "Hello" ;
int main() {
X<int> xi ;
cout << "xi.s = " << xi.s << endl ;
X<char*> xc ;
cout << "xc.s = " << xc.s << endl ;
return 0 ;
}
Program Output:
xi.s = 10
xc.s = Hello

Manipal University Jaipur B2114 Page No.: 288


Object Oriented Programming – C++ Unit 12

4. Each instantiation of a function template has its own copy of the static
variable. For example,
#include <iostream>
using namespace std;
template <class T>
void f(T t) {
static T s = 0;
s = t;
cout << "s = " << s << endl;
}
int main() {
f(10);
f("Hello");
return 0;
}
Program Output:
s = 10
s = Hello
Here f<int>(int) has a static variable s of type int, and f<char*>(char*)
has a static variable s of type char*.

12.9 Templates and Friends


We have already studied that functions and classes can be declared as
friends of non-template classes. With class templates friendship can be
established between a class template and a global function, a member
function of another class (possibly a template class), or even an entire class
(possible template class). Throughout this section we assume that we have
defined a class template for a class named x with a single type parameter T,
as shown below:
template <typename T> class X

Manipal University Jaipur B2114 Page No.: 289


Object Oriented Programming – C++ Unit 12

The table 12.1 lists the results of declaring different kinds of friends of a
class.
Table 12.1: Different kinds of friends of a class

Class friend declaration


Results of giving friendship
Template in class template X
makes f1() a friend of all
template
instantiations of template X. For
class <T> friend void f1();
example, f1() is a friend of
class X
X<int>, X<A>, and X<Y>.
For a particular type T for
template example, float, makes
friend void
class <T> f2(X<float>&) a friend of class
f2(X<T>&);
class X X<float> only. f2(x<float>&)
cannot be a friend of class X<A>.
friend A::f4(); // A is makes A::f4() a friend of all
template
a user defined class instantiations of template X. For
class <T>
with a member example, A::f4() is a friend of
class X
function f4(); X<int>, X<A>, and X<Y>.
For a particular type T for
friend
example, float, makes
template C<T>::f5(X<T>&); //
C<float>::f5(X<float>&) a friend
class <T> C is a class template
of class X<float> only.
class X with a member
C<float>::f5(x<float>&) cannot be
function f5
a friend of class X<A>.
makes every member function of
template
class Y a friend of every template
class <T> friend class Y;
class produced from the class
class X
template X.
when a template class is
template instantiated with a particular type
class <T> friend class Z<T>; T, such as a float, all members of
class X class Z<float> become friends of
template class X<float>.

Manipal University Jaipur B2114 Page No.: 290


Object Oriented Programming – C++ Unit 12

12.10 Templates and Multiple-file Projects


From the compiler’s point of view, templates are not considered as normal
functions or classes. They are compiled on demand. It means that the code
of a template function is not compiled until an instantiation with specific
template arguments is required. The moment when a need for an
instantiation arises, a function is generated by the compiler which is
specifically for those arguments from the template
When the project expands, the code of program is distributed in many
source code files. In such situations the interface and implementations are
separated. For example in library functions the interface contains the
declaration of prototypes of all the functions that can be called. These
functions are declared in a header file having .h extension and the
definitions of functions i.e. implementation is contained in a different file with
C++ code.
Because templates are compiled when required, this forces a restriction for
multi-file projects: the implementation (definition) of a template class or
function must be in the same file as its declaration. That means that the
interface cannot be separated in different header file. And it is required to
include both the interface and implementation in any file using the
templates.
Since no code is generated until a template is instantiated when required,
compilers are prepared to allow the inclusion more than once of the same
template file with both declarations and definitions in a project without
generating linkage errors.
Self Assessment Questions
10. Each template class or function generated from a template has its own
copies of any static variables or members. (True/False)
11. Templates are compiled when required. (True/False)
12. With _________, friendship can be established between a class
template and a global function, a member function of another class
(possibly a template class), or even an entire class.

Manipal University Jaipur B2114 Page No.: 291


Object Oriented Programming – C++ Unit 12

12.11 Summary
 Templates are a fairly new addition to the C++ language, and were only
recently standardized on. They are also one of the more useful features
of C++. They allow you to create classes that are more dynamic in
terms of the types of data they can handle.
 A class template is a class that is implemented with one or more type
parameters left open. The class template definition is similar to an
ordinary class definition except the prefix template<class T> and the
use of type T.
 This is a process of creating a specific class from a class template and
it is called as instantiation.
 It is possible to use more than one generic data type in a class template
 In C++ we can create functions that use variable types. These function
templates serve as an outline or pattern for a group of functions that
differ in the types of parameters they use.
 Function templates are implemented like regular functions, except they
are prefixed with the keyword template.
 Multiple parameters are supported by function templates.
 Like ordinary functions it is possible to overload function templates.
 When the compiler generates a class, function or static data members
from a template, it is referred to as template instantiation.
 In some cases it is possible to override the template-generated code by
providing special definitions for specific types. This is called template
specialization.
 Each template class or function generated from a template has its own
copies of any static variables or members.
 With class templates, friendship can be established between a class
template and a global function, a member function of another class or
even an entire class.
 Compiling templates when required forces a restriction for multi-file
projects: the implementation (definition) of a template class or function
must be in the same file as its declaration

Manipal University Jaipur B2114 Page No.: 292


Object Oriented Programming – C++ Unit 12

12.12 Terminal Questions


1. Explain with the help of an example the method to implement a class
template.
2. Explain the implementation of function template with multiple
parameters and procedure to overload function templates.
3. Discuss template function specialization.
4. Write a note on template parameters.
5. How static members are declared within a template class? Explain with
an example.
6. Describe the various types of template friendships.

12.13 Answers
Self Assessment Question
1. Templates
2. template<class T>
3. Function templates
4. True
5. Generated class
6. False
7. Template specialization
8. True
9. Default arguments
10. True
11. True
12. Class templates

Terminal Questions
1. It is a simple process to create a generic class using a template with
anonymous type. The general format of class template is as follows:
class classname
{
//class member specification with anonymous type T wherever
appropriate.
………….
};
For more details refer section 12.2.1

Manipal University Jaipur B2114 Page No.: 293


Object Oriented Programming – C++ Unit 12

2. Multiple parameters are supported by function templates. We can write


a function that compares three parameters and returns the largest of the
three. For example, in the program code shown below the function
template named findLargest(), returns the largest amongst the three
parameters.
Like ordinary functions, it is possible to overload function templates.
That means you can have many function definitions with the same
function name so that when that name is used in function call, it is
decided by the C++ compiler that which one of the functions to be
called.
For more details refer sections 12.3.3 and 12.3.4.
3. In some cases it is possible to override the template-generated code by
providing special definitions for specific types. This is called template
specialization.
For more details refer section 12.6
4. C++ templates allow one to implement a generic Queue<T> template
that has a type parameter T. T can be replaced with actual types, for
example, Queue<Customers>, and C++ will generate the class
Queue<Customers>.
For example,
template <class T>
class Stack{
};
For more details refer section 12.7.
5. Each template class or function generated from a template has its own
copies of any static variables or members. Each instantiation of a
function template has its own copy of any static variables defined within
the scope of the function.
For more details refer section 12.8
6. Friendship can be established between a class template and a global
function, a member function of another class, or even an entire class.
For more details refer section 12.9.

Manipal University Jaipur B2114 Page No.: 294


Object Oriented Programming – C++ Unit 12

References:
 Object Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
 Object Oriented Programming In C++, 4/E by Robert Lafore. Pearson
Education India.
 C++ Templates: The Complete Guide, By David Vandevoorde, Nicolai
M. Josuttis. Addison Wesley Professional.
 C++ for Programmers, By Paul Deitel, Harvey M. Deitel. Pearson
Education.

Manipal University Jaipur B2114 Page No.: 295


Object Oriented Programming – C++ Unit 13

Unit 13 Standard Template Library


Structure:
13.1 Introduction
Objectives
13.2 STL Components
Containers
Iterators
Algorithms
Functions Objects
13.3 Sequence Containers
Vector
Deque
List
13.4 Associative Containers
13.5 Derived Containers
13.6 Iterators
13.7 Summary
13.8 Terminal Questions
13.9 Answers

13.1 Introduction
In the previous unit you studied about the templates in C++. You got a clear
idea of ‘class’ and ‘function’ templates. You also studied about the template
instantiation, template specialization along with the template parameters.
You also got some idea of using static members and variables in templates
as well as using friend functions in templates. In this unit you will study in
detail the standard template library.
Many people felt that C++ classes were inadequate in situations requiring
containers for user-defined types, and methods for common operations on
them. For example, you might need self-expanding arrays, which can easily
be searched, sorted, added to or removed from without messing with
memory reallocation and management. Other Object-oriented languages
used templates to implement this sort of thing, and hence they were
incorporated into C++.

Manipal University Jaipur B2114 Page No.: 296


Object Oriented Programming – C++ Unit 13

To assist the users of C++ in generic programming, Alexender Stepnov and


Meng Lee of Hewlett Packard developed a general purpose templatized
classes and functions that could be used as a standard approach for the
storing and processing of data. The standard template library is the
collection of these generic classes and functions.
STL is a C++ library of container classes, algorithms, and iterators; it
provides many of the basic algorithms and data structures of computer
science. The STL is a generic library, i.e., its components are heavily
parameterized: almost every component in the STL is a template. You
should make sure that you understand how templates work in C++ before
you use the STL.
Objectives:
After studying this unit you should be able to:
 explain the importance of STL
 list and explain the STL components
 list and explain types of containers
 explain the role of iterators in STL

13.2 STL Components


There are many components present in STL. But there are three major
components in STL namely:
 Containers
 Algorithms
 Iterators.
These components work together to provide support to a variety of
programming solutions. Figure 13.1 shows the relationship between the
three components of STL. Algorithms employ iterators to perform operations
stored in containers.

B2114 Page No.: 297


Object Oriented Programming – C++ Unit 13

Figure 13.1: Relationship between the three STL components

13.2.1 Containers
The containers are objects that hold data of the same type. It is a way data
is organized in memory. The STL containers are implemented by template
classes, and hence, can be customized to hold many data types.
Very many container types are provided by STL which represents objects
that contain other objects. The major ones are sequence containers,
associative containers and derived containers. The classification of
containers is shown in figure 13.2.

Containers

Sequence Associative Containers Derived Containers


Containers
set stack
vector multiset queue
deque map priority_queue
list multimap

Figure 13.2: Three major categories of containers

Manipal University Jaipur B2114 Page No.: 298


Object Oriented Programming – C++ Unit 13

As you can see in figure 13.2, the standard sequence containers include
vector, deque and list. Data is stored in linear sequence in sequence
containers. The standard associative containers can be categorized into set,
multiset, map and multimap. Associative containers are a generalization of
sequences. Sequences are indexed by integers; associative containers can
be indexed by any type. The derived containers can be classified into three
types i.e., stack, queue and priority queue.
13.2.2 Iterators
An iterator is an object (like a pointer) that points to an element in a
container. Iterators can be used to move through the contents of the
container. Iterators are handled just like pointers. Iterators can be
incremented or decremented. They connect algorithms with containers, and
play an important role in the manipulation of data stored in the container.
Iterators are like location specifiers for containers or streams of data, in the
same way that an int* can be used as a location specifier for an array of
integers, or an ifstream can be used as a location specifier for a file.
The STL implements five different types of iterators. These are: input
iterators (which can only be used to read a sequence of values), output
iterators (which can only be used to write a sequence of values), forward
iterators (which can be read, written to, and moved forward), bidirectional
iterators (which are like forward iterators but can also move backwards) and
random access iterators (which can move freely any number of steps in one
operation). The table 13.1 shown below illustrates the iterators and their
characteristics:
Table 13.1: Iterators and their characteristics
Access Direction of
Iterator I/O capability Remark
Method movement
Input Linear Forward Only Read Only Cannot be saved
Output Linear Forward Only Write only Cannot be saved
Forward Linear Forward Only Read/Write Cannot be saved
Bidirectional Linear Forward and Read/Write Cannot be saved
backward
Random Random Forward and Read/Write Cannot be saved
backward

It is possible to have bidirectional iterators act like random access iterators,


as moving forward ten steps could be done by simply moving forward a step
Manipal University Jaipur B2114 Page No.: 299
Object Oriented Programming – C++ Unit 13

at a time, a total of ten times. However, having distinct random access


iterators offers efficiency advantages. For example, a vector would have a
random access iterator, but a list only a bidirectional iterator.
Iterators are the major features which allow the generality of the STL. For
example, an algorithm to reverse a sequence can be implemented using
bidirectional iterators, and then the same implementation can be used on
lists, vectors and deques. User-created containers have to provide only an
iterator which implements one of the 5 standard iterator interfaces, and all
the algorithms provided in the STL can be used on the container.
This generality also comes at a price at times. For example, performing a
search on an associative container such as a map or set can be much
slower while using iterators than by calling member functions offered by the
container itself. This is because an associative container's methods can
take advantage of knowledge of the internal structure, which is opaque to
algorithms using iterators.
13.2.3 Algorithms
Algorithms are functions that can be used across a variety of containers for
processing their contents. The STL algorithms are template C++ functions
to perform operations on containers. Although each container provides
functions for its basic operations, more than sixty standard algorithms are
provided by STL to support more extended or complex operations. Standard
algorithms also allow us to work with two different types of containers at the
same time. In order to be able to work with many types of containers, the
algorithms do not take containers as arguments. Instead, they take iterators
that specify part or all of a container. In this way we can use algorithms to
work on entities which are not the containers. For example, we can use the
copy function to copy data from standard input into a vector. Numerous
algorithms used to perform operations such as searching and sorting are
provided in the STL; each of them is implemented to require a certain level
of iterator (and therefore will work on any container that provides an
interface by iterators).
The algorithms include sorting operations (sort, merge, min, max, etc.),
searching operations (find, count, equal, etc.), mutating operations
(transform, replace, fill, rotate, shuffle), and generalized numeric operations
(accumulate, adjacent difference, etc.).

Manipal University Jaipur B2114 Page No.: 300


Object Oriented Programming – C++ Unit 13

13.2.4 Function objects


The function object is a function that has been wrapped in a class so that it
looks like an object. The class would have only one member function, an
overloaded() operator and no data. This class is templatized to enable its
use with different data types. It is used as arguments to certain containers
and algorithms. For example the statement
sort(array, array+5, greater<int>());
uses the function object greater<int>() to sort the elements contained in
array in the descending order.
It is useful in keeping and retrieving state information in functions passed
into other functions. Regular function pointers can also be used as function
objects. Function objects are STL's way of representing "executable data".
For example, one of the STL algorithms is for_each. This applies a function
to each object in a container. You need to be able to specify its function to
each object in the container.
Self Assessment Questions:
1. The three major components in STL are_________,________ and
_______.
2. The containers are objects that hold data of the same type.
3. ________ is an object that points to an element in a container.
4. The _________ are template C++ functions to perform operations on
containers.

13.3 Sequence Containers


Sequence containers store elements in a linear sequence, like a line, as
shown in figure 13.3 below:

Figure 13.3: Elements in a sequence containers

Manipal University Jaipur B2114 Page No.: 301


Object Oriented Programming – C++ Unit 13

Each element is related to other elements by its position along the line.
They all expand themselves to allow insertion of elements, and all of them
support a number of operations on them.
There are three types of sequence containers in the STL. These, as their
name suggests, store data in linear sequence. They are the vector, deque
and list:
 vector<Type>
 deque<Type>
 list<Type>
To choose a container, decide what sort of operations you will most
frequently perform on your data, and then, use the following table to help
you.
Table 13.2: Time overhead of operations on sequence containers

Operation Vector Deque List


Access first element constant constant constant
Access last element constant constant constant
Access random element constant constant linear
Add/delete at beginning Linear constant constant
Add/delete at end constant constant constant
Add/delete at random Linear linear constant

Each container has attributes suited to particular applications. The


subsections and code samples below should further clarify when and how to
use each type of the sequence container.
13.3.1 Vector
#include <vector>
The vector class is similar to an array. Its syntax is also similar to an array
e.g. vector[3]. Vector allows random access of the elements, with a constant
time overhead, O(1). Performing insertion and deletion at the end of vectors
is cheap. As with strings, no bounds-checking is performed with vectors
when you use the operator [].
There is an overhead of O(N) to perform insertions and deletions at the end
of the vector, where N is the number of vector elements. The reason for this

Manipal University Jaipur B2114 Page No.: 302


Object Oriented Programming – C++ Unit 13

complexity is that the storage is contiguous, and to perform insertions and


deletions in the middle, the elements have to be shuffled to make space for
new entries. Memory overhead of a vector is very low and comparable to a
normal array.
The table 13.3 shows some of the main vector functions:
Table 13.3: Vector functions
Vector access function Purpose
begin() Returns iterator pointing to the first element
end() Returns iterator pointing _after_ the last element
push_back(…) Add an element to the end of vector
pop_back(…) Destroy an element at the end of vector
swap( , ) Swap two elements
insert( , ) Insert a new element
size() The Number of elements in vector
capacity() Element capacity before more memory is needed
empty() True if the vector is empty
[] Random access operator

The example below shows how vectors are used:


#include <stdlib.h>
// C++ STL Headers
#include <algorithm.h.>
#include <iostream.h>
#include <vector.h>
using namespace std;
int main(int argc, char *argv[])
{
int nitems = 0;
int ival;
vector<int> v;
cout << "Enter integers, <Return> after each, <Ctrl>Z to finish:" << endl;
while(cin >> ival, cin.good())
Manipal University Jaipur B2114 Page No.: 303
Object Oriented Programming – C++ Unit 13

{
v.push_back(ival);
cout.width(6);
cout << nitems << ": " << v[nitems++] << endl;
}
if (nitems)
{
sort(v.begin(), v.end());
for (vector<int>::const_iterator viter=v.begin(); viter!=v.end(); ++viter)
cout << *viter << " ";
cout << endl;
}
return(EXIT_SUCCESS);
}
Note how the element sort takes v.begin() and v.end() as range arguments.
This is very common in the STL, and you will meet it again. The STL
provides specialized variants of vectors: the bitset and valarray. The former
allows a degree of array-like addressing for individual bits, and the latter is
intended for numeric use with real or integer quantities. To use them,
include the <bitset> or <valarray> header files (these are not always
supported in current STL implementations). Be careful when you erase() or
insert() elements in the middle of a vector. This can invalidate all existing
iterators. To erase all elements in a vector, use the clear() member function.
13.3.2 Deque
#include <deque>
The double-ended queue, deque (pronounced "deck") has properties similar
to those of a vector. But as you can observe from the name, it is possible to
perform insertions and deletions at both the ends of a deque.

Manipal University Jaipur B2114 Page No.: 304


Object Oriented Programming – C++ Unit 13

The table 13.4 shows some of the main deque functions:


Table 13.4: Deque functions
Deque access function Purpose
begin() Returns iterator pointing to the first element
end() Returns iterator pointing _after_ the last element
push_front(…) Add an element to the front of a deque
pop_front(…) Destroy an element at the front of a deque
push_back(…) Add an element to the end of a deque
pop_back(…) Destroy an element at the end of a deque
swap( , ) Swap two elements
insert( , ) Insert a new element
size() The number of elements in a deque
capacity() Element capacity before more memory is needed
empty() True if the deque is empty
[] Random access operator

It is not easy to perform insertions and deletions at random positions in a


deque. But it is easy - though not as efficiently as in a vector - to access the
elements randomly using an array-like syntax. Like a vector, an erase() or
insert() in the middle can invalidate all existing iterators.
The following program shows a deque representing a deck of cards. The
queue is double-ended, so you could modify it to cheat and deal off the
bottom.
#include <stdlib.h>
// C++ STL Headers
#include <algorithm>
#include <deque>
#include <iostream>
#ifdef _WIN32
using namespace std;
#endif
class Card
Manipal University Jaipur B2114 Page No.: 305
Object Oriented Programming – C++ Unit 13

{
public:
Card() { Card(1,1); }
Card( int s, int c ) { suit = s; card = c; }
friend ostream & operator<<( ostream &os, const Card &card );
int value() { return( card ); }
private:
int suit, card;
};
ostream & operator<<( ostream &os, const Card &card ) {
static const char *suitname[] = { "Hearts", "Clubs", "Diamonds", "Spades"
};
static const char *cardname[] = { "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King" };
return( os << cardname[card.card-1] << " of " << suitname[card.suit] );
}
class Deck {
public:
Deck() { newpack(); };
void newpack() {
for ( int i = 0; i < 4; ++i ) {
for ( int j = 1; j <= 13; ++j ) cards.push_back( Card( i, j ) );
}
}
// shuffle() uses the STL sequence modifying algorithm,
random_shuffle()
void shuffle() { random_shuffle( cards.begin(), cards.end() ); }
bool empty() const { return( cards.empty() ); }
Card twist() { Card next = cards.front(); cards.pop_front(); return(next);
}
private:

Manipal University Jaipur B2114 Page No.: 306


Object Oriented Programming – C++ Unit 13

deque< Card > cards;


};
int main( int argc, char *argv[] ) {
Deck deck;
Card card;
int total, bank_total;
char ch;
// End of declarations ...
while ( 1 ) {
cout << "\n\n ---- New deck ----" << endl;
total = bank_total = 0;
deck.shuffle();
ch = 'T';
while ( 1 ) {
if ( total > 0 && total != 21 ) {
cout << "Twist or Stick ? ";
cin >> ch;
if ( !cin.good() ) cin.clear(); // Catch Ctrl-Z
ch = toupper( ch );
} else {
if ( total == 21 ) ch = 'S'; // Stick at 21
}
if ( ch == 'Y' || ch == 'T' ) {
card = deck.twist();
total += card.value();
cout << card << " makes a total of " << total << endl;
if ( total > 21 ) {
cout << "Bust !" << endl;
break;
}
} else {
Manipal University Jaipur B2114 Page No.: 307
Object Oriented Programming – C++ Unit 13

cout << "You stuck at " << total << "\n"


<< "Bank tries to beat you" << endl;
while ( bank_total < total ) {
if ( !deck.empty() ) {
card = deck.twist();
bank_total += card.value();
cout << card << " makes bank's total " << bank_total << endl;
if ( bank_total > 21 ) {
cout << "Bank has bust - You win !" << endl;
break;
} else if ( bank_total >= total ) {
cout << "Bank has won !" << endl;
break;
}
}
}
break;
}
}
cout << "New game [Y/N] ? ";
cin >> ch;
if ( !cin.good() ) cin.clear(); // Catch Ctrl-Z
ch = toupper( ch );
if ( ch != 'Y' && ch != 'T' ) break;
deck.newpack();
}

return( EXIT_SUCCESS );
}
The card game is a version of pontoon, the idea being to get as close to 21
as possible. Aces are counted as one, and picture cards, as 10. Try to
Manipal University Jaipur B2114 Page No.: 308
Object Oriented Programming – C++ Unit 13

modify the program to do smart addition and count aces as 10 or 1; use a


vector to store your "hand" and give alternative totals.
Notice the check on the state of the input stream after reading in the
character response. This is needed because if you hit, say, <Ctrl>Z, the
input stream will be in an error state, and the next read will return
immediately, causing a loop if you do not clear cin to a good state.
13.3.3 List
#include <list>
It is not possible with lists to access the elements randomly. It is best suited
for applications in which it is required to add or delete elements to and from
the middle. These elements are implemented as double linked list structures
in order to support bidirectional iterators, and are the most memory-hungry
standard containers, vector being the least so. In compensation, lists allow
low-cost growth at either end, or in the middle.
Here are some main list functions:
Table 13.5: List functions

List access function Purpose


begin() Returns the iterator pointing to the first element
end() Returns the iterator pointing _after_ the last element
push_front(…) Add an element to the front of list
pop_front(…) Destroy an element at the front of list
push_back(…) Add an element to the end of list
pop_back(…) Destroy an element at the end of list
swap( , ) Swap two elements
insert( , ) Insert a new element
size() The number of elements in list
capacity() Element capacity before more memory is needed
empty() True if list is empty
sort() Specific function because <algorithm>sort routines
expect random access iterators

Manipal University Jaipur B2114 Page No.: 309


Object Oriented Programming – C++ Unit 13

Following is an example with list in use:


#include <stdlib.h>
// C++ STL Headers
#include <algorithm>
#include <iostream>
#include <list>
#include <string>
using namespace std;
int main( int argc, char *argv[] ) {
string things[] = { "JAF", "ROB", "PHIL", "ELLIOTT", "ANDRZEJ" };
const int N = sizeof(things)/sizeof(things[0]);
list< string > yrl;
list< string >::iterator iter;
for ( int i = 0; i < N; ++i) yrl.push_back( things[i] );
for ( iter = yrl.begin(); iter != yrl.end(); ++iter ) cout << *iter << endl;
// Find "ELLIOTT"
cout << "\nNow look for ELLIOTT" << endl;
iter = find( yrl.begin(), yrl.end(), "ELLIOTT" );
// Mary should be ahead of Elliott
if ( iter != yrl.end() ) {
cout << "\nInsert MARY before ELLIOTT" << endl;
yrl.insert( iter, "MARY" );
} else {
cout << "\nCouldn't find ELLIOTT" << endl;
}
for ( iter = yrl.begin(); iter != yrl.end(); ++iter ) cout << *iter << endl;
return( EXIT_SUCCESS );
}
The loop over elements starts at yrl.begin() and ends just before yrl.end().
The STL .end() functions return iterators pointing just past the last element,
and so, loops should do a != test, and not try to dereference this most likely
invalid, position. Take care not to reuse (e.g. ++) iterators after they have

Manipal University Jaipur B2114 Page No.: 310


Object Oriented Programming – C++ Unit 13

been used with erase() - they will be invalid. Other iterators, however, will
still be valid after erase() or insert().
Self Assessment Questions
5. The three types of sequence containers in the STL are________,
_______ and _______,
6. Vector allows _______ of the elements.
7. _________ are the best suited for applications in which it is required to
add or delete elements to and from the middle.
8. ___________list access function returns iterator pointing to the first
element.

13.4 Associative Containers


Associative containers are designed to support direct access to elements
using keys. They are not sequential. There are four types of associative
containers. They are:
 Set
 Multiset
 Map
 Multimap
All these containers store data in a tree data structure which facilitates fast
searching, deletion, and insertion. However, these are very slow for random
access, and inefficient for sorting.
A number of items can be stored by set and multiset containers, and
provides operations for manipulating them using the values as keys. For
example, a set might store objects of the student class which are ordered
alphabetically using names as keys. We can search for a desired student
using his name as the key. The main difference between a set and a
multiset is that a multiset allows duplicate items while a set does not.
Map and multipmap containers are used to store pairs of items, one called
the key and the other called the value. The values can be manipulated using
the keys associated with them. The values are sometimes called the
mapped values. The main difference between a map and a multimap is that
a map allows only one key for a given value to be stored while multiple keys
are allowed by a multimap.

Manipal University Jaipur B2114 Page No.: 311


Object Oriented Programming – C++ Unit 13

13.5 Derived Containers


Three derived containers are provided by STL. These are- stack, queue and
priority queue. These are also known as container adapters. It is possible to
create stack, queue and priority queues from different sequence containers.
The derived containers are not supported by iterators, and hence, they
cannot be used for data manipulation. However, two member functions i.e.
push and pop, are supported by them for implementation of insertion and
deletion operations.
Self Assessment Questions
9. The four types of associative containers are__________
10. The three derived containers provided by STL are __________.

13.6 Iterators
#include <iterator> // do not normally need you to include this
yourself
An iterator you are already familiar with is a pointer into an array:
char name[] = "Word";
char ch, *p;
p = name; // or &name[0] if you like
ch = p[3]; // Use [] for random access
ch = *(p+3);// Equivalent to the above
*p = 'C'; // Write "through" p into name
while ( *p && *p++ != 'r' ); // Read name through p
We can observe from the above program that the iterators are very flexible
and powerful. As you can see, the above code uses variable ‘p’ in five
different ways. We take it for granted that the compiler generates the
appropriate offset for array elements, using the size of a single element.
The STL iterators you have already met are those returned by the begin()
and end() container access functions, that let you loop over container
elements. For example:
List<int> l;
List<int>::iterator liter; // Iterator for looping over list elements
for ( liter = l.begin(); liter != l.end(); ++liter ) {
*liter = 0;
}
Manipal University Jaipur B2114 Page No.: 312
Object Oriented Programming – C++ Unit 13

The end-of-loop condition is slightly different from normal. Usually the end
condition would be a less than < comparison, but as you can see from the
table of iterator categories below, not all iterators support <, so we
increment the iterator from begin() and stop just before it becomes equal to
end(). It is important to note that, for virtually all STL purposes, end() returns
an iterator "pointing" to an element just after the last element, which it is not
safe to dereference, but is safe to use in equality tests with another iterator
of the same type. Sometimes, better performance is given by the pre
increment operator (++). The reason for this is that there is no requirement
of creating a temporary copy of the previous value, though the compiler
usually optimizes this way.
Iterators can be termed as the generalized abstraction to the pointers which
are designed to allow programmers to access different container types in a
consistent way. To put it more simply, you can think of iterators as a "black
box" between containers and algorithms. When you use a telephone to
directly dial someone in another country, you do not need to know how the
other phone system works. You can talk to the remote person provided it
supports certain basic operations like dialing, ringing, reporting an engaged
tone, hanging up after the call. . Similarly, if the minimum required iterator
types for an algorithm are supported by a container class, then the algorithm
will work with the container. This is important because it means that you can
use algorithms such as the sort and random_shuffle as we've seen in the
earlier examples. The authors of the algorithm are not required to know
which containers they are acting on, provided we support the type of iterator
required by that algorithm. The sort algorithm, for example, only needs to
know how to move through the container elements, how to compare them,
and how to swap them.
There are 5 categories of iterator:
 Random access iterators
 Bidirectional iterators
 Forward iterators
 Input iterators
 Output iterators
They are not all as powerful in terms of the operations they support - most
do not allow random access- as we've seen in the difference between

Manipal University Jaipur B2114 Page No.: 313


Object Oriented Programming – C++ Unit 13

vector and list. The figure 13.4 is the summary of the iterator hierarchy, the
most capable at the top, and the operations supported on the right.
Iterator Type Operations Supported
^ +-------------------------------------+
/ \ \ == != < > >= <= /
/ \ \ ++ -- + - += -= /
/ [] \ \ *p= /
/Random \ \ -> [] /
/ Access \ \ =*p /
/-----------\ \-------------------------/
/Bidirectional\ \ == != ++ -- /
/ \ \ *p= -> =*p /
/-----------------\ \-------------------/
/ Forward \ \ == != ++ /
/ \ \ *p= -> =*p /
/-----------+-----------\ \-------+-----/
/Input | Output\ \ == !=| ++ /
/ | \ \++ ->|*p=/
+--------------+--------------+ \ =*p| /
\ | /
\ |/
\ /
V

Figure 13.4: Iterator Hierarchy

The higher contains all the functionality of the layers below it. In addition, it
contains some more functionalities. Only random iterators provide the ability
to add or subtract an integer to or from the iterator, like *(p+3). If you write
an iterator, it must provide all the operations needed for its category, e.g. if it
is a forward iterator, it must provide ==, !=, ++, *p=, -> and =*p. It is to be
taken care that ++p and p++ are different. ++p increments the iterator and
Manipal University Jaipur B2114 Page No.: 314
Object Oriented Programming – C++ Unit 13

then it returns a reference to itself. p++ first returns a copy of itself, and then
increments.
Operators must retain their conventional meaning, and elements must have
the conventional copy semantics. In a nutshell, this means that the copy
operation must produce an object that, when tested for equality with the
original item, must match. Because only random iterators support integer
add and subtract, all iterators except output iterators provide a distance()
function to find the "distance" between any two iterators. The type of the
value returned is:
template<class C> typename iterator_traits<C>::difference_type
This is useful if, for example, you find() a value in a container, and want to
know the "position" of the element you have found.
map< key_type, data_type >::iterator im;
map< key_type, data_type >::difference_type dDiff;
im = my_map.find( key );
dDiff = distance( my_map.begin(), im );
This operation will be inefficient if the random access iterators are not
supported by the containers because in that case, it will have to "walk
through" the elements comparing the iterators.
Just as you can declare pointers to const objects, you can have iterators to
const elements. The const_ prefix is used for this purpose.
e.g. vector::iterator i; // Similar to my_type *i
vector::const_iterator i; // Similar to const my_type *i
The iterator_traits for a particular class is a collection of information, like the
"iterator tag" category, which helps the STL "decide" on the best algorithm
to use when calculating distances. The calculation is trivial for random
iterators, but if you have only forward iterators, then it may be a case of
slogging through a linked list to find the distance. If you write a new class of
container, then this is one of the things you must be aware of. As it
happens, the vector, list, deque, map and set - all provide at least
Bidirectional iterators, but if you write a new algorithm, you should not
assume any capability better than that which you really need. The lower the

B2114 Page No.: 315


Object Oriented Programming – C++ Unit 13

category of iterator you use in your algorithm, the wider the range of
containers your algorithm will work with.
Although the input and output iterators seem rather poor in capability, in fact
they do add the useful ability to read and write containers to or from files.
This is demonstrated in the program below:
#include <stdlib.h>
// C++ STL Headers
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int main( int argc, char *argv[] ) {
int i, iarray[] = { 1,3,5,7,11,13,17,19 };
fstream my_file("vector.dat",ios::out);// Add |ios::nocreate to avoid
// creation if it doesn't exist
vector<int> v1, v2;
for (i = 0;i<sizeof(iarray)/sizeof(iarray[0]); ++i) v1.push_back(iarray[i]);
// Write v1 to file
copy(v1.begin(),v1.end(), ostream_iterator<int,char>(my_file," "));
cout << "Wrote vector v1 to file vector.dat" << endl;
// Close file
my_file.close();
// Open file for reading or writing
my_file.open( "vector.dat", ios::in|ios::out );
// Read v2 from file
copy( istream_iterator<int,char>(my_file), // Start of my_file
istream_iterator<int,char>(), // Val. returned at eof
inserter(v2,v2.begin()));
cout << "Read vector v2 from file vector.dat" << endl;
for ( vector<int>::const_iterator iv=v2.begin(); iv != v2.end(); ++iv )
cout << *iv << " ";

Manipal University Jaipur B2114 Page No.: 316


Object Oriented Programming – C++ Unit 13

cout << endl;


return(EXIT_SUCCESS);
}
The result of the possible restrictions on an iterator is that most algorithms
have two iterators as their arguments, or (perhaps less safely) an iterator
and a number of elements count. In particular, when you are using iterators,
you need to be aware that it is not a good idea to test an iterator against
NULL, or to test whether one iterator is greater than another. Testing for
equality or inequality is safe except for output iterators, which is why the
loops in the example code use iterator != x.end() as their termination test.

Self Assessment Questions


11. There are _______ categories of iterator.
12. Only random iterators provide the ability to add or subtract an integer to
or from the iterator. (True/False)

13.7 Summary
 STL, is a C++ library of container classes, algorithms, and iterators; it
provides many of the basic algorithms and data structures of computer
science.
 There are many components present in STL. But there are three major
components in STL. They are: containers, algorithms and iterators.
 The containers are objects that hold data of the same type. It is the way
data is organized in memory.
 An iterator is an object (like a pointer) that points to an element in a
container. Iterators can be used to move through the contents of the
container.
 Algorithms are functions that can be used across a variety of containers
for processing their contents.
 The function object is a function that has been wrapped in a class so
that it looks like an object.
 Sequence containers store elements in a linear sequence. There are
three types of sequence containers in the STL- the vector, the deque
and the list.
 The vector class is similar to an array. Vector allows random access of
the elements, with a constant time overhead, O(1). It is possible to
Manipal University Jaipur B2114 Page No.: 317
Object Oriented Programming – C++ Unit 13

perform insertions and deletions at both the ends of Lists. Lists are best
suitable for the applications where it is required to add or delete the
elements to and from the middle.
 Associative containers are designed to support direct access to
elements using keys. They are not sequential. There are four types of
associative containers: set, multiset, map and multimap.
 The derived containers provided by STL are: stack, queue and priority
queue. These are also known as container adapters.

13.8 Terminal Questions


1. List and explain the STL components.
2. Explain sequence containers.
3. Explain associative and derived containers.
4. Discuss on iterators.

13.9 Answers
Self Assessment Questions
1. Containers, algorithms, iterators
2. Containers
3. Iterator
4. STL algorithms
5. Vector, deque and list
6. Random access
7. Lists
8. begin()
9. Set, multiset, amp and multimap
10. Stack, queue and priority queue
11. Five
12. True
Terminal Questions
1. STL provides a number of container types, representing objects that
contain other objects. The STL contains sequence containers and
associative containers. For more details refer section 13.2.
2. There are three types of sequence containers in the STL They are: the
vector, the deque and the list. For more details refer section 13.3.

Manipal University Jaipur B2114 Page No.: 318


Object Oriented Programming – C++ Unit 13

3. Associative containers are designed to support direct access to


elements using keys. They are not sequential. There are four types of
associative containers: set, multiset, map and multimap.
Three derived containers are provided by STL. These are: stack, queue
and priority queue. These are also known as container adapters. For
more details refer section 13.4 and 13.5.
4. The STL iterators are returned by the begin() and end() container
access functions. For more details refer section 13.6.

References:
 Object-Oriented Programming with C++ - Sixth Edition, by
E Balagurusamy. Tata McGraw-Hill Education.
 The C++ Programming Language, fourth edition, by Bjarne Stroustrup.
Addison-Wesley.
 Object-Oriented Programming with ANSI and Turbo C++, by Kamthane
 http://clinuxpro.com/

Manipal University Jaipur B2114 Page No.: 319


Object Oriented Programming – C++ Unit 14

Unit 14 Exception Handling


Structure:
14.1 Introduction
Objectives
14.2 Basics of Exception Handling
14.3 Exception Handling Mechanism
14.4 Throwing Mechanism
14.5 Catching Mechanism
Multiple catch statements
14.6 User Defined Exception Class
14.7 Termination vs. Resumption
14.8 Exception Specifications
unexpected()
set_unexpected()
Catching any exception
14.9 Rethrowing an Exception
14.10 Uncaught Exceptions
terminate()
set_terminate()
14.11 Standard Exceptions
14.12 Programming with Exceptions
When to avoid exceptions
Using exceptions
14.13 Summary
14.14 Terminal Questions
14.15 Answers

14.1 Introduction
In the previous unit you have studied standard template library and its
components. In this unit you will study the concept of exception handling in
C++. The program which we write might have bugs. The common types of
errors which occur in our programs are – logical and syntactic errors. The
reason for logical errors is the poor understanding of the problem and
solution procedure. Syntactic errors occur due to the poor understanding of
the programming language. These errors can be detected by debugging
and testing procedures. Sometimes we come across errors other than the

Manipal University Jaipur B2114 Page No.: 320


Object Oriented Programming – C++ Unit 14

above mentioned ones. These errors are known as exceptions. Exceptions


are run time anomalies or unusual conditions that a program may encounter
while executing. Anomalies might include conditions such as division by
zero, access to an array outside its bounds or running out of memory or disk
space. When such an exceptional condition occurs in a program, it should
be identified and handled effectively. Some built in features are provided by
C++ to detect and handle the exceptions which are basically run-time errors.
Objectives:
After studying this unit you should be able to:
 describe exception, exception handling, and the necessity to have
exception handling.
 explain the usage of try and catch blocks.
 explain the models of exception-handling, and the necessity of
exception specifications.
 discuss the special functions unexpected(), terminate(), and more.
 describe the situations when the exceptions should be avoided and
used.

14.2 Basics of Exception Handling


There are two kinds of exceptions i.e. synchronous and asynchronous
exceptions. Errors like “out of range index” and “overflow” belong to the
category of synchronous exceptions. The errors which occur beyond the
control of the program (like keyboard interrupts) belong to the category of
asynchronous interrupts. The proposed exception handling mechanism in
C++ is designed to handle only asynchronous exceptions.
The aim of exception handling mechanism is to identify an exception and
take necessary action to handle it. 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 actions (handle the exception).
There are two parts in error handling code: one is to detect errors and to
throw exceptions; the other is to catch the exceptions and to take
appropriate actions.

Manipal University Jaipur B2114 Page No.: 321


Object Oriented Programming – C++ Unit 14

14.3 Exception Handling Mechanism


The exception handling mechanism in C++ is built upon the three keywords
named as try, throw and catch. The block of statements which generates
exceptions are prefaced by the “try” keyword. These blocks of statements
are called “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” catches the exception thrown by the throw statement in the try block,
and handles it appropriately. The relationship is shown in figure 14.1:

Figure 14.1: The block throwing exception

When an exception is thrown by a try block, the control is transferred to the


catch block and program leaves the try block. It should be noted that the
exceptions are objects that transmit the information about a problem. If a
type of object thrown matches the arg type in the catch statement, then the
catch block is executed for handling the exception. If it doesn’t match, the
program is aborted with the help of abort() function which is invoked by
default. When there is no exception then the control is transferred to the
statement immediately after the catch block i.e. the catch block is skipped.
The simple try catch mechanism is shown in the program below.
#include<iostream.h>
int main()
{
int a,b;
cout << “ Enter the values of a and b:”;
cin >> a;

Manipal University Jaipur B2114 Page No.: 322


Object Oriented Programming – C++ Unit 14

cin >> b;
int x= a-b;
try
{
if(x!=0)
{
cout << “result (a/x) =” << a/x << “\n”;
}
else //there is an exception
{
throw (x); //throws int object
}
}
catch(int i) //catches the exception
{
cout << “exception caught : divide by zero error\n”;
}
cout << “end”;
return 0;
}
The output of the above program will be:
First run
Enter the values of a and b: 10 5
result (a/x) = 2
end
Second run
Enter the values of a and b: 5 5
exception caught: divide by zero
end
You can see that the first run has shown a successful execution. In the first
run, there is no exception and hence, catch block is skipped and the
execution resumes with the first line after the catch. You can observe that in
second run the ‘divide by zero’ error occurs as the denominator x becomes
zero. Using the object x the exception is thrown. As the data type of the
exception object is int the catch statement containing int type argument
catches the exception and the necessary message is displayed.

Manipal University Jaipur B2114 Page No.: 323


Object Oriented Programming – C++ Unit 14

Most often, exceptions are thrown by functions that are invoked from within
the try blocks. The point at which throw is executed is called throw point.
The control cannot be returned to the throw point once the exception is
thrown to the catch block. This relationship is shown in figure 14.2.

Figure 14.2: Function invoked by try block throwing exception

The code below shown is the general format of this kind of code
type function (arg list) // function with exception
{
……….
………..
throw (object); //throws exception
………
………
}
……….
……….
try
{
………
……… invoke function here

Manipal University Jaipur B2114 Page No.: 324


Object Oriented Programming – C++ Unit 14

……..
}
catch(type arg) // catches exception
{
……….
………. Handles exception here
……….
}
……….
The program below illustrates how a try block invokes a function that
generates an exception.
// throw point outside the try block
#include<iostream.h>
void divide (int x, int y, int z)
{
cout << “\n we are inside the function \n”;
if ((x-y)! =0)
{
int R = z/ (x-y)
cout << “Result =” << R << “\n”;
}
else
{
throw(x-y) //throw point
}
}
void main()
{
try
{
cout << “ we are inside the try block \n”;
divide (10,20,30) //invoke divide()
divide (10,10,10) // invoke divide()
}
catch(int i)
{

Manipal University Jaipur B2114 Page No.: 325


Object Oriented Programming – C++ Unit 14

cout << “caught the exception\n”;


}
}
The output of the above program will be as follows:
we are inside the try block
we are inside the function
Result = – 3
We are inside the function
caught the exception
Self Assessment Questions
1. _______________ are run time unusual conditions that a program may
encounter while executing.
2. The two kinds of exceptions are ________ and _________ exceptions.
3. The block of statements which generates exceptions is prefaced by the
________ keyword
4. When an exception is thrown by a try block, then the control is
transferred to the ________.

14.4 Throwing Mechanism


When an exception that is desired to be handled is detected, then it is
thrown using the “throw” statement. It can take one of the following forms:
throw (exception);
throw exception;
throw; //it is used for rethrowing an exception
The operand object exception may be of any type including constants. It is
also possible to throw objects not intended for error handling.
The catch statement associated with the try block catches the exception
when the exception is thrown. That is the control exits the current try block
and is transferred to the catch block after the try block.

14.5 Catching Mechanism


As you have already studied, we include code for handling exceptions in
catch blocks. A catch block looks like a function definition and it has the
following form:
catch (type arg)
Manipal University Jaipur B2114 Page No.: 326
Object Oriented Programming – C++ Unit 14

{
//statements to manage exceptions
}
Here the type shows the type of the exceptions to be handled by the catch
block. The parameter arg is an optional parameter name. Between the two
braces the exception handling code is placed. The catch statement catches
an exception whose type matches with the type of catch argument. When it
is caught, the code in the catch block is executed.
The parameter can be used in the exception handling code if the parameter
in the catch statement is named. After the handler is executed, the control is
transferred to the statements immediately following the catch blocks.
If an exception is not caught due to mismatch, then the program will
terminate abnormally. If an exception is not caught by catch statements then
the catch block is simply skipped.
14.5.1 Multiple catch statements
Sometimes program segment has more than one condition to throw an
exception. In such cases you can associate more than one catch blocks
with a try block. The syntax to achieve this task is shown below:
try
{
//try block
}
catch (type1 arg)
{
//catch block1
}
catch (type2 arg)
{
//catch block2
}
……..
……..
catch(typeN arg)
{
//catch blockN
}

Manipal University Jaipur B2114 Page No.: 327


Object Oriented Programming – C++ Unit 14

When an exception occurs, there is a search for an appropriate exception


handler. The handler which is matched is executed. After the handler is
executed, the control is transferred to the statement immediately after the
catch block for that try. The program is terminated if there is no match.
If arguments of more than one catch statements match the type of
exception, the first handler that matches with the exception is executed.
The example below shows how the various types of exceptions are handled
by multiple catch statements.
#include<iostream.h>
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
cout << “end of try block\n”;
}
catch (char c) //catch1
{
cout << “ caught a character \n”;
}
catch (int m) //catch2
{
cout << “caught an integer\n”;
}
catch (double d) //catch3
{
cout << “caught a double\n”;
}
cout << “end of try catch system\n”;
}

Manipal University Jaipur B2114 Page No.: 328


Object Oriented Programming – C++ Unit 14

void 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);
}
The output of the above program will be:
testing multiple catches
x==1
caught an integer
end of try cacth system
x==0
caught a character
end of try catch system
x==-2
end of try block
end of try catch system
As you can observe from the above program, when it is executed first the
function test() with x=1 is invoked and hence throws x an int exception.
There is match of type of parameter m in catch2 and hence the catch2
handler is executed. The function test() with x=0 is invoked immediately
after the execution of catch2 handler. This type the function throws ‘x’, a
character type exception and hence the first handler is executed. Finally, the
handler catch3 is executed when a double exception is thrown. You should
note that each time only the handler which catches the exception is
executed and all the rest handlers are skipped.
When no exception is thrown by the try block and if there is a normal
execution, then the control is transferred to the first statement after the last
catch handler associated with that try block.

Manipal University Jaipur B2114 Page No.: 329


Object Oriented Programming – C++ Unit 14

Self Assessment Questions


5. When an exception is detected, it is thrown using the ______________
statement.
6. A catch block looks like a function definition and it has the form
_________.

14.6 User Defined Exception Class


It is possible to create your own exception class and use them as exception
types in your exception handling code instead of using predefined data
types in C++ as exception. You can achieve further control over exception
handling by defining your own exception classes. This can be explained with
the following example.
Let us assume that your program requires an input number in the range of 0
to 100. So instead of using built-in data types of C++, we will write our own
exception classes to validate the input. An out of range exception will be
thrown if user inputs a number greater than 100. And a negative number
exception is thrown if user inputs a number less than zero. To achieve this
we need to create the two exception classes of our own.
First we will create an exception for out of range condition. We define a
class called OutofRange as follows:
class OutofRange
{
public:
OutofRange()
{
cout << “exception :out of range” << endl;
}
};
As you can see above that a constructor is defined by the class that prints a
message to the user whenever an object of this type is constructed.
Similarly, we will create another class for negative number input. The class
definition is as follows:
class NegativeNumber
{
public:

Manipal University Jaipur B2114 Page No.: 330


Object Oriented Programming – C++ Unit 14

NegativeNumber()
{
cout << “exception: Negative input” << endl;
}
};
Again, the class constructor prints an appropriate message on the user
console. Once you create the two user-defined cl for classes for exception,
you need to use these data types in the catch block of your error handler
code. To catch OutofRange, we the catch block will be as shown below:
catch(OutofRange)
{
//error handler code
}
Similarly to catch negative number exception, the catch block will be as
follows:
catch(NegativeNumber)
{
//error handler code
}
Next you need to throw exceptions of these types in your try block. For this
you need to construct an object of the user-defined exception and then use
it as a parameter in the throw statement. For example: to throw OutofRange
exception, the following code will be used:
OutofRange e;
throw e;

14.7 Termination vs. Resumption


There are two basic models in exception-handling theory. In termination
(which is what C++ supports) you assume the error is so critical that there’s
no way to get back to where the exception occurred. Whoever threw the
exception decided there was no way to salvage the situation, and they don’t
want to come back. The alternative is called resumption. It means the
exception handler is expected to do something to rectify the situation, and
then the faulting function is retried, presuming success the second time. If
you want resumption, you still hope to continue execution after the

Manipal University Jaipur B2114 Page No.: 331


Object Oriented Programming – C++ Unit 14

exception is handled, so your exception is more like a function call – which


is how you should set up situations in C++ where you want resumption-like
behavior (that is, don’t throw an exception; call a function that fixes the
problem). Alternatively, place your try block inside a while loop that keeps
reentering the try block until the result is satisfactory.
Historically, programmers using operating systems that supported
resumptive exception handling eventually ended up using termination-like
code and skipping resumption. So although resumption sounds attractive at
first, it isn’t quite so useful in practice. One reason may be the distance that
can occur between the exception and its handler; it’s one thing to terminate
to a handler that’s far away, but to jump to that handler and then back again
may be too conceptually difficult for large systems where the exception can
be generated from many points.
Self Assessment Questions
7. We can achieve further control over exception handling by __________
8. In __________ we assume the error is so critical that there’s no way to
get back to where the exception occurred.

14.8 Exception Specifications


It is not necessary to inform the person using your function what exceptions
you might throw. However, this is not considered as a good practice as he
cannot be sure what code to write to catch all potential exceptions. Of
course, if he has your source code, he can hunt through and look for throw
statements, but very often a library doesn’t come with sources. C++
provides us the facility to inform the user what exceptions are thrown by the
function, so it can be handled by the user. This is the exception specification
and it’s part of the function declaration, appearing after the argument list.
The exception specification reuses the keyword throw, followed by a
parenthesized list of all the potential exception types. So your function
declaration may look like
void f() throw(toobig, toosmall, divzero);
With exceptions, the traditional function declaration
void f();
means any type of exception may be thrown from the function. If you say
void f() throw();

Manipal University Jaipur B2114 Page No.: 332


Object Oriented Programming – C++ Unit 14

it illustrates that a function doesn’t throw any exceptions.


For good coding policy, good documentation, and ease-of-use for the
function caller, you should always use an exception specification when you
write a function that throws exceptions.
14.8.1 unexpected()
If your exception specification claims you’re going to throw a certain set of
exceptions and then you throw something that isn’t in that set, what’s the
penalty? When something other than what appears in the exception
specification is thrown, a special function unexpected() is called.
14.8.2 set_unexpected()
unexpected() is implemented with a pointer to a function, and you can
change its behavior. You do so with a function called set_unexpected()
which, like set_new_handler(), takes the address of a function with no
arguments and void return value. Also, it returns the previous value of the
unexpected() pointer so that you can save it and restore it later. To use
set_unexpected(), you must include the header file <exception>.
14.8.3 Catching any exception
If your function has no exception specification, any type of exception can be
thrown. One solution to this problem is to create a handler that catches any
type of exception. You do this using the ellipses in the argument list:
catch(...) {
cout << "an exception was thrown" << endl;
}
This will catch any exception, so you’ll want to put it at the end of your list of
handlers to avoid pre-empting any that follow it. The ellipses give you no
possibility to have an argument or to know anything about the type of the
exception. It’s a catch-all.
Self Assessment Questions
9. The exception specification reuses the keyword ________, followed by
a parenthesized list of all the potential exception types.
10. ___________ is implemented with a pointer to a function, so you can
change its behavior.

Manipal University Jaipur B2114 Page No.: 333


Object Oriented Programming – C++ Unit 14

14.9 Rethrowing an Exception


Sometimes you may want to rethrow the exception that you just caught,
particularly when you use the ellipses to catch any exception because
there’s no information available about the exception. This is accomplished
by saying throw with no argument:
catch(...) {
cout << "an exception was thrown" << endl;
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.
The program below illustrates how an exception is rethrown and caught.
#include<iosream.h>
void divide (double x, double y)
{
cout << “inside function\n”;
try
{
if(y==0.0)
throw y; //throwing double
else
cout << “division = “ << x/y << “\n”;
}
catch (double) //catch a double
{
cout << “caught double inside function \n”;
throw;
}
cout << “end of function \n\n”;
}
void main()
{
cout << “inside main \n”;
try
{
Manipal University Jaipur B2114 Page No.: 334
Object Oriented Programming – C++ Unit 14

divide(10.5, 2.0);
divide(20.0, 0.0);
}
catch(double)
{
cout << “caught double inside main \n”;
}
cout << “end of main \n”;
}
The output of the above program will be:
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 the group. Instead, it will be caught by an
appropriate catch in 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.

14.10 Uncaught Exceptions


If none of the exception handlers following a particular try block matches an
exception, that exception moves to the next-higher context, that is, the
function or try block surrounding the try block that failed to catch the
exception. (The location of this higher-context try block is not always
obvious at first glance.) This process continues until, at some level, a
handler matches the exception. The exception is considered to be caught at
that point and no further searching takes place.
The exception is uncaught if no handler catches the exception at any level.
An uncaught exception also occurs if a new exception is thrown before an

Manipal University Jaipur B2114 Page No.: 335


Object Oriented Programming – C++ Unit 14

existing exception reaches its handler – the most common reason for this is
that the constructor for the exception object itself causes a new exception.
14.10.1 terminate()
This function is called automatically if an exception is uncaught. Like
unexpected(), terminate is actually a pointer to a function. Its default value is
the Standard C library function abort(), which immediately exits the program
with no calls to the normal termination functions (which means that
destructors for global and static objects might not be called).
No destructors are called for an uncaught exception. If you don’t wrap your
code (including, if necessary, all the code in main()) in a try block followed
by handlers and ending with a default handler (catch(...)) to catch all
exceptions, then you will take your lumps. An uncaught exception should be
thought of as a programming error.
14.10.2 set_terminate()
Using this function, it is possible to install your own terminate () function,
which returns a pointer to the terminate() function you are replacing, so you
can restore it later if you want. Your custom terminate() must take no
arguments and have a void return value. In addition, any terminate() handler
you install must not return or throw an exception, but instead must call some
sort of program-termination function. If terminate() is called, it means the
problem is unrecoverable. Like unexpected(), the terminate() function
pointer should never be null.
Self Assessment Questions
11. Rethrowing is achieved by using throw with ________.
12. Using __________ function it is possible to install your own terminate()
function.

14.11 Standard Exceptions


The set of exceptions used with the Standard C++ library are also available
for your own use. Generally it’s easier and faster to start with a standard
exception class than try to define your own. If the task which we want to
perform cannot be done by the standard then we should derive from it.

Manipal University Jaipur B2114 Page No.: 336


Object Oriented Programming – C++ Unit 14

The following table describes the standard exceptions:


Table 14.1: Standard Exceptions
The base class for all the exceptions thrown by the C++
Exception standard library. You can ask what() and get a result that can
be displayed as a character representation.
Derived from exception. Reports program logic errors, which
logic_error
could presumably be detected before the program executes.
Derived from exception. Reports runtime errors, which can
runtime_error
presumably be detected only when the program executes.

The iostream exception class ios::failure is also derived from exception, but
it has no further subclasses.
The classes in both of the following tables 14.2 and 14.3 can be used as
they are, or they can act as base classes to derive your own more specific
types of exceptions.
Table 14.2: Exceptions derived from logic_error
domain_error Reports violations of a precondition.
Indicates an invalid argument to the function it’s thrown
invalid_argument
from.
Indicates an attempt to produce an object whose length is
length_error greater than or equal to NPOS (the largest representable
value of type size_t).
out_of_range Reports an out-of-range argument.
Thrown for executing an invalid dynamic_cast expression
Bad_cast
in run-time type identification
Bad_typeid Reports a null pointer p in an expression typeid(*p).

Table 14.3: Exceptions derived from runtime_error


range_error Reports violation of a postcondition.
overflow_error Reports an arithmetic overflow.
bad_alloc Reports a failure to allocate storage.

14.12 Programming with Exceptions


For most programmers, especially C programmers, exceptions are not
available in their existing language and take a bit of adjustment. Here are
some guidelines for programming with exceptions.

Manipal University Jaipur B2114 Page No.: 337


Object Oriented Programming – C++ Unit 14

14.12.1 When to avoid exceptions


Exceptions aren’t the answer to all problems. The following sections point
out situations where exceptions are not required:
 Not for asynchronous events – The Standard C signal() system, and
any similar system, handles asynchronous events: events that happen
outside the scope of the program, and thus events the program cannot
anticipate. The asynchronous events cannot be handled by C++
exceptions the reason is that the exception and its handler are on the
same call stack. That is, exceptions rely on scoping, whereas
asynchronous events must be handled by completely separate code that
is not part of the normal program flow (typically, interrupt service
routines or event loops). This is not to say that asynchronous events
cannot be associated with exceptions. But the interrupt handler should
do its job as quickly as possible and then return. Later, at some well-
defined point in the program, an exception might be thrown based on
the interrupt.
 Not for ordinary error conditions – If you have enough information to
handle an error, it’s not an exception. It should be taken care of in the
current context rather than throwing an exception to a larger context.
Also in C++ exceptions are not thrown for the machine level events.
They should be handled by some other mechanisms like the operating
system or hardware. That way, C++ exceptions can be reasonably
efficient, and their use is isolated to program-level exceptional
conditions.
 Not for flow-of-control – We should not use the exceptions other than
their original intent. For example some programmers may think of using
exceptions instead of switch statement and as an alternate return
mechanism. This should not be done because the exception-handling
system is significantly less efficient than normal program execution;
exceptions are a rare event, so the normal program shouldn’t pay for
them. Also, exceptions from anything other than error conditions are
quite confusing to the user of your class or function.
 You’re not forced to use exceptions – Many programs are very simple
in their implementations. Only thing required in the program is to take
input and perform some processing. Some problems may arise while

Manipal University Jaipur B2114 Page No.: 338


Object Oriented Programming – C++ Unit 14

executing these programs like you might attempt to allocate memory


and fail, or try to open a file and fail, and so on. It is acceptable in these
programs to use assert() or to print a message and abort() the program,
allowing the system to clean up the mess, rather than to work very hard
to catch all exceptions and recover all the resources yourself. So you
should not use exceptions if there is not a need to use it.
 New exceptions, old code – Sometimes a situation may arise in which
we want to modify an existing program that is not using any exception.
You may introduce a library that does use exceptions and wonder if you
need to modify all your code throughout the program. Assuming you
have an acceptable error handling scheme already in place, the most
sensible thing to do here is surround the largest block that uses the new
library (this may be all the code in main()) with a try block, followed by a
catch(...) and basic error message. You can refine this to whatever
degree necessary by adding more specific handlers, but, in any case,
the code you’re forced to add can be minimal. You can also isolate your
exception-generating code in a try block and write handlers to convert
the exceptions into your existing error-handling scheme. It’s truly
important to think about exceptions when you’re creating a library for
someone else to use, and you can’t know how they need to respond to
critical error conditions.
14.12.2 Using exceptions
Use exceptions to:
 Fix the problem and call the function (which caused the exception)
again.
 Patch things up and continue without retrying the function.
 Calculate some alternative result instead of what the function was
supposed to produce.
 Do whatever you can in the current context and rethrow the same
exception to a higher context.
 Do whatever you can in the current context and throw a different
exception to a higher context.
 Terminate the program.
 Make your library and program safer. This is a short-term investment (for
debugging) and a long-term investment (for application robustness).

Manipal University Jaipur B2114 Page No.: 339


Object Oriented Programming – C++ Unit 14

 Always use exception specifications – The exception specification is like


a function prototype: It tells the user to write exception handling code
and what exceptions to handle. It tells the compiler the exceptions that
may come out of this function. It is not possible to find out what
exceptions will arise from a particular function by looking at the code.
Sometimes unexpected exception is generated by the function it calls.
And sometimes an old function that didn’t throw an exception is replaced
with a new one that does, and you’ll get a call to unexpected(). Anytime
you use exception specifications or call functions that do, you should
create your own unexpected() function that logs a message and
rethrows the same exception.
 Start with standard exceptions – Before you throw any exception you
should check the Standard C++ library. If you find a standard exception
that does what we need then that will be easier for user to understand
and handle. You should try to derive the exception from an existing
standard exception if the desired exception type is not part of the
standard library. It’s nice for your users if they can always write their
code to expect the what() function defined in the exception() class
interface.
 Nest your own exceptions – If you create exceptions for your particular
class, it is a very good idea to nest the exception classes inside your
class to provide a clear message to the reader that this exception is
used only for your class. In addition, it prevents the pollution of the
namespace. It is possible to nest your exceptions even if it is derived
from C++ standard exceptions.
 Use exception hierarchies – Many types of critical errors that can be
encountered with our class or library are classified by the exception
hierarchies. This gives helpful information to users, assists them in
organizing their code, and gives them the option of ignoring all the
specific types of exceptions and just catching the base-class type. Also,
any exceptions added later by inheriting from the same base class will
not force all existing code to be rewritten – the base class handler will
catch the new exception. Of course, the Standard C++ exceptions are a
good example of an exception hierarchy, and one that you can use to
build upon.

Manipal University Jaipur B2114 Page No.: 340


Object Oriented Programming – C++ Unit 14

 Catch by reference, not by value – If you throw an object of a derived


class and it is caught by value in a handler for an object of the base
class, that object is “sliced” – that is, the derived-class elements are cut
off and you’ll end up with the base-class object being passed. The
possibility is that the result is not what we want because the object will
behave like a base class object and not the derived class object it really
is (or rather, was – before it was sliced). Here is an example:
//: C07:Catchref.cpp
// Why catch by reference?
#include <iostream>
using namespace std;
class Base {
public:
virtual void what() {
cout << "Base" << endl;
}
};
class Derived : public Base {
public:
void what() {
cout << "Derived" << endl;
}
};
void f() { throw Derived(); }
int main() {
try {
f();
} catch(Base b) {
b.what();
}
try {
f();
} catch(Base& b) {
b.what();
}
} ///:~
Output of the above program is as follows:
Manipal University Jaipur B2114 Page No.: 341
Object Oriented Programming – C++ Unit 14

Base
Derived
The output of the program is as shown above because, when the object
is caught by value, it is turned into a Base object (by the copy
constructor) and must behave that way in all situations, whereas when
it’s caught by reference, only the address is passed and the object isn’t
truncated, so it behaves like what it really is, a Derived in this case.
Although you can also throw and catch pointers, by doing so you
introduce more coupling – the thrower and the catcher must agree on
how the exception object is allocated and cleaned up. This is a problem
because the exception itself may have occurred from heap exhaustion.
If you throw exception objects, the exception-handling system takes
care of all storage.
 Don’t cause exceptions in destructors – Because destructors are called
in the process of throwing other exceptions, you’ll never want to throw
an exception in a destructor or cause another exception to be thrown by
some action you perform in the destructor. If this happens, it means that
a new exception may be thrown before the catch-clause for an existing
exception is reached, which will cause a call to terminate(). This means
that if you call any functions inside a destructor that may throw
exceptions, those calls should be within a try block in the destructor, and
the destructor must handle all exceptions itself. None must escape from
the destructor.
Self Assessment Questions
13. The asynchronous events can be handled by C++ exceptions.
(True/False)
14. We should check the standard library before throwing an exception.
(True/False)

14.13 Summary
 Exceptions are run time anomalies or unusual conditions that a program
may encounter while executing.
 There are two kinds of exceptions i.e. synchronous and asynchronous
exceptions

Manipal University Jaipur B2114 Page No.: 342


Object Oriented Programming – C++ Unit 14

 The exception handling mechanism in C++ is built upon the three


keywords named as try, throw and catch.
 When an exception that is desired to be handled is detected, it is
thrown using the “throw” statement.
 We include code for handling exceptions in catch blocks.
 Sometimes program segment has more than one condition to throw an
exception. In such cases you can associate more than one catch blocks
with a try block.
 It is possible to create your own exception class and use them as
exception types in your exception handling code instead of using pre-
defined data types in C++ as exception.
 There are two basic models in exception-handling theory. In termination
(which is what C++ supports) you assume the error is so critical there’s
no way to get back to where the exception occurred.
 The alternative is called resumption. It means the exception handler is
expected to do something to rectify the situation, and then the faulting
function is retried, presuming success the second time.
 C++ provides us the facility to inform the user what exceptions are
thrown by the function, so it can be handled by the user. This is the
exception specification and it is part of the function declaration,
appearing after the argument list.
 Sometimes you may want to rethrow the exception that you just caught.
This is accomplished by using throw with no argument.
 The exception is uncaught if no handler catches the exception at any
level
 An uncaught exception also occurs if a new exception is thrown before
an existing exception reaches its handler.
 The programmers should follow certain guidelines while dealing with the
exceptions.

14.14 Terminal Questions


1. Define exception. Explain exception handling mechanism.
2. Explain the implementation of multiple catch statements with the help of
an example.

Manipal University Jaipur B2114 Page No.: 343


Object Oriented Programming – C++ Unit 14

3. Discuss user-defined exception classes.


4. Compare termination and resumption
5. What is rethrowing of exception?
6. Describe the standard exceptions in C++ language.
7. Describe all the situations when we should avoid or use the exceptions.

14.15 Answers
Self Assessment Questions
1. Exceptions
2. Synchronous, Asynchronous
3. try
4. catch block
5. throw
6. catch( type arg)
{
//statements to manage exceptions
}
7. User defined exception classes
8. termination
9. throw
10. unexpected()
11. no argument
12. set_terminate()
13. False
14. True

Terminal Questions
1. Exceptions are run time anomalies or unusual conditions that a program
may encounter while executing. The exception handling mechanism in
C++ is built upon the three keywords named as try, throw and catch. For
more details refer section 14.3.
2. Sometimes program segment has more than one condition to throw an
exception. In such cases you can associate more than one catch blocks
with a try block. For more details refer section 14.5.
3. It is possible to create your own exception class and use it as exception
type in your exception handling code instead of using pre-defined data

Manipal University Jaipur B2114 Page No.: 344


Object Oriented Programming – C++ Unit 14

types in C++ as exception. You can achieve further control over


exception handling by defining your own exception classes. For more
details refer section 14.6.
4. There are two basic models in exception-handling theory. In termination
(which is what C++ supports) you assume the error is so critical there’s
no way to get back to where the exception occurred. Whoever threw the
exception decided that there was no way to salvage the situation, and
they don’t want to come back. The alternative is called resumption. For
more details refer section 14.7.
5. Sometimes you may want to rethrow the exception that you just caught,
particularly when you use the ellipses to catch any exception because
there is no information available about the exception. This is
accomplished by saying throw with no argument. For more details refer
section 14.9.
6. The set of exceptions used with the Standard C++ library are also
available for your own use. For more details refer section 14.11.
7. The exceptions should not be used for the following: Not for
asynchronous events, not for ordinary error conditions, not for flow-of-
control, you are not forced to use exceptions New exceptions, old code.
For more details refer section 14.12.

References:
 Object Oriented Programming with C++ - Sixth Edition,
by E Balagurusamy. Tata McGraw-Hill Education.
 The C++ Standard Library: A Tutorial and Handbook, By Nicolai M.
Josuttis, Addison-Wesley Professional.
 Object-Oriented Programming with C++ 2Nd Ed. By Sarang, Sarang
Poornachandra, PHI Learning Pvt. Ltd.

––––––––––––––––

Manipal University Jaipur B2114 Page No.: 345

You might also like