Вы находитесь на странице: 1из 88

- 1 -

KALASALINGAM UNIVERSITY
(KALASALINGAM ACADEMY OF RESEARCH AND EDUCATION)
ANAND NAGAR, KRISHNANKOIL 626190.


Department of computer Science and Engineering




OBJECT ORIENTED PROGRAMMING
LAB (CSE285)


LAB MANUAL









- 2 -
Table of contents

S.No
Topic
Page No
1






2
3
4
5
6
7
8
9
10
11




Introduction
1.1 Object Oriented Programming Lab Objectives
1.2 Tools Required
1.3 Lab Plan
1.4 Instructions to faculties
1.5 Instructions to students
1.6 Method of evaluation
Simple C++ Programs
Programs using functions
Programs using classes
Function overloading
Operator overloading
Inheritance
Polymorphism and Virtual functions
File Handling and I/O Manipulation
Templates Function and class templates
Exception handling
Appendix A C++ reserved words
Appendix B C++ Programming Guidelines
Appendix C Sample Programs
Reference
3
3
4
4
5
6
7
9
12
16
24
28
31
37
46
58
64
70
71
83
88




- 3 -
OBJECT ORIENTED PROGRAMMING LAB CSE285
LAB MANUAL
1. Introduction
Programming language which serves as the intelligent of any computer
systems has evolved tremendously since it was first developed. Currently, in most
electronic devices ranging from mobile handset to washing machine even to cars
have computer embedded system and thus requires some form of programming
language to govern the operation of those devices.
Object-oriented programming (OOP) is a programming paradigm that uses
abstraction to create models based on the real world. It utilizes several techniques
from previously established paradigms, including modularity, polymorphism and
encapsulation. Even though it originated in 1960s, OOP was not commonly used
in mainstream software application development until the 1990s. Today, many
popular programming languages such as Java, JavaScript, C# , C++, Python
support OOP.
OOP may be seen as a collection of cooperating objects, as opposed to a
traditional view in which a program may be seen as a collection of functions, or
simple as a list of instructions to the computer. In OOP, each object is capable of
receiving messages, processing data, and sending messages to other objects. Each
object can be viewed as an independent little machine with a distinct role or
responsibility.
OOP is intended to promote greater flexibility and maintainability in
programming, and is widely popular in large-scale software engineering. By virtue
of its strong emphasis on modularity, object oriented code is intended to be
simpler to develop and easier to understand later on, lending itself to more direct
analysis, coding, and understanding of complex situations and procedures than less
modular programming methods.
C++ is one of the high-level language that is developed by Bjarne
Stroustrup (http://www.research.att.com/~bs/homepage.html), of which is
- 4 -
actually C is a subset of C++. It is developed on basis of enabling object-oriented
programming, where the students will learn and apply its concept in this subject.
1.1 Object Oriented Programming Lab Objectives
To provide the student with the fundamental knowledge and skills to
become a proficient C++ programmer.
To learn to transpose the physical problem domain into a hierarchy of
objects.
To develop ability of using OOP to solve simple engineering problems
To work with advanced futures of C++ (templates, exception handling).
1.2 Tools Required
Hardware Requirement
Pentium IV
512 MB RAM
20 GB Hard disk drive
Software Requirement
Windows 9x or above
Turbo C++ compiler
Microsoft Visual C++ 6.0
1.3 Lab Plan
Week # Lab Content Software
Week 1 Simple C++ programs Turbo C++ / VC++
Week 2 Programs Using Functions Turbo C++ / VC++
Week
3 & 4
Programs using Classes ( Constructor,
destructor, Friend Functions etc)
Turbo C++ / VC++
Week 5 Function Overloading Turbo C++ / VC++
Week 6 Operator Overloading Turbo C++ / VC++
Week 7 Simple and Multiple Inheritance Turbo C++ / VC++
Week 8 Multilevel and hybrid Inheritance Turbo C++ / VC++
- 5 -
Week 9 Model Lab Exam # 1 Turbo C++ / VC++
Week 10 Virtual Functions Turbo C++ / VC++
Week 11 Polymorphism Turbo C++ / VC++
Week1 2 File Handling and I/O Manipulation Turbo C++ / VC++
Week 13
Templates Function Templates and
Class Templates
VC++
Week1 4 Exception Handling VC++
Week 15 Model Lab Exam # 2 Turbo C++ / VC++

1.4 Instructions to Faculties
Learning Overview: To develop better understanding of importance of the
subject. To know related skills to be developed such as Intellectual skills.
Know your Laboratory Work: To understand the layout of laboratory,
specifications of Equipment / Instruments / Software, procedure, working
in groups, planning time etc. Also to know total amount of work to be done
in the laboratory.
Faculties shall ensure that required equipments are in working condition
before start of experiment, also keep operating instruction manual available.
Explain prior concepts to the students before starting of each experiment.
Involve students activity at the time of conduct of each experiment.
List of questions is given at the end of each experiment. Faculties shall
instruct the students to attempt all questions given at the end of each
experiment / exercise.
Faculties shall ensure that each student writes the answers to the allotted
questions in the laboratory manual after performance is over.
Faculties shall assess the performance of students continuously.
Faculties should ensure that the respective skills and competencies are
developed in the students after the completion of the practical exercise.
- 6 -
Faculties are expected to share the skills and competencies to be developed
in the students.
Faculties may provide additional knowledge and skills to the students even
though not covered in the manual but are expected from the students by the
industries.
Faculties may suggest the students to refer additional related literature of the
Technical papers / Reference books / Seminar proceedings, etc.
During assessment faculties are expected to ask questions to the students to
tap their achievements regarding related knowledge and skills so that
students can prepare while submitting record of the practical.
Faculties should enlist the skills to be developed in the students that are
expected by the industry.
1.5 Instructions to Students
Students shall read the points given below for understanding the theoretical
concepts and practical applications.
Listen carefully to the lecture given by teacher about importance of subject,
curriculum philosophy, learning structure, skills to be developed and
procedure method of continuous assessment, tentative plan of work in
laboratory and total amount of work to be done in a semester.
Read the write up of each experiment to be performed, a day in advance.
Organize the work in the group and make a record of all programs,
algorithms.
Understand the purpose of experiment and its practical implications.
Write the answers of the viva questions allotted by the teacher during
practical hours if possible or afterwards, but immediately.
Student should not hesitate to ask any difficulty faced during conduct of
practical / exercise.
The student shall study all the questions given in the laboratory manual and
practice to write the answers to these questions.
- 7 -
Student shall develop maintenance skills as expected by the industries.
Student should develop the habit of pocket discussion / group discussion
related to the experiments / exercises so that exchanges of knowledge /
skills could take place.
Student shall attempt to develop related hands - on - skills and gain
confidence.
Student shall focus on development of skills rather than theoretical or
codified knowledge.
Student shall develop the habit of evolving more ideas, innovations, skills
etc. those included in the scope of the manual.
Student shall refer technical magazines, proceedings of the Seminars, refer
websites related to the scope of the subjects and update his knowledge and
skills.
Student should develop the habit of not to depend totally on teachers as
well as their classmates but to develop self learning techniques.
Student should develop the habit to react with the teacher without hesitation
with respect to the academics involved.
Student should develop habit to submit the practical, exercise continuously
and progressively on the scheduled dates and should get the assessment
done.
Student should be well prepared while submitting the write up of the
exercise. This will develop the continuity of the studies and he will not be
over loaded at the end of the term.
For loading C++, process is same as of C. While saving give extension as
.cpp.
1.6 Method of Evaluation
For each Exercise (Out of 10 Marks)
1. Algorithm - 2 Marks
2. Program - 4 marks
- 8 -
3. Output - 2 Marks
4. Answers to Viva Questions - 2 Marks

For Model / End Semester Practical Examination
Each student will be given two programs for lab examination.
1. Algorithm - 10 (5 for each)
2. Program - 40 (20 for each)
3. Output - 40 (20 for each)
4. Viva - 10
_______
Total Marks 100
_______
End Evaluation
1. Model Practical I - 20 Marks
2. Model Practical II - 20 Marks
3. Record and Observation Maintenance - 10 Marks
4. End semester Practical Examination - 50 Marks
----------------
Total Marks 100
----------------









- 9 -
2. Simple C++ Programs
Aim
To let the student experience coding, compiling and debugging some
simple C++ programs.
To get familiar in C++ form of input and output.
To get familiar in writing simple C++ programs using looping
statements, structures, arrays and preprocessors.
Instructions
1. Each student should do a minimum of 4 experiments by using looping
statements, arrays, structures and preprocessor statements.
2. Faculties can suggest their own programs also to the students.
List of Exercises
1. An electricity board charges the following rates to domestic users to discourage
large conceptions of energy.
First 100 units Rs 1.50 p/unit
From 100 to 200 units Rs 1.80 p/unit
Beyond 200 Rs 2.50 p/unit
All users are charged a minimum of Rs 50/-. If the total amount is more than 300
then an additional surcharge of 15% of the calculated amount is added. Write a
c++ program to read the name of an user, number of units consumed and print
out the Electricity bill in a neat format.
2. Create a structure book with relevant information for maintaining a book.
Create an array of structure to hold a minimum of 5 books details. Also print all
the books details in a table format.
3. Write C++ programs that produce following outputs.
i) A
A B
A B C
A B C D
- 10 -
ii) A B C D E
A B C D
A B C
A B
A
4. Write a C++ program to find all prime numbers between two given numbers.
5. Write a C++ program that asks to enter any number and then prints the
multiplication table of that number from 1 to 10.
6. Write a C++ program to enter a matrix of 3*3 and check whether it is an
identity matrix.
7. Write a C++ program to find the transpose of a given 3*3 matrix.
8. Write a program to evaluate the following functions to 0.0001% accuracy for n
terms..
i) sin (x) = x (x
3
/ 3!) + (x
5
/ 5!) (x
7
/ 7!) +.
ii) SUM = 1 + (1/2)
2
+ (1/3)
3
+ ()
4
+..
9. Write a c++ program to find the cube of a square using preprocessor
statements.
Viva Questions
1. What is the basic difference between C and C++?
2. What are all the differences between C structure and C++ structure?
3. Name the C++ input and output statements,
4. How does a main ( ) function in C++ differ from main ( ) in C?
5. What is the purpose of a # include statement?
6. What is the need for the directive # include<iostream.h> and
# include<conio.h>?
7. In C++, a variable can be declare anywhere in the scope. What is the
significance of this feature?
8. What is meant by dynamic initialization of a variable?
9. Why an array is called a derived data type?
- 11 -
10. What are the applications of void data type in C++?
11. What are the two types of comment styles in C++?
12. What is the difference between using a break and using continue in a
looping statement?
Learning Outcome
At the end of this experiment the students will
Get familiar with basic C++ program format.
Know the input and output format of C++ language.
Have a good idea of using looping statements
Create, execute, and test C++ programs using calculations and decision
statements, loops and arrays.





















- 12 -
3. Programs Using Functions
Aim
To make the students to get familiar in problem decomposition by
using functions in C++ language.
To learn various parameter passing techniques like call by value, call by
address, call by reference to functions.
To know how to use inline functions, default arguments and their
significance in C++ programming
Theory
Inline function
It is defined as a function definition such that each call to the function is in
effect, replaced by the statements that define the function. It is expanded in line
when it is invoked.
The general form is




Situations where inline expansion cannot work.
For functions returning values, if a loop, a switch, or a goto exists.
For functions not returning values, if a return statement exists.
If functions contain static variables.
If inline functions are recursive.
Default argument
Default arguments assign a default value to the parameter, which does not
have matching argument in the function call. Default values are specified when the
function is declared.
Eg : float amount(float principle,int period, float rate=0.15)

inline function-header
{
function body
}
- 13 -
Function call is
Value=amount(5000,7);
Here it takes principle=5000& period=7 And default value for rate=0.15

Value=amount(5000,7,0.34)
Passes an explicit value 0f 0.34 to rate
We must add default value from right to left
Static data member
Static variable are normally used to maintain values common to the entire
class. They are called as class variable because they are associated with the class
itself rather than with any class object
Features:
It is initialized to zero when the first object is created. No other
initialization is permitted
Only one copy of it is created for the entire class and is shared by all
the objects
It is only visible within the class, but its life time is the entire class
Type and scope of each static member variable must be defined outside
the class
It is stored separately rather than along with objects
Eg: static int count//count is initialized to zero when an object is created.
int classname::count;//definition of static data member
Static member function
A member function that is declared as static has the following properties
A static function can have access to only other static data member
declared in the same class
A static member function can be called only by using the classname as
follows
classname ::function_name;
- 14 -
Const objects and const member functions
We can create constant object by using const keyword before object declaration.
Eg: const integer i(m,n);
If a member function does not alter any data in the class, then we may declare it as
const member function as
void mul(int ,int) const;
It const object can call const member functions.
List of Exercises
1. Write a C++ program to input and output data for finding area of rectangle
using functions.
2. Write a C++ program using functions to get and print a 3*3 matrix.
3. Write a C++ program to swap two integer values using functions with call by
value, call by reference and call by pointers techniques.
4. Write a C++ program to find and print the volume of a cube using inline
functions.
5. Write a C++ program using inline functions to find and print the maximum of
three numbers.
6. Write a C++ program using default arguments to find the simple interest using
a function by pasting amount, time and rate of interest. The default value for
time is 1 year and that of rate of interest is 12%.
7. Write a C++ program using function to raise a number m (double) to a power
n (int). Use a default value of 2 for n to make the function to calculate squares
when this argument is omitted.
8. Write a C++ program to perform the following arithmetic operations of a
complex number using a structure.
a. Addition of two complex numbers
b. Multiplication of two complex numbers
9. Write a C++ program with a structure to store the students details like name,
roll no, height and weight. Use function and array of structure to get the details
- 15 -
of 5 students. Also include a function to sort them in an ascending order using
the field height. Print the results in a neat format.
Viva Questions:
1. What is meant by function prototyping / function declaration and
function definition?
2. List out the advantages of using functions in C++.
3. What is inline function?
4. What are all the advantages of inline function?
5. What are all the differences between preprocessor statements and inline
functions?
6. When inline functions should not be used?
7. What is reference variable?
8. What are all the uses of reference variable?
9. Write the differences between reference variable and pointer variable?
10. What are default arguments?
11. Mention the uses of default arguments.
12. Write the rules to use default arguments in a c++ program.
Learning Outcome
At the end of this experiment the students will
know how to use functions and inline functions in programs
come to know various parameter passing techniques
learn how to pass arrays, structures to functions
learn the way of using default arguments






- 16 -
4. Program using Classes
Aim
To enhance the understanding of students about the underlying concepts
of classes
To demonstrate the approach to build classes and create object
To learn the usage of constructors and destructors in classes
Theory
A class in C++ can be viewed as a customized struct that encapsulates
data and function as well. When we encapsulate data and function in one entity,
most of the time, the function would not have to take trouble to ask for some data
to be included in its argument list, but will still need to if it is required.
Objects are basic run-time entities in an object-oriented system. They may
represent a person, a place, a bank account, a table of data or any item that the
program has to handle. Each object has the data and code to manipulate the data
and theses objects interact with each other. The entire set of data and code of
an object can be made a user-defined data type with the help of a class. Once a
class has been defined, we can create any number of objects belonging to the
classes. Classes are user-defined data types and behave like built-in types of the
programming language
Format of a class definition:
class your_class_name
{
private : // access specifier
data members;
member_functions();
public:
data members;
member_functions();
} ;
- 17 -
The properties or attributes of an object can be represented as data
members in a class and its behaviors can be represented as member functions. The
secret properties and behaviors can be kept in private section which can not be
seen by remaining part of program. Whereas, the external properties and behaviors
can be kept in the public function through which other part of the program will
communicate with.
Member functions can be defined in two ways
Outside the class definition
Member function can be defined outside the class by using scope resolution
operator:
General format:
Return type class_name::function-name(arguments list)
{
//function body
}
Inside the class definition
This method of defining member function is to replace the function
declaration by the actual function definition inside the class. It is treated as inline
function.
Eg:
class item
{
private:
int a,b ;
public :
void getdata(int x,int y)
{
a=x;
b=y;
}
} ;

- 18 -
Once the class has been declared, we can create objects which are variables
of that type by using the classname as follows
Eg : classname x; //memory for x is created
Then the public members of the class can be accessed as follows:
object-name . function-name(actual arguments);
eg : x . getdata(100,75.5);

Constructors
A constructor is a special member function whose task is to initialize the
objects of its class. It is special because its name is same as class name. The
constructor is invoked whenever an object of its associated class is created. It is
called constructor because it constructs the values of data members of the class
Eg:
Class integer
{
int i;
public:
integer( ) }//constructor
{
i = 10;
}

};
The constructors are of three types
Default Constructor
Parameterized Constructor
Copy Constructor
Default Constructor
The constructor with no arguments is called default constructor. This will be
automatically created if not specified in the program.
The statement integer a; invokes the default constructor.
Parameterized constructor
A constructor with arguments is called parameterized constructor. Normally
- 19 -
these arguments will contain the initial values for data members.
Copy constructor
A copy constructor is used to declare and initialize an object from another
object. It takes a reference to an object of the same class as an argument
Eg;
class integer
{
int m,n;
public:
integer( );
integer(int x,int y) // parameterized constructor
{
m=x;n=y;
}
integer(const integer &i)
{
m = i.m;
m = i.n
}

.
} ;
integer::integer( )//default constructor
{
m=0;n=0;
}
Invoking constructors
integer a; //calls default constructor
To invoke parameterized constructor we must pass the initial values as
arguments to the constructor function when an object is declared. This is done in
two ways
1.By calling the constructor explicitly
eg: integer int1=integer(10,10);
2.By calling the constructor implicitly
eg: integer int1(10,10);
To call copy constructor also we have two ways:
- 20 -
1. integer i2(i1);
2. integer i2 = i1;
Both the forms define the object i2 as well as time initialize it to the values
of i1.
Dynamic constructor
Allocation of memory to data members of objects at time of their construction
is known as dynamic constructor. The memory is allocated with the help of the
NEW operator. The dynamic constructor can take any form of the above
constructor.
Eg:
class string
{
char *name;
int length;
public:
string( char str[10])
{
length=strlen(str);
name=new char[length +1];
strcpy(str, name);
}
} ;
void main( )
{
string name1(Louis);
name3(Lagrange);
}
Destructor
It is used to destroy the objects that have been created by constructor.
Destructor name is same as class name preceded by tilde symbol(~)
Eg;
~integer()
{
}
A destructor never takes any arguments nor it does return any value. The
compiler upon exit from the program will invoke it. Whenever new operator is
- 21 -
used to allocate memory in the constructor, we should use delete operator to free
that memory.
Friend functions
A function that has access to the private member of the class but is not
itself a member of the class is called friend functions.
The general form is
friend data_type function_name( ); (inside the class)
Friend function is preceded by the keyword friend.
Properties of friend functions.
Friend function is not in the scope of the class to which it has been
declared as friend. Hence it cannot be called using the object of that
class.
Usually it has objects as arguments.
It can be declared either in the public or private part of a class.
It cannot access member names directly. It has to use an object name
and dot membership operator with each member name. eg: ( A . x )
List of Exercises
1. Create a class called Employee that includes three pieces of information as
instance variables a first name (type String), a last name (type String) and a
monthly salary (double). Create a constructor in above class to initialize the
three instance variables. Provide a get method for each instance variable. Create
two employee objects and display each objects yearly salary using display
function. Give each employee a 10% raise using raise_salary function and
display each Employees yearly salary again.
2. Create a class called time that has separate int member data for hours, minutes,
and second. One constructor should initialize this data to 0, and another should
initialize it to fixed values. A member function should display it, in 11:59:59
format. The final member function should add two objects of type time passed
as arguments. A main ( ) program should create two initialized time objects, and
- 22 -
one that isnt initialized. Then it should add the two initialized values together,
leaving the result in the third time variable. Finally it should display the value of
this third variable.
3. Define a class to represent a bank account. Include the following members.
Data Members: Name of depositor, Account number, Type of Account,
Balance amount in the account Member functions : To assign initial values, To
deposit an amount, To withdraw an amount after checking the balance, To
display name and balance.
4. Create a class complex with real and imaginary as data members. Also include
member functions to get the values for a complex number, to add two complex
number, to multiply two complex numbers, to print the complex number in
a+ib format.
5. Create a class complex with real and imaginary as data members. Also include
member functions to get the values for a complex number and to print the
complex number in a+ib format. Also include friend functions to add two
complex numbers and multiply two complex numbers.
6. Write a C++ program to implement the stack data structure using classes.
7. Define a class String that could work as a user-defined string type. Include
constructors that will enable you to create an uninitialized string String S1;
(string with length 0) and also to initialize an object with a string constant at the
time of creation like String S2(Well done); . Include a function that adds
two string to make a third string.(note that the statement s2=s1; will be
perfectly reasonable expression to copy one string to another. (Use new and
delete operators). Write a complete program to test your class to see that it does
the following tasks:
(a) Creates uninitialized string objects
(b) Creates objects with string constants.
8. Write a C++ program to count the number of objects created and destroyed
for a class using stating data members and static member functions.
- 23 -
9. Write a c++ program with a class to represent Vector. Include necessary
member functions to
i) to get a vector
ii) to add two vectors using friend function
iii) to display a vector in the form (10,20, 30)
10. Write a C++ program with a class Pixel to represent a Cartesian coordinate
system. Also include member functions to get, print and to move (both
coordinates by +10) using this pointer.
11. Write a C++ program to depict the concept of friend class in C++.
Viva Questions
1. What is the basic difference between class and structure?
2. What is the basic difference between private and protected?
3. What is constructor? What is its role? How does constructor differ from
normal function?
4. What is data hiding? What is encapsulation?
5. What is the difference between writing the body of the function in side the
class and outside the class?
6. What is this pointer? Write its uses.
7. What are friend functions and friend classes?
8. State the uses of static members and constant members.
9. Write the various access types of class members.
10. Write the need for destructor.
Learning Outcome
At the end of this experiment the students will
be able to solve any real world problem with concept of classes
learn the usage of constructors and destructors
Know the ways of using static members, constant members and friend
functions.


- 24 -
5. Function Overloading
Aim
To understand the fundamentals of function overloading
Theory
Function overloading is a feature of C++ that allows us to create multiple
functions with the same name, so long as they have different number and different
type of parameters. Consider the following functions:
int Add(int nX, int nY)
{
return nX + nY;
}
double Add(double dX, double dY)
{
return dX + dY;
}
We now have two version of Add( ):
Function Call
int Add(int nX, int nY); // integer version
double Add(double dX, double dY); // floating point version
Which version of Add() gets called depends on the arguments used in the call if
we provide two ints, C++ will know we mean to call Add(int, int). If we provide
two floating point numbers, C++ will know we mean to call Add(double, double).
In fact, we can define as many overloaded Add() functions as we want, so long as
each Add() function has unique parameters.
Consequently, its also possible to define Add() functions with a differing number
of parameters:
int Add(int nX, int nY, int nZ)
{
return nX + nY + nZ;
}
Even though this Add() function has 3 parameters instead of 2, because the
parameters are different than any other version of Add(), this is valid.
- 25 -
Note :The functions return type is NOT considered when overloading functions.
Making a call to an overloaded function results in one of three possible outcomes:
1) A match is found. The call is resolved to a particular overloaded function.
2) No match is found. The arguments can not be matched to any overloaded
function.
3) An ambiguous match is found. The arguments matched more than one
overloaded function.

When an overloaded function is called, C++ goes through the following process to
determine which version of the function will be called:

1) First, C++ tries to find an exact match. This is the case where the actual
argument exactly matches the parameter type of one of the overloaded functions.
For example:
2) If no exact match is found, C++ tries to find a match through promotion. In
the lesson on type conversion and casting, we covered how certain types can be
automatically promoted via internal type conversion to other types. To summarize,
3) If no promotion is found, C++ tries to find a match through standard
conversion. Standard conversions include:
4) Finally, C++ tries to find a match through user-defined conversion.
Ambiguous matches
If every overloaded function has to have unique parameters, how is it
possible that a call could result in more than one match? Because all standard
conversions are considered equal, and all user-defined conversions are considered
equal, if a function call matches multiple candidates via standard conversion or
user-defined conversion, an ambiguous match will result. For example:
void Print(unsigned int nValue);
void Print(float fValue);

- 26 -
Calls
Print('a');
Print(0);
Print(3.14159);
In the case of Print('a'), C++ can not find an exact match. It tries promoting a to
an int, but there is no Print(int) either. Using a standard conversion, it can convert
a to both an unsigned int and a floating point value. Because all standard
conversions are considered equal, this is an ambiguous match.
Print(0) is similar. 0 is an int, and there is no Print(int). It matches both calls via
standard conversion.
Print(3.14159) might be a little surprising, as most programmers would assume it
matches Print(float). But remember that all literal floating point values are doubles
unless they have the f suffix. 3.14159 is a double, and there is no Print(double).
Consequently, it matches both calls via standard conversion.
Ambiguous matches are considered a compile-time error. Consequently, an
ambiguous match needs to be disambiguated before your program will compile.
There are two ways to resolve ambiguous matches:
1) Often, the best way is simply to define a new overloaded function that takes
parameters of exactly the type you are trying to call the function with. Then C++
will be able to find an exact match for the function call.
2) Alternatively, explicitly cast the ambiguous parameter(s) to the type of the
function you want to call. For example, to have Print(0) call the Print(unsigned
int), you would do this:
Print(static_cast<unsigned int>(0)); // will call Print(unsigned int)
Multiple arguments
If there are multiple arguments, C++ applies the matching rules to each argument
in turn. The function chosen is the one for which each argument matches at least
as well as all the other functions, with at least one argument matching better than
all the other functions. In other words, the function chosen must provide a better
- 27 -
match than all the other candidate functions for at least one parameter, and no
worse for all of the other parameters. In the case that such a function is found, it is
clearly and unambiguously the best choice. If no such function can be found, the
call will be considered ambiguous (or a non-match).
Hence function overloading can lower a programs complexity significantly
while introducing very little additional risk.
List of Exercises
1. Write a C++ program to find the area of a square and rectangle using
function overloading.
2. Write a C++ program to find the volume of a cube, cone and a rectangle
using function overloading.
3. Write a C++ program to swap two integers, floats, characters and two
strings suing function overloading concept.
Viva Questions
1. What are the syntactic rules governing the definition of function
overloading.
2. List out the advantages of function overloading.
Learning outcome
At the end of this exercise, the students will be able to
Understand the concept of function overloading
Learn how ambiguity is handled in function overloading.







- 28 -
6. Operator Overloading
Aim
To understand the fundamentals of operator overloading
To understand the differences between overloading as member function
and non-member friend function
Theory
Need for operator overloading
If we compare the following syntaxes to perform addition of two objects a
and b of a user defined class number (assume this class has a member function
called add() which adds two fraction objects):
1 c=a.add(b);
2 c=a+b;
Which one is easier to use, line 1 or 2? Obviously option 2 is easier.
Operator overloading
It is needed to make operation with user defined data type, i.e., classes, can
be performed concisely. C++ has the ability to provide the operators with a special
meaning for a data type. This mechanism of giving such special meanings to an
operator is known as Operator overloading. It provides a flexible option for the
creation of new definitions for C++ operators. The behavior of various operator
on such user define data types can be specified using operator functions.
Operator functions are either member functions or friend functions. The general
form is
return type classname :: operator op(op-arglist )
{
function body
}
where return type is the type of value returned by specified operation.
Op is the operator being overloaded. The op is preceded by a keyword
operator. operator op is the function name.
Limitation on operator overloading
- 29 -
Although C++ allows us to overload operators, it also imposes restrictions
to ensure that operator overloading serves its purpose to enhance the
programming language itself, without compromising the existing entity. The
followings are the restrictions:
Can not change the original behavior of the operator with built in data
types.
Can not create new operator
Operators =, [], () and -> can only be defined as members of a class and not
as friend or global functions
The arity or number of operands for an operator may not be changed. For
example, addition, +, may not be defined to take other than two arguments
regardless of data type.
The precedence of the operator is preserved, i.e., does not change, with
overloading operators
There are many ways of performing operator overloading, namely:
1. as member function
2. as non member friend function
3. as non member non friend function
List of Exercises
In all the following experiments, use <<, >> operator overloading functions for
print and input of the members of class.
1. Write a C++ program to perform complex number addition, subtraction,
multiplication using operator overloading with friend functions.
2. Write a C++ program to perform complex number addition, subtraction,
multiplication using operator overloading with member functions.
3. Write a C++ program to perform matrix addition, subtraction, multiplication
using operator overloading with friend functions.
4. Write a C++ program to perform matrix addition, subtraction, multiplication
using operator overloading with member functions.
- 30 -
5. Define a class space that represents three dimensional coordinate system.
Overload unary minus operator i) Using member function ii) Using friend
function. Write a C++ program to check this.
6. Create a class Integer that contains one integer data member. Overload all
possible relational operators (using member functions and using friend
functions) so that they operate on he objects of Integer.
7. For Integer class, overload post as well as pre increment and decrement
operators.
8. Write a C++ program to overload all arithmetic assignment operator (+=, -=,
*=, /=) for the complex number class using friend functions and member
functions.
9. Write a C++ program to overload new and delete operators for the string class.

Viva Questions
1. What is operator overloading? State the importance of operator overloading?
2. List the operators that cant be overloaded. Give justifications.
3. What are the limitations of overloading unary increment/ decrement operator?
4. List the operators that can be overloaded with only member functions. Why?
5. Write the difference between overloading operators using friend functions and
member functions.

Learning Outcome
At the end of this experiment, the students will
Be familiar in operator overloading in C++
Learn how to overload operators using member functions and friend
functions.




- 31 -
7. Inheritance
Aim
To understand the fundamentals of inheritance
To develop skills on how to use inheritance to simplify development of new
classes
To understand some concepts such as overridden function, protected access
specifier and the sequence of constructor and destructor calls
Theory
Initially, OOP is proposed as a means to increase the efficiency of software
developments. One of its benefits is promoting software/program reuse. Once a
class is developed reliably, i.e., after went through all sorts of possible verification
processes, it can be used everywhere. It can be used right away, without needing to
reinvent the wheel.
Inheritance is the process by which new classes called derived classes are
created from existing classes called base classes. 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, a programmer can create a base class named fruit and define derived
classes as mango, orange, banana, etc. Each of these derived classes, (mango,
orange, banana, etc.) has all the features of the base class (fruit) with additional
attributes or features specific to these newly created derived classes. Mango would
have its own defined features, orange would have its own defined features, banana
would have its own defined features, etc.
Features or 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.
- 32 -
Saves Time and Effort: The above concept of reusability achieved by
inheritance saves the programmer time and effort, since the main code
written can be reused in various situations as needed.
Increases Program Structure which results in greater reliability.
Polymorphism (to be discussed in detail in later sections)
Important terminologies:
Base class: a class which is inherited from by other classes. E.g., class Vehicle is
the base class for all other classes. Class Sedan is base class.

Base class: a class which is inherited from by other classes. E.g., class Vehicle is
the base class for all other classes. Class Sedan is base class for classes Honda Civic
and class Nissan President.
Derived class: a class which inherits from base class (es). E.g., classes Truck, Car
and Bus are derived classes from base class Vehicle.
Direct inheritance: inheritance relationship where the derived class inherit
directly from its base class. E.g., class Car and class Vehicle have direct inheritance
relationship.
Indirect inheritance: inheritance relationship where the derived class inherit
indirectly from its base class.
Vehicle
Truck Car Bus
Honda
Civic
Sedan MPV
Nissan
Preside
- 33 -
E.g., class Honda Civic and class Car have indirect inheritance relationship.
Single inheritance: a derived class inherits from a single base class. E.g., all
examples in above Fig. are single inheritance
Multiple inheritance: a derived class inherits from more than one base classes.

Type of inheritance: private, protected, public
There are three types of inheritance, namely private, protected and public
inheritances. We can observe from following table that different types of
inheritances have different effect on how members of the base class can be
accessed from the derived classes.
Base class
member
access
specifier
Type of Inheritance
Public Inheritance Private Inheritance Protected Inheritance
Public Public in derived class can
be accessed directly by
any non-static member
functions, friend functions
and non member
functions
Protected in derived
class can be accessed
directly by all non-static
member functions and
friend functions
Private in derived class
can be accessed directly
by all non-static member
functions and friend
functions
Protected Protected in derived class
can be accessed directly by
all non-static member
functions and friend
functions
Protected in derived
class can be accessed
directly by all non-static
member functions and
friend functions
Private in derived class
can be accessed directly
by all non-static member
functions and friend
functions
Private Hidden in derived class.
Can be accessed by non-
static member function
and friend functions
through public or
protected member
functions of base class.
Hidden in derived class.
Can be accessed by non-
static member function
and friend functions
through public or
protected member
functions of base class.
Hidden in derived class.
Can be accessed by non-
static member function
and friend functions
through public or
protected member
functions of base class

Protected Data Member
Since private class members are accessible from within class scope (by member
functions of the same class) and friend functions, another member access specifier
called protected is provided to enable its members accessible directly from:
within the class scope
friend functions
- 34 -
derived classes
friend functions of derived classes
General syntax for single inheritance:
Derived_class_name : type_of_inheritance Base_class_name{ } ;
General syntax for multiple inheritance:
Derived_class_name : type_of_inheritance1 Base_class_name1,
type_of_inheritance2 Base_class_name2,{ } ;
List of Programs
1. Imagine a publishing company that market s both book and audio-cassette
versions of its work. Create a class publication that stores the title and price. From
this class derive two classes book and tape; book includes one more property: page
numbers and tape contains its length in minutes (float). Each of these classes must
have getdata ( ) functions and putdata ( ) functions to input/output its data. Write
a main function to test the book and tape classes.
2. Create a Circle class with following members.
A data member that stores the radius of a circle
A constructor function with an argument that initializes the radius
A function that computes and returns are of a circle
Create two derived classes Sector and Segment that inherit the Circle class. Both
classes inherit radius and the function that returns the circles are from Circle. In
addition to the members inherited from Circle, Sector and Segment have some
specific members as follows:
Sector
1. A data member that stores the control angle of a sector(in radians)
2. A constructor function with arguments that initialize radius and angle
3. A function that computes and returns the area of a sector
Segment
1. A data member that stores the length of a segment in a circle
2. A constructor function with arguments that initialize radius and length
- 35 -
3. A function that computes and returns the area of a segment
Create the main () function to instantiate an object of each class and then call
appropriate member functions to compute and return the area of a circle, sector
and segment.
Note : Area_of_circle = r
2

Area_of_Sector=r
2
/2
Area_of_segment=r
2
arccos((r-h)/r) (r-h)(2rh-h
2
)
1/2

Where r os the radius of a circle,

is the central angle of a sector in radians, h is
the length of a segment and arccos((r-h)/r) is in radians.
3. Create three classes Student, Test and Result classes. The student class contains
student relevant information. Test class contains marks for five subjects. The result
class contains Total and average of the marks obtained in five subjects. Inherit the
properties of Student and Text class details in Result class through multilevel
inheritance.
4. Create three classes Student, Test and Result classes. The student class contains
student relevant information. Test class contains marks for five subjects. The result
class contains Total and average of the marks obtained in five subjects. Inherit the
properties of Student and Text class details in Result class through multiple
inheritance.
5. Create three classes Employee, Boss and CEO. Employee class stores basic
details like, name, employee no, department, salary. The Boss class contains bonus
information and CEO class contains shares that he owns information. Include
AskInfo( ) and writeInfo( ) functions in all the classes. In main create and object
for CEO class and call its functions. Use scope resolution operator in CEO
functions to call Employee and Boss functions.
Note : CEO is a boss and boss is an employee.
Viva Questions
1. What area the implications of using private, public and protected access
specifiers for declaring class members for a base class.
- 36 -
2. Describe the base class access control mechanism.
3. What is the firing order of the constructors under multiple and multilevel
inheritance.
4. What is method overriding?
5. What are the different forms of inheritance? Give example.
6. Write the need for protected visibility specifier to a class member.
7. What are the advantages offered by inheritance?
8. Mention the members of base classes, which cant be inherited.
Learning Outcome
After performing this lab, the students should be able to write c++ programs:
using the concepts of inheritance
using inheritance as a tool for code reuse
calling base-class constructors and member functions
Implementing all types if inheritances.

















- 37 -
8. Polymorphism & Virtual Functions
Aim
To learn the difference between inheritance and polymorphism
To understand the mechanism of polymorphism through virtual function
To understand the concept of an abstract base class
Theory
Polymorphism is the ability to use an operator or function in different ways.
Polymorphism gives different meanings or functions to the operators or
functions. Poly, referring to many, signifies the many uses of these operators
and functions. A single function usage or an operator functioning in many ways
can be called polymorphism. Polymorphism refers to codes, operations or
objects that behave differently in different contexts.
Polymorphism refers to the ability to call different functions by using only
one type of function call. Polymorphism is a powerful feature of the object
oriented programming language C++. A single operator + behaves differently
in different contexts such as integer, float or strings referring the concept of
polymorphism. The above concept leads to operator overloading. The concept
of overloading is also a branch of polymorphism. When the exiting operator or
function operates on new data type it is overloaded. This feature of
polymorphism leads to the concept of virtual methods.
Static Binding vs. Dynamic Binding
Binding means the actual time when the code for a given function is
attached or bound to the function call.
Static Binding Dynamic Binding
Actual code is attached during
compile time.
Actual code will be attached
during run-time/execution
time
Implementing function
overloading
Implementing virtual
functions
- 38 -
What are Virtual Functions?
Virtual, as the name implies, is something that exists in effect but not in
reality. The concept of virtual function is the same as a function, but it does not
really exist although it appears in needed places in a program. The object-
oriented programming language C++ implements the concept of virtual
function as a simple member function, like all member functions of the class.
The functionality of virtual functions can be over-ridden in its derived
classes. The programmer must pay attention not to confuse this concept with
function overloading. Function overloading is a different concept and will be
explained in later sections of this tutorial. Virtual function is a mechanism to
implement the concept of polymorphism (the ability to give different meanings
to one function).
Need for Virtual Function:
The vital reason for having a virtual function is to implement a different
functionality in the derived class.
For example: a Make function in a class Vehicle may have to make a Vehicle
with red color. A class called Four Wheeler, derived or inherited from Vehicle,
may have to use a blue background and 4 tires as wheels. For this scenario, the
Make function for FourWheeler should now have a different functionality from
the one at the class called Vehicle. This concept is called Virtual Function.
Properties of Virtual Functions:
Virtual Functions are resolved during run-time or dynamic binding. Virtual
functions are also simple member functions. The main difference between a
non-virtual C++ member function and a virtual member function is in the way
they are both resolved. A non-virtual C++ member function is resolved during
compile time or static binding. Virtual Functions are resolved during run-time
or dynamic binding
Dynamic Binding Property:
Virtual functions are member functions of a class.
- 39 -
Virtual functions are declared with the keyword virtual, detailed in an
example below.
Virtual function takes a different functionality in the derived class.
Declaration of Virtual Function:
Virtual functions are member functions declared with the keyword virtual.
General syntax
class classname //This denotes the base class of C++ virtual function
{
public:
virtual void memberfunctionname() //This denotes the C++
virtual function
{ ............. ............ }
} ;

Referring back to the Vehicle example, the declaration of Virtual function
would take the shape below:
class Vehicle //This denotes the base class of C++ virtual function
{
public:
virtual void Make() //This denotes the C++ virtual function
{
cout <<"Member function of Base Class Vehicle
Accessed"<<endl;
}
} ;

After the virtual function is declared, the derived class is defined. In this
derived class, the new definition of the virtual function takes place.
When the class FourWheeler is derived or inherited from Vehicle and defined
by the virtual function in the class FourWheeler, it is written as:
class Vehicle //This denotes the base class of C++ virtual function
{
public:
virtual void Make() //This denotes the C++ virtual function
{
cout <<"Member function of Base Class Vehicle Accessed"<<endl;

- 40 -
}
} ;
class FourWheeler : public Vehicle
{
public:
void Make()
{
cout<<"Virtual Member function of Derived class
FourWheeler Accessed"<<endl;
}
} ;
void main()
{
Vehicle *a, *b;
a = new Vehicle();
a->Make();
b = new FourWheeler();
b->Make();
}
In the above example, it is evidenced that after declaring the member
functions Make() as virtual inside the base class Vehicle, class FourWheeler is
derived from the base class Vehicle. In this derived class, the new
implementation for virtual function Make() is placed. The programmer might
be surprised to see the function call differs and the output is then printed as
above. If the member function has not been declared as virtual, the base class
member function is always called because linking takes place during compile
time and is therefore static.
In this example, the member function is declared virtual and the address is
bounded only during run time, making it dynamic binding and thus the derived
class member function is called. To achieve the concept of dynamic binding in
C++, the compiler creates a v-table each time a virtual function is declared.
This v-table contains classes and pointers to the functions from each of the
objects of the derived class. This is used by the compiler whenever a virtual
function is needed.
C++ Pure Virtual Function and Virtual Base Class
Pure Virtual Function is a Virtual function with no body.
- 41 -
Declaration of Pure Virtual Function:
Since pure virtual function has no body, the programmer must add the notation
=0 for declaration of the pure virtual function in the base class.
General Syntax of Pure Virtual Function takes the form:
class classname //This denotes the base class of C++ virtual function
{
public:
virtual void virtualfunctioname() = 0 //This denotes the pure virtual
function in C++
} ;
To understand the declaration and usage of Pure Virtual Function, refer to this
example:
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];
Exf1 e1;
Exf2 e2;
arra[0]=&e1;
- 42 -
arra[1]=&e2;
arra[0]->example();
arra[1]->example();
}

Since the above example has no body, the pure virtual function example() is
declared with notation =0 in the base class Exforsys. The two derived class
named Exf1 and Exf2 are derived from the base class Exforsys. The pure
virtual function example() takes up new definition. In the main function, a list
of pointers is defined to the base class.
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 and thus, the output is as in the above
example.
One must clearly understand the concept of pure virtual functions having
no body in the base class and the notation =0 is independent of value
assignment. The notation =0 simply indicates the Virtual function is a pure
virtual function as it has no body.
We may want to remove this pure virtual function from the base class as it
has no body but this would result in an error. Without the declaration of the
pure virtual function in the base class, accessing statements of the pure virtual
function such as, arra[0]->example() and arra[1]->example() would result in an
error. The pointers should point to the base class Exforsys. Special care must
be taken not to remove the statement of declaration of the pure virtual function
in the base class.
Virtual Base Class
In the following example, there are two derived classes Exf1 and Exf2 from
the base class Exforsys. As shown in the above diagram, the Training class is
derived from both of the derived classes Exf1 and Exf2. In this scenario, if a
user has a member function in the class Training where the user wants to access
- 43 -
the data or member functions of the class Exforsys it would result in error if it
is performed like this:

class Exforsys
{
protected:
int x;
} ;
class Exf1:public Exforsys
{ } ;
class Exf2:public Exforsys
{ } ;

class Training:public Exf1,public Exf2
{
public:
int example()
{
return x;
}
} ;

The above program results in a compile time error as the member function
example() of class Training tries to access member data x of class Exforsys.
This results in an error because the derived classes Exf1 and Exf2 (derived
from base class Exforsys) create copies of Exforsys called subobjects.
This means that each of the subobjects have Exforsys member data and
member functions and each have one copy of member data x. When the
member function of the class Training tries to access member data x, confusion
- 44 -
arises as to which of the two copies it must access since it derived from both
derived classes, resulting in a compile time error.
When this occurs, Virtual base class is used. Both of the derived classes
Exf1 and Exf2 are created as virtual base classes, meaning they should share a
common subobject in their base class.
For Example:
class Exforsys
{
protected:
int x;
} ;
class Exf1:virtual public Exforsys
{ } ;
class Exf2:virtual public Exforsys
{ } ;
class Training:public Exf1,public Exf2
{
public:
int example()
{
return x;
}
} ;
In the above example, both Exf1 and Exf2 are created as Virtual base classes by
using the keyword virtual. This enables them to share a common subobject of
their base class Exforsys. This results in only one copy that the member
function example() of Class Training can access the member data x.
List of Programs
1. Create a base class Shape with relevant data members and member functions
to get data and print the area. Create two more classes Rectangle and Triangle
which inherit Shape class. Make the print data function as virtual function in
base class. Write a C++ main ( ) function to check this.
2. Write a C++ program to implement virtual destructor concept.
3. Design a vehicle class that contains the following properties of motor
vehicles: Fuel tank capacity, average fuel consumption per 100 km and the
- 45 -
distance a vehicle can travel on a full tank. The vehicle class should be designed
as an abstract base class from which the Car and Truck classes are derived. The
derived classes should have following member functions.
A function that contains data for a vehicle from the user
A function that computes and returns the distance a vehicle can travel on
a full tank.
A function that computes and returns how many times a vehicle has to
be refueled to travel a given distance.
These functions should be used as pure virtual functions in the Vehicle class
and refined by the derived classes. Design the main ( ) function that instantiates a
pointer of Vehicle Type and , Car and Truck object respectively. The pointer
should be used to invoke appropriate member functions to get and process data
for car and truck. The program should output how many time each vehicle has to
be refueled to travel the distance entered by the user, as well as the distance each
vehicle can travel on a full tank.
Viva Questions
1. Justify the need for virtual functions in C++.
2. What are pure virtual functions? How they differ from normal virtual functions?
3. What is mean by abstract class?
4. Write the role of virtual destructors.
5. What is polymorphism?
6. What id meant by compile time binding and run time binding?
7. What are the merits and demerits of using pure virtual functions?
Learning Outcome
At the end of this exercise, the students will know
To identify the need for virtual functions in a program
How to use the concept of abstract classes
How polymorphism work with c++.

- 46 -
9. File Handling and I/O Manipulation
Aim
To understand and use various member functions for C++ formatted I/O.
To understand and use stream manipulators for C++ formatted I/O.
To open and close a file programmatically
To read from a file, to process the data and to write back again to the file
Theory
Manipulator
Manipulators are operators used in C++ for formatting output. The data is
manipulated by the programmers choice of display. Manipulators are the most
common way to control output formating.
endl Manipulator:
This manipulator has the same functionality as the \n newline character.
Example:
cout<<C<<endl;
cout<<C++;
produces the output:
C
C++
setw Manipulator: (available in iomanip.h)
This manipulator sets the minimum field width on output. The syntax is:
setw(x)
Here setw causes the number or string that follows it to be printed within a
field of x characters wide and x is the argument set in setw manipulator.
setfill Manipulator:
This is used after setw manipulator. If a value does not entirely fill a field,
then the character specified in the setfill argument of the manipulator is used for
filling the fields.
cout << setw(10) << setfill('$') << 50 << 33 << endl
- 47 -
Output
$$$$$$$$5033
This is because the setw sets 10 width for the field and the number 50 has only
2 positions in it. So the remaining 8 positions are filled with $ symbol which is
specified in the setfill argument.
setprecision Manipulator:
The setprecision Manipulator is used with floating point numbers. It is used
to set the number of digits printed to the right of the decimal point. This may be
used in two forms: fixed and scientific.
These two forms are used when the keywords fixed or scientific are
appropriately used before the setprecision manipulator. The keyword fixed before
the setprecision manipulator prints the floating point number in fixed notation.
The keyword scientific before the setprecision manipulator prints the floating point
number in scientific notation.
float x = 0.1;
cout << fixed << setprecision(3) << x << endl;
cout << sceintific << x << endl;
output:
0.100
1.000000e-001
The first cout statement contains fixed notation and the setprecision
contains argument 3. This means that three digits after the decimal point and in
fixed notation will output the first cout statement as 0.100. The second cout
produces the output in scientific notation. The default value is used since no
setprecision value is provided.
width(n)
Same as setw(n).
left
Left justifies output in field width. Only useful after setw(n).
- 48 -
right
Right justifies output in field width. Since this is the default, it is only used
to override the effects of left. Only useful after setw(n).
Other Manipulators

Predefined
Manipulator
Description
1 Cout << dec,
cin >> dec
Makes the integer conversion base 10.
2 Cout << ends Inserts a null (0) character. Useful when dealing with
strstreams.
3 cout << flush Invokes ostream::flush().
4 Cout << hex,
cin >> hex
Makes the integer conversion base 16.
5 cout << oct, cin
>> oct
Make the integer conversion base 8.
6 cin >> ws Extracts whitespace characters (skips whitespace) until
a non-whitespace character is found (which is left in
istr).
7 cout <<
setbase(n),
cin >>
setbase(n)
Sets the conversion base to n (0, 8, 10, 16 only).

To use predefined manipulators, one must include the file iomanip.h in your
program.
User defined manipulators.
There are two basic types of manipulator:
1. Plain manipulator--Takes an istream&, ostream&, or ios& argument, operates
on the stream, and then returns its argument.
2. Parameterized manipulator--Takes an istream&, ostream&, or ios& argument,
one additional argument (the parameter), operates on the stream, and then returns
its stream argument.
File Manipulations in C++
- 49 -
C++ provides the following classes to perform output and input of
characters to/from files:
ofstream: Stream class to write on files
ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.
These classes are derived directly or indirectly from the classes istream, and
ostream.
Open a file
An open file is represented within a program by a stream object (an
instantiation of one of these classes, in the previous example this was myfile) and
any input or output operation performed on this stream object will be applied to
the physical file associated to it.
Syntax
open (filename, mode);
Where filename is a null-terminated character sequence of type const char * (the
same type that string literals have) representing the name of the file to be opened,
and mode is an optional parameter with a combination of the following flags:

ios::in Open for input operations.
ios::out Open for output operations.
ios::binary Open in binary mode.
ios::ate
Set the initial position at the end of the file.
If this flag is not set to any value, the initial position is the
beginning of the file.
ios::app
All output operations are performed at the end of the file,
appending the content to the current content of the file. This
flag can only be used in streams open for output-only
operations.
ios::trunc
If the file opened for output operations already existed
before, its previous content is deleted and replaced by the new
one.
- 50 -
All these flags can be combined using the bitwise operator OR (|). For example, if
we want to open the file example.bin in binary mode to add data we could do it by
the following call to member function open():
ofstream myfile;
myfile.open ("example.bin", ios::out | ios::app | ios::binary);
Each one of the open() member functions of the classes ofstream, ifstream and
fstream has a default mode that is used if the file is opened without a second
argument:
class default mode parameter
ofstream ios::out
ifstream ios::in
fstream ios::in | ios::out

For ifstream and ofstream classes, ios::in and ios::out are automatically and
respectively assumed, even if a mode that does not include them is passed as
second argument to the open() member function.
The default value is only applied if the function is called without specifying
any value for the mode parameter. If the function is called with any value in that
parameter the default mode is overridden, not combined.
File streams opened in binary mode perform input and output operations
independently of any format considerations. Non-binary files are known as text files,
and some translations may occur due to formatting of some special characters (like
newline and carriage return characters).
Since the first task that is performed on a file stream object is generally to
open a file, these three classes include a constructor that automatically calls the
open() member function and has the exact same parameters as this member.
Therefore, we could also have declared the previous myfile object and conducted
the same opening operation in our previous example by writing:
ofstream myfile ("example.bin", ios::out | ios::app | ios::binary);
- 51 -
Combining object construction and stream opening in a single statement.
Both forms to open a file are valid and equivalent.
To check if a file stream was successful opening a file, you can do it by
calling to member is_open() with no arguments. This member function returns a
bool value of true in the case that indeed the stream object is associated with an
open file, or false otherwise:
if (myfile.is_open()) { /* ok, proceed with output */ }
Closing a file
When we are finished with our input and output operations on a file we
shall close it so that its resources become available again. In order to do that we
have to call the stream's member function close(). This member function takes no
parameters, and what it does is to flush the associated buffers and close the file:
myfile.close();
Once this member function is called, the stream object can be used to open
another file, and the file is available again to be opened by other processes. In case
that an object is destructed while still associated with an open file, the destructor
automatically calls the member function close().
Checking state flags
bad( )
Returns true if a reading or writing operation fails. For example in the case
that we try to write to a file that is not open for writing or if the device where we
try to write has no space left.
fail( )
Returns true in the same cases as bad(), but also in the case that a format
error happens, like when an alphabetical character is extracted when we are trying
to read an integer number.
eof( )
Returns true if a file open for reading has reached the end.

- 52 -
good( )
It is the most generic state flag: it returns false in the same cases in which
calling any of the previous functions would return true.
In order to reset the state flags checked by any of these member functions,
we can use the member function clear ( ), which takes no parameters.
Header files
Getting a stream
Three streams just exist: cout (terminal output), cin (terminal input), and
cerr (error output, which also goes to the terminal).
File streams are of type ifstream (input) or ofstream (output).
ifstream fp_in; // declarations of streams fp_in and fp_out
ofstream fp_out;
fp_in.open("myfile.txt", ios::in); // open the streams
fp_out.open("myfile.txt", ios::out);
fp_in.close(); // close the streams
fp_out.close();
A file should be closed if you are done with it, but the program will continue
running for a while longer. This is particularly important when you intend to open
a lot of files, as there may be a limit on how many you can have open at once. It is
also a good idea if you intend to open a file for input, and then re-open the file for
output.
Declaring the pointer and opening the file can be combined:
ifstream fp_in("myfile.txt", ios::in); // declare and open
The parameters ios::in and ios::out specify the mode in which the file is to
be opened. Depending on the implementation of C++, it may be possible to
specify a variety of other mode options, such as appending to the end of an
existing file, triggering an error rather than overwriting an existing file, or
specifying that a file is binary for operating systems (e.g. MS-DOS) which
distinguish binary and ASCII files.
- 53 -
Passing streams to functions
File streams must be passed to functions by reference, not by value.
void myfunction(ifstream &fp, ...) // use this
void myfunction(ifstream fp, ...) // not this
If you pass streams by value, the C++ compiler will not complain.
However, mysterious bad things will start happening, often in parts of the code
which don't appear to be related to the offending function.
Item by item input and output
If each input item is surrounded by whitespace (blanks, tabs, newlines), the
items can be read easily using the extraction operator >>.
int myinteger; // declarations
float myfloat;
char mychar;
char *mystring; // two ways to declare a string
char mystring[64];
fp_in >> myinteger; // input from file pointer or standard input
cin >> myfloat;
fp_in >> mychar;
cin >> mystring;
The extraction operator works for numbers (ints, floats), characters (char),
and strings (declared as arrays of type char or pointers to type char).
The extraction operator returns a zero value if it encounters a problem
(typically, the end of the file). Therefore, it can be used as the test in an if
statement or a while loop.
WARNING: when reading data into a character string, bad things will happen if
the input word is longer than your string. To avoid problems, use the operator
setw to force excessively long input to be broken up. (You must include the
iomanip header file.) The input to setw should be the length of your string
(including the null character '\0' at the end of the string).
- 54 -
cin >> setw(length) >> mystring;

Numbers, characters, and strings can be written to a file, standard output, or
the standard error using the insertion operator <<.
cout << "Value of myinteger " << myinteger << endl;
cout << "My string is " << mystring << " plus a null character\n" <<
flush;
To insert a line break, either insert the magic variable endl or write the end-
of-line character ('\n') to the output.
To make a pointer print out as a pointer, not as whatever type of data it
points to, cast it to the type (void *).
To make a character print as a number, cast it to type int. Similarly, you can
use a cast to convince C++ to print an integer as the corresponding
character.
cout << (void *)ptr;
cout << (int)ch;
cout << (char)ival;
Buffering and flush
When you send output to a stream, it does not necessarily get printed
immediately. Rather, it may wait in a buffer until some unspecified event,
e.g. buffer full enough, reading from input, or exit from program. The
details may vary.
Buffering makes it faster to print a large amount of output, particularly if
you are producing the output bit-by-bit (e.g. one character at a time).
However, it is a nuisance for output used in debugging (e.g. a statement that
informs you that step 3 of your algorithm has been finished).
Forcing all buffered output to actually be printed is known as "flushing" the
stream. A flush can be forced by calling the flush function associated with
- 55 -
each output stream, inserting the magic variable flush into the stream, or
inserting endl.
cout << flush;
cout.flush();
cout << endl;
Other input operations
ifstream fp_in;
fp_in.get(char &ch)
Puts the next input character in the variable ch. Returns an integer value,
which is zero if it encountered a problem (e.g. end of file).
fp_in.getline(char *buffer, int length)
Reads characters into the string buffer, stopping when (a) it has read length-
1 characters or (b) when it finds an end-of-line character ('\n') or the end of the
file. Stores a null character ('\0') after the last character read.
fp_in.read(char *buffer, int n)
Reads n bytes (or until the end of the file) from the stream into the buffer.
fp_in.gcount()
Returns the number of characters read by a preceding get, getline, or read
command.
fp_in.ignore(int n)
Remove the next n characters (or until end of file) from the input stream,
throwing them away into the Great Bit Bucket.
cin.putback(char ch)
Puts character ch back onto the stream. Bad things will happen if this
character is not the one most recently extracted from the stream.
These operations all return zero if something goes wrong, e.g. they hit the
end of the file. Therefore, they can be used as the condition in an if statement or
while loop.
- 56 -
In addition, there are two more input operations, get and peek. These
functions return EOF (which is secretly -1) if they encounter the end of the file.
The output of these functions should be put into an integer (not a char) variable.
fp_in.get( ) ; Returns the next character in the stream.
fp_in.peek( ); Returns the next character in the stream but does not remove
it from the stream.
Other output operations
ofstream fp_out;
Other options for writing data to an output stream are:
fp_out.put(char ch)
Puts ch onto the stream.
fp_out.write(char *str, int n)
Puts n characters onto the stream, reading them from the string str.
Repositioning and error states
In general, it is possible to move to any position in a file stream. This is a
capability most programmers use rarely, if at all. For fairly obvious reasons, don't
try to use repositioning operations on the standard input, output, or error streams.
The most likely reason for using a repositioning command is to rewind a file to the
start, so that you can read its contents again. This is done as follows:
fp_in.clear(); // forget we hit the end of file
fp_in.seekg(0, ios::beg); // move to the start of the file
List of Exercises
1. Create a user defined manipulator for displaying the details of employees in a
neat table format. (Hint: Employee details can be maintained as array of
structures).
2. Write a c++ program to create a sequential file and to write 20 random integer
numbers in the range 0 to 50 in that file. Now check the file and display on screen,
all numbers < 20 from that file.
- 57 -
3. Write a c++ program to read a list containing book name, book code and book
cost from user interactively. Produce the following output.
_________________________________________
NAME CODE COST
________________________________________
Turbo c++ 1001 $$$$250.95
C++ Primer 21 $$$$$$5.00
_________________________________________
4. Write a C++ program to copy the contents of one text file to another text file.
5. A file is required to record a citys daily temperature, humidity and barometric
pressure for one month. Design a program which first creates this file. It should
then open the file for reading and compute and displays the largest, smallest, and
average values of the temperature, humidity and barometric pressure data tat are
recorded in the file.
6. Write a C++ program to open two files containing integers (in sorted order) and
merge their contents.
Viva Questions
1. What is a stream?
2. What is the difference in using manipulators and ios functions?
3. What is file mode? Describe the various file mode options available.
4. Describe the approaches used to detect end-of-file condition.
5. What are the different types of errors that might pop-up while processing files?
6. What are the differences between sequential and random files?
Learning Outcome
At the end of this experiment, the students will be able to
Work with stream i/o manipulators
Will know how to create user defined manipulators
Will know how to open, process and close a text file.

- 58 -
10.Templates Function Templates and Class Templates
Aim
To learn about generic programming
To know how to implement function templates and class templates
Theory
Templates are very useful when implementing generic constructs like
vectors, stacks, lists, queues which can be used with any arbitrary type. C++
templates provide a way to re-use source code as opposed to inheritance and
composition which provide a way to re-use object code.
C++ provides two kinds of templates: class templates and function
templates. Use function templates to write generic functions that can be used
with arbitrary types. For example, one can write searching and sorting routines
which can be used with any arbitrary type. The Standard Template Library
generic algorithms have been implemented as function templates, and the
containers have been implemented as class templates.
Class Templates
A class template definition looks like a regular class definition, except it is
prefixed by the keyword template. For example, here is the definition of a class
template for a Stack.
template <class T>
class Stack
{
public:
Stack(int = 10) ;
~Stack() { delete [] stackPtr ; }
int push(const T&);
int pop(T&) ;
int isEmpty()const { return top == -1 ; }
int isFull() const { return top == size - 1 ; }
private:
int size ; // number of elements on Stack.
int top ;
T* stackPtr ;
} ;
- 59 -
T is a type parameter and it can be any type. For example, Stack<Token>,
where Token is a user defined class. T does not have to be a class type as
implied by the keyword class. For example, Stack<int> and Stack<Message*>
are valid instantiations, even though int and Message* are not "classes".
Implementing class template member functions
Implementing template member functions is somewhat different compared
to the regular class member functions. The declarations and definitions of the
class template member functions should all be in the same header file. The
declarations and definitions need to be in the same header file. Consider the
following.
//B.H
template <class t>
class b
{
public:
b() ;
~b() ;
} ;
// B.CPP
# include "B.H"
template <class t>
b<t>::b()
{
}
template <class t>
b<t>::~b()
{
}
//MAIN.CPP
# include "B.H"
void main()
{
b<int> bi ;
b <float> bf ;
}

When compiling B.cpp, the compiler has both the declarations and the
definitions available. At this point the compiler does not need to generate any
definitions for template classes, since there are no instantiations. When the
compiler compiles main.cpp, there are two instantiations: template class B<int>
and B<float>. At this point the compiler has the declarations but no
definitions!
Using a class template
Using a class template is easy. Create the required classes by plugging in the
actual type for the type parameters. This process is commonly known as
"Instantiating a class".

- 60 -
Example
typedef Stack<float> FloatStack ;
FloatStack fs(5) ;
A good programming practice is using typedef while instantiating template
classes. Then throughout the program, one can use the typedef name. There are
two advantages:
Function Templates
To perform identical operations for each type of data compactly and
conveniently, use function templates. 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. The STL algorithms are implemented as
function templates.
Implementing Template Functions
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 Template Functions
Using function templates is very easy: just use them like 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
- 61 -
template <class T>
T max(T a, T b)
{
return a > b ? a : b ;
}
void 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 ;
}
Template Instantiation
When the compiler generates a class, function or static data members from a
template, it is referred to as template instantiation.
A class generated from a class template is called a generated class.
A function generated from a function template is called a generated
function.
A static data member generated from a static data member template 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.
Templates and Friends
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). The table below lists the results of declaring
different kinds of friends of a class.
Class
Template
friend declaration
in class template
X
Results of giving friendship
template
class <T>
class X
friend void f1() ;
makes f1() a friend of all
instantiations of template X. For
example, f1() is a friend of X<int>,
X<A>, and X<Y>.
- 62 -
template
class <T>
class X
friend void
f2(X<T>&) ;
For a particular type T for example,
float, makes f2(X<float>&) a friend
of class X<float> only.
f2(x<float>&) cannot be a friend of
class X<A>.
template
class <T>
class X
friend A::f4() ; // A
is a user defined
class with a member
function f4() ;
makes A::f4() a friend of all
instantiations of template X. For
example, A::f4() is a friend of
X<int>, X<A>, and X<Y>.
template
class <T>
class X
friend
C<T>::f5(X<T>&)
; // C is a class
template with a
member function f5
For a particular type T for example,
float, makes
C<float>::f5(X<float>&) a friend
of class X<float> only.
C<float>::f5(x<float>&) cannot be
a friend of class X<A>.
template
class <T>
class X
friend class Y ;
makes every member function of
class Y a friend of every template
class produced from the class
template X.
template
class <T>
class X
friend class Z<T> ;
when a template class is instantiated
with a particular type T, such as a
float, all members of class Z<float>
become friends of template class
X<float>.

List of Exercises
1. Write a function template for finding the minimum value contained in an
array.
2. Write a C++ program to represent a stack data structure using class template.
2. Write a class template to represent generic vector include member function
to perform following tasks.
a. To create a vector.
b. To modify the value of given element.
c. To multiply by scalar value.
d. To display the vector in the form (a,b,c,..)
- 63 -
Viva Questions
1. What is meant by generic programming?
2. How the compiler processes calls to a function template?
3. How the compiler processes calls to a class template?
4. Distinguish between overloaded function and function template.
Learning Outcome
At the end of this experiment, the students will be able to
Understand the need for generic programming
Know how to develop C++ program using class template and function
template






















- 64 -
11. Exception Handling
Aim
To understand the importance of fault tolerance in programming
To learn how to handle exceptions .
Theory
Exceptions provide a way to react to exceptional circumstances (like
runtime errors) in our program by transferring control to special functions called
handlers. To catch exceptions we must place a portion of code under exception
inspection. This is done by enclosing that portion of code in a try block. When an
exceptional circumstance arises within that block, an exception is thrown that
transfers the control to the exception handler. If no exception is thrown, the code
continues normally and all handlers are ignored.
A exception is thrown by using the throw keyword from inside the try
block. Exception handlers are declared with the keyword catch, which must be
placed immediately after the try block:
int main ( )
{
try
{
throw 20;
}
catch (int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
}
return 0;
}
Here An exception is occurred and its exception Number. is 20. The code
under exception handling is enclosed in a try block. A throw expression accepts
one parameter (in this case the integer value 20), which is passed as an argument to
the exception handler. The exception handler is declared with the catch keyword.
As you can see, it follows immediately the closing brace of the try block. The catch
format is similar to a regular function that always has at least one parameter. The
- 65 -
type of this parameter is very important, since the type of the argument passed by
the throw expression is checked against it, and only in the case they match, the
exception is caught. We can chain multiple handlers (catch expressions), each one
with a different parameter type. Only the handler that matches its type with the
argument specified in the throw statement is executed. If we use an ellipsis (...) as
the parameter of catch, that handler will catch any exception no matter what the
type of the throw exception is. This can be used as a default handler that catches all
exceptions not caught by other handlers if it is specified at last:
try {
// code here
}
catch (int param) { cout << "int exception"; }
catch (char param) { cout << "char exception"; }
catch (...) { cout << "default exception"; }
In this case the last handler would catch any exception thrown with any
parameter that is neither an int nor a char. After an exception has been handled
the program execution resumes after the try-catch block, not after the throw
statement!. It is also possible to nest try-catch blocks within more external try
blocks. In these cases, we have the possibility that an internal catch block forwards
the exception to its external level. This is done with the expression throw; with no
arguments. For example:
try {
try {
// code here
}
catch (int n) {
hrow;
}
}
catch (...) {
out << "Exception occurred";
}

- 66 -
Exception specifications
When declaring a function we can limit the exception type it might directly
or indirectly throw by appending a throw suffix to the function declaration:
float myfunction (char param) throw (int);
This declares a function called myfunction which takes one argument of
type char and returns an element of type float. The only exception that this
function might throw is an exception of type int. If it throws an exception with a
different type, either directly or indirectly, it cannot be caught by a regular int-type
handler. If this throw specifier is left empty with no type, this means the function
is not allowed to throw exceptions. Functions with no throw specifier (regular
functions) are allowed to throw exceptions with any type:
int myfunction (int param) throw(); // no exceptions allowed
int myfunction (int param); // all exceptions allowed
Standard exceptions
The C++ Standard library provides a base class specifically designed to
declare objects to be thrown as exceptions. It is called exception and is defined in
the <exception> header file under the namespace std. This class has the usual
default and copy constructors, operators and destructors, plus an additional virtual
member function called what that returns a null-terminated character sequence
(char *) and that can be overwritten in derived classes to contain some sort of
description of the exception.
// standard exceptions
#include <iostream>
#include <exception>
using namespace std;
class myexception: public exception
{
virtual const char* what() const throw()
{
return "My exception happened";
}
} myex;

- 67 -
int main () {
try
{
throw myex;
}
catch (exception& e)
{
cout << e.what() << endl;
}
return 0;
}

We have placed a handler that catches exception objects by reference (notice
the ampersand & after the type), therefore this catches also classes derived from
exception, like our myex object of class myexception. All exceptions thrown by
components of the C++ Standard library throw exceptions derived from this
std::exception class. These are:
exception description
bad_alloc thrown by new on allocation failure
bad_cast thrown by dynamic_cast when fails with a referenced type
bad_exception thrown when an exception type doesn't match any catch
bad_typeid thrown by typeid
ios_base::failure thrown by functions in the iostream library
For example, if we use the operator new and the memory cannot be
allocated, an exception of type bad_alloc is thrown:
try
{
int * myarray= new int[1000];
}
catch (bad_alloc&)
{
cout << "Error allocating memory." << endl;
}

- 68 -
It is recommended to include all dynamic memory allocations within a try
block that catches this type of exception to perform a clean action instead of an
abnormal program termination, which is what happens when this type of exception
is thrown and not caught. If you want to force a bad_alloc exception to see it in
action, you can try to allocate a huge array; On my system, trying to allocate 1
billion ints threw a bad_alloc exception.

List of Exercises
1. Design two functions with an exception-specification lists as follows:
a) A function which can throw only an integer exception
b) A function which can throw only a string exception
Design a main( ) function with a try block that is used to test and handle
exceptions thrown by these two functions.
2. Write a C++ program to handle divide by zero exception.
3. Write a C++ program to handle array out of bound exception.
4. Write a C++ program to find the roots of a quadratic equation. Throw an
exception whenever an imaginary root is found.
5. Write a C++ program to process memory allocation error using exception
handling mechanism.
6. Write C++ programs handle multiple catch block, default catch block and
rethrowing exceptions for your own problem situation.

Viva Questions
1. What happens when a raised exception is not handled by a catch block?
2. When memory allocation fails, how does the new operator notify the error
to the caller?
3. What should be placed inside a catch block?
4. Why should we rethrow an exception?
5. When do we use multiple catch handlers?
- 69 -
Learning Outcome
At the end of this experiment, the students will be able to
Know how to handle the exception in C++ language1
How to rethrow the exception
How to handle exception using functions.


























- 70 -
Appendix A: C++ Reserved Words
C++ reserves some words for its own use in the libraries. These words have
special meaning to the compiler and therefore can not be used as identifiers in a
declaration statement. Reserved words are classified into three categories:
C++ Keywords
asm auto bool break case
catch char class const const_cast
continue default delete do double
dynamic_cast else enum explicit export
extern false float for friend
goto if inline int long
mutable namespace new operator private
protected public register reinterpret_cast while
return short signed sizeof static
static_cast struct switch template this
throw true try typedef typeid
typename union unsigned using virtual
void volatile wchar_t
Alternative Tokens
Alternative tokens are the equivalences of operators at the right side of the
following list.
Token Meaning
and &&
and_eq &=
bitand &
bitor |
compl ~
not !
not_e !=
or ||
or_eq |=
xor ^
xor_eq ^=
- 71 -
Appendix B: Programming Guidelines
Remember the divide and conquer principle. If the problem youre
looking at is too confusing, try to imagine what the basic operation of the
program would be, given the existence of a magic piece that handles the hard
parts. That piece is an object write the code that uses the object, then look
at the object and encapsulate its hard parts into other objects, etc.
Dont automatically rewrite all your existing C code in C++ unless you
need to significantly change its functionality (that is, dont fix it if it isnt
broken). Recompiling C in C++ is a valuable activity because it may reveal hidden
bugs. However, taking C code that works fine and rewriting it in C++ may not
be the best use of your time, unless the C++ version will provide a lot of
opportunities for reuse as a class.
If you do have a large body of C code that needs changing, first isolate the parts
of the code that will not be modified, possibly wrapping those functions in an
API class as static member functions. Then focus on the code that will be
changed, Refactoring it into classes to facilitate easy modifications as your
maintenance proceeds.
When you create a class, make your names as clear as possible. Your goal
should be to make the client programmers interface conceptually simple.
Attempt to make your names so clear that comments are unnecessary. To this
end, use function overloading and default arguments to create an intuitive, easy-
to-use interface.
Access control allows you (the class creator) to change as much as possible in
the future without damaging client code in which the class is used. In this light,
keep everything as private as possible, and make only the class interface
public, always using functions rather than data. Make data public only when
forced. If class users dont need to access a function, make it private. If a part
of your class must be exposed to inheritors as protected, provide a function
interface rather than expose the actual data. In this way, implementation
- 72 -
changes will have minimal impact on derived classes. Dont fall into analysis
paralysis. There are some things that you dont learn until you start coding and
get some kind of system working. C++ has built-in firewalls; let them work for
you. Your mistakes in a class or set of classes wont destroy the integrity of the
whole system.
Your analysis and design must produce, at minimum, the classes in your system,
their public interfaces, and their relationships to other classes, especially base
classes. If your design methodology produces more than that, ask yourself if all
the pieces produced by that methodology have value over the lifetime of the
program. If they do not, maintaining them will cost you. Members of
development teams tend not to maintain anything that does not contribute to
their productivity; this is a fact of life that many design methods dont account
for.
Make classes as atomic as possible; that is, give each class a single, clear
purpose. If your classes or your system design grows too complicated, break
complex classes into simpler ones. The most obvious indicator of this is sheer
size: if a class is big, chances are its doing too much and should be broken up.
Watch for long member function definitions. A function that is long and
complicated is difficult and expensive to maintain, and is probably trying to do
too much all by itself. If you see such a function, it indicates that, at the least, it
should be broken up into multiple functions. It may also suggest the creation of
a new class.
Watch for long argument lists. Function calls then become difficult to write,
read and maintain. Instead, try to move the member function to a class where it
is (more) appropriate, and/or pass objects in as arguments.
Dont repeat yourself. If a piece of code is recurring in many functions in
derived classes, put that code into a single function in the base class and call it
from the derived-class functions. Not only do you save code space, you provide
for easy propagation of changes. You can use an inline function for efficiency.
- 73 -
Sometimes the discovery of this common code will add valuable functionality
to your interface. Watch for switch statements or chained if-else clauses. This
is typically an indicator of type-check coding, which means you are choosing what
code to execute based on some kind of type information (the exact type may
not be obvious at first). You can usually replace this kind of code with
inheritance and polymorphism; a polymorphic function call will perform the
type checking for you, and allow for more reliable and easier extensibility.
From a design standpoint, look for and separate things that change from things
that stay the same. That is, search for the elements in a system that you might
want to change without forcing a redesign, then encapsulate those elements in
classes.
Watch out for variance. Two semantically different objects may have identical
actions, or responsibilities, and there is a natural temptation to try to make one
a subclass of the other just to benefit from inheritance. This is called variance,
but theres no real justification to force a superclass/subclass relationship where
it doesnt exist. A better solution is to create a general base class that produces
an interface for both as derived classes it requires a bit more space, but you
still benefit from inheritance and will probably make an important discovery
about the design.
Watch out for limitation during inheritance. The clearest designs add new
capabilities to inherited ones. A suspicious design removes old capabilities
during inheritance without adding new ones. But rules are made to be broken,
and if you are working from an old class library, it may be more efficient to
restrict an existing class in its subclass than it would be to restructure the
hierarchy so your new class fits in where it should, above the old class. Dont
extend fundamental functionality by subclassing. If an interface element is
essential to a class it should be in the base class, not added during derivation. If
youre adding member functions by inheriting, perhaps you should rethink the
design.
- 74 -
Less is more. Start with a minimal interface to a class, as small and simple as
you need to solve the problem at hand, but dont try to anticipate all the ways
that your class might be used. As the class is used, youll discover ways you must
expand the interface. However, once a class is in use you cannot shrink the
interface without disturbing client code. If you need to add more functions,
thats fine; it wont disturb code, other than forcing recompiles. But even if new
member functions replace the functionality of old ones, leave the existing
interface alone (you can combine the functionality in the underlying
implementation if you want). If you need to expand the interface of an existing
function by adding more arguments, leave the existing arguments in their
current order, and put default values on all of the new arguments; this way you
wont disturb any existing calls to that function.
Read your classes aloud to make sure theyre logical, referring to the
relationship between a base class and derived class as is-a and member
objects as has-a.
When deciding between inheritance and composition, ask if you need to upcast
to the base type. If not, prefer composition (member objects) to inheritance.
This can eliminate the perceived need for multiple inheritance. If you inherit,
users will think they are supposed to upcast.
Sometimes you need to inherit in order to access protected members of the
base class. This can lead to a perceived need for multiple inheritance. If you
dont need to upcast, first derive a new class to perform the protected access.
Then make that new class a member object inside any class that needs to use it,
rather than inheriting.
Typically, a base class will be used primarily to create an interface to classes
derived from it. Thus, when you create a base class, default to making the
member functions pure virtual. The destructor can also be pure virtual (to force
inheritors to explicitly override it), but remember to give the destructor a
function body, because all destructors in a hierarchy are always called.
- 75 -
When you put a virtual function in a class, make all functions in that class
virtual, and put in a virtual destructor. This approach prevents surprises in the
behavior of the interface. Only start removing the virtual keyword when youre
tuning for efficiency and your profiler has pointed you in this direction.
Use data members for variation in value and virtual functions for variation in
behavior. That is, if you find a class that uses state variables along with member
functions that switch behavior based on those variables, you should probably
redesign it to express the differences in behavior within subclasses and
overridden virtual functions.
If you must do something nonportable, make an abstraction for that service
and localize it within a class. This extra level of indirection prevents the non-
portability from being distributed throughout your program.
Avoid multiple inheritance. Its for getting you out of bad situations,
especially repairing class interfaces in which you dont have control of the
broken class.
Dont use private inheritance. Although its in the language and seems to
have occasional functionality, it introduces significant ambiguities when
combined with run-time type identification. Create a private member object
instead of using private inheritance.
If two classes are associated with each other in some functional way (such as
containers and iterators), try to make one a publicnested friend class of the
other, as the Standard C++ Library does with iterators inside containers. It
allows the class name to be reused by nesting it within another class. The other
reason youll want to nest a class is as part of the private implementation. Here,
nesting is beneficial for implementation hiding rather than the class association
and prevention of namespace pollution noted above.
Operator overloading is only syntactic sugar: a different way to make a
function call. If overloading an operator doesnt make the class interface clearer
- 76 -
and easier to use, dont do it. Create only one automatic type conversion
operator for a class.
Dont fall prey to premature optimization. That way lies madness. In
particular, dont worry about writing (or avoiding) inline functions, making
some functions non virtual, or tweaking code to be efficient when you are first
constructing the system. Your primary goal should be to prove the design,
unless the design requires certain efficiency.
Normally, dont let the compiler create the constructors, destructors, or
the operator= for you. Class designers should always say exactly what the class
should do and keep the class entirely under control. If you dont want a
copyconstructor or operator=, declare them as private. Remember that if you
create any constructor, it prevents the default constructor from being
synthesized.
If your class contains pointers, you must create the copy constructor,
operator=, and destructor for the class to work properly.
When you write a copy-constructor for a derived class, remember to call the
base-class copy-constructor explicitly. If you dont, the default constructor will
be called for the base class (or member object) and that probably isnt what you
want. To call the base-class copy-constructor, pass it the derived object youre
copying from:
Derived(const Derived& d) : Base(d) { // ...
When you write an assignment operator for a derived class, remember to call
the base-class version of the assignment operator explicitly. If you dont, then
nothing will happen (the same is true for the member objects). To call the base-
class assignment operator, use the base-class name and scope resolution:
Derived& operator=(const Derived& d) {
Base::operator=(d);
Avoid the preprocessor. Always use const for value substitution and inlines
for macros.
- 77 -
Keep scopes as small as possible so the visibility and lifetime of your objects
are as small as possible. This reduces the chance of using an object in the wrong
context and hiding a difficult-to-find bug. For example, suppose you have a
container and a piece of code that iterates through it. If you copy that code to
use with a new container, you may accidentally end up using the size of the old
container as the upper bound of the new one. If, however, the old container is
out of scope, the error will be caught at compile time.
Avoid global variables. Always strive to put data inside classes. Global
functions are more likely to occur naturally than global variables, although you
may later discover that a global function may fit better as a static member of a
class.
If you need to declare a class or function from a library, always do so by
including a header file. For example, if you want to create a function to write to
an ostream, never declare ostream yourself using an incomplete type
specification like this, class ostream; This approach leaves your code
vulnerable to changes in representation. (For example, ostream could actually
be a typedef.) Instead, always use the header file: #include <iostream>.
When creating your own classes, if a library is big, provide your users an
abbreviated form of the header file with incomplete type specifications (that is,
class name declarations) for cases in which they need to use only pointers. (It
can speed compilations.)
When choosing the return type of an overloaded operator, consider what will
happen if expressions are chained together. Return a copy or reference to the
lvalue (return *this) so it can be used in a chained expression (A = B = C).
When defining operator=, remember x=x.
When writing a function, pass arguments by const reference as your first
choice. As long as you dont need to modify the object being passed, this
practice is best because it has the simplicity of pass-by-value syntax but doesnt
require expensive constructions and destructions to create a local object, which
- 78 -
occurs when passing by value. Normally you dont want to be worrying too
much about efficiency issues when designing and building your system, but this
habit is a sure win.
Be aware of temporaries. When tuning for performance, watch out for
temporary creation, especially with operator overloading. If your constructors
and destructors are complicated, the cost of creating and destroying
temporaries can be high. When returning a value from a function, always try to
build the object in place with a constructor call in the return statement:
return MyType(i, j);
rather than
MyType x(i, j);
return x;
The former return statement (the so-called return-value optimization) eliminates
a copy- constructor call and destructor call.
When creating constructors, consider exceptions. In the best case, the
constructor wont do anything that throws an exception. In the next-best
scenario, the class will be composed and inherited from robust classes only, so
they will automatically clean themselves up if an exception is thrown. If you
must have naked pointers, you are responsible for catching your own
exceptions and then deallocating any resources pointed to before you throw an
exception in your constructor. If a constructor must fail, the appropriate action
is to throw an exception.
Do only what is minimally necessary in your constructors. Not only does
this produce a lower overhead for constructor calls (many of which may not be
under your control) but your constructors are then less likely to throw
exceptions or cause problems.
The responsibility of the destructor is to release resources allocated during the
lifetime of the object, not just during construction.
- 79 -
Use exception hierarchies, preferably derived from the Standard C++
exception hierarchy and nested as public classes within the class that throws the
exceptions. The person catching the exceptions can then catch the specific
types of exceptions, followed by the base type. If you add new derived
exceptions, existing client code will still catch the exception through the base
type.
Throw exceptions by value and catch exceptions by reference. Let the
exception-handling mechanism handle memory management. If you throw
pointers to exception objects that have been created on the heap, the catcher
must know to destroy the exception, which is bad coupling. If you catch
exceptions by value, you cause extra constructions and destructions; worse, the
derived portions of your exception objects may be sliced during upcasting by
value.
Dont write your own class templates unless you must. Look first in the
Standard C++ Library, then to vendors who create special-purpose tools.
Become proficient with their use and youll greatly increase your productivity.
When creating templates, watch for code that does not depend on type and put
that code in a non-template base class to prevent needless code bloat. Using
inheritance or composition, you can create templates in which the bulk of the
code they contain is type-dependent and therefore essential.
Dont use the <cstdio> functions, such as printf( ). Learn to use iostreams
instead; they are type-safe and type-extensible, and significantly more powerful.
Your investment will be rewarded regularly. In general, always use C++
libraries in preference to C libraries.
Avoid Cs built-in types. They are supported in C++ for backward
compatibility, but they are much less robust than C++ classes, so your bug-
hunting time will increase. Whenever you use built-in types as globals or
automatics, dont define them until you can also initialize them. Define
variables one per line along with their initialization. When defining pointers, put
- 80 -
the * next to the type name. You can safely do this if you define one variable
per line. This style tends to be less confusing for the reader.
Guarantee that initialization occurs in all aspects of your code. Perform all
member initialization in the constructor initializer list, even built-in types (using
pseudo-constructor calls). Using the constructor initializer list is often more
efficient when initializing subobjects; otherwise the default constructor is called,
and you end up calling other member functions (probably operator=) on top
of that in order to get the initialization you want.
Dont use the form MyType a = b; to define an object. This one feature is a
major source of confusion because it calls a constructor instead of the
operator=. For clarity, always be specific and use the form MyType a(b);
instead. The results are identical, but other programmers wont be confused.
Use the explicit casts. A cast overrides the normal typing system and is a
potential error spot. Since the explicit casts divide Cs one-cast-does-all into
classes of well-marked casts, anyone debugging and maintaining the code can
easily find all the places where logical errors are most likely to happen.
For a program to be robust, each component must be robust. Use all the tools
provided by C++: access control, exceptions, const-correctness, type checking,
and so on in each class you create. That way you can safely move to the next
level of abstraction when building your system.
Build in const-correctness. This allows the compiler to point out bugs that
would otherwise be subtle and difficult to find. This practice takes a little
discipline and must be used consistently throughout your classes, but it pays
off.
Use compiler error checking to your advantage. Perform all compiles with
full warnings, and fix your code to remove all warnings. Write code that utilizes
the compile-time errors and warnings rather than that which causes runtime
errors (for example, dont use variadic argument lists, which disable all type
checking). Use assert( ) for debugging, but use exceptions for runtime errors.
- 81 -
Prefer compile-time errors to runtime errors. Try to handle an error as close
to the point of its occurrence as possible. Prefer dealing with the error at that
point to throwing an exception. Catch any exceptions in the nearest handler
that has enough information to deal with them. Do what you can with the
exception at the current level; if that doesnt solve the problem, rethrow the
exception. If youre using exception specifications install your own
unexpected( ) function using set_unexpected( ) . Your unexpected( )
should log the error and rethrow the current exception. That way, if an existing
function gets overridden and starts throwing exceptions, you will have a record
of the culprit and can modify your calling code to handle the exception. Create
a user-defined terminate( ) (indicating a programmer error) to log the error
that caused the exception, then release system resources, and exit the program.
If a destructor calls any functions, those functions might throw exceptions. A
destructor cannot throw an exception (this can result in a call to terminate( ),
which indicates a programming error), so any destructor that calls functions
must catch and manage its own exceptions.
Dont create your own decorated private data member names
(prepending underscores, Hungarian notation, etc.), unless you have a lot of
pre-existing global values; otherwise, let classes and namespaces do the name
scoping for you.
Watch for overloading. A function should not conditionally execute code
based on the value of an argument, default or not. In this case, you should
create two or more overloaded functions instead.
Hide your pointers inside container classes. Bring them out only when you
are going to immediately perform operations on them. Pointers have always
been a major source of bugs. When you use new, try to drop the resulting
pointer into a container. Prefer that a container own its pointers so its
responsible for cleanup. Even better, wrap a pointer inside a class; if you still
want it to look like a pointer, overload operator->and operator*. If you must
- 82 -
have a free-standing pointer, always initialize it, preferably to an object address,
but to zero if necessary. Set it to zero when you delete it to prevent accidental
multiple deletions.
Dont overload global new and delete; always do this on a class-by-class
basis. Overloading the global versions affects the entire client programmer
project, something only the creators of a project should control. When
overloading new and delete for classes, dont assume that you know the size of
the object; someone may be inheriting from you. Use the provided argument. If
you do anything special, consider the effect it could have on inheritors.
Prevent object slicing. It virtually never makes sense to upcast an object by
value. To prevent upcasting by value, put pure virtual functions in your base
class.

















- 83 -
Appendix C: Sample Programs
Problem 1 : Write a C++ program to find the area of a rectangle using inline
function.

Aim
To write a c++ program to find the area of a rectangle for its given length and
width using inline function.

Algorithm
1. Include the necessary header files iostream.h and conio.h
2. Declare and define an inline function find_area( ) with two arguments
length and width of float type.
3. Also make the return type of that function as float.
4. The inline function returns the multiplication of length and width.
5. In main function declare necessary variables for length, width and area
for the given rectangle.
6. Get input from user for length and width.
7. Call the inline function find_area( ) with user specified length and width.
8. Print the area of the rectangle returned by the inline function

Program
# include<iostream.h>
# include<conio.h>
inline float find_area(float length, float width)
{
return length * width;
}
int main()
{
float len, wid, area;
clrscr();
cout<<"Enter the length of the rectangle : ";
cin>>len;
- 84 -
cout<<"Enter the width of the rectangle: ";
cin>>wid;
area=find_area(len,wid);
cout<<"Area of rectangle = "<<area;
getch();
return 0;
}

Sample Input

Enter the length of the rectangle
10.2
Enter the width of the rectangle
5.1

Sample Output

Area of rectangle = 52.02

Result
Thus the c++ program to find the area of a rectangle using inline function is
created and executed successfully.














- 85 -
Problem 2: Given that an EMPLOYEE class contains the following
members: Data Members: Employee_Number, Employee_Name, Basic,
DA, IT, Net_Sal. Member Functions: to read data, to calculate and print
Net_Sal. Write a C++ program to read data on N employees and compute
the Net_Sal of each employee
(DA = 52% of Basic and Income Tax = 30% of the gross salary)
Aim
To develop a c++ program to represeant an employee details as a class and
to calculate and display the salary details using member functions.
Alogirthm
1. Include the the necessary header file.
2. Create a class EMPLOYEE with data members employee no, employee name ,
basic pay, dearness allowance, income tax, and net salary.
3. Also include three member function to read the data calculate net salary and to
display data.
4. In the read member function, read employee name, number and basic salary.
5. In calculate_net_salary function, calculate DA, Gross salary, IT and Net salary
as follows.
DA = 52 % of basic salary
Gross Salary = basic+DA
Income_tax(IT) = 30 % of gross salary
Net salary = Gross_Sal-IT;
6. In display member function, display the employee number, name and net salary
detail.
7. In main function, create and object for EMPLOYEE class and call all the
member functions.
Program
# include <iostream.h>
# include <conio.h>
class EMPLOYEE //implements the EMPLOYEE class
{
private:
- 86 -
char employee_number[10],employee_name[10];
float basic,DA, IT, net_sal;
public:
void Read_Data(); //reads the employee_number, name and basic
void Calculate_Net_Salary(); //calculates the net salary
void Display_Data(); //Displays the data
} ;

void EMPLOYEE::Read_Data()
{
cout << "Enter the Employee Number and Name : " << endl;
cin >> employee_number >> employee_name;
cout << "Enter the Basic Salary: " << endl;
cin >> basic;
}

void EMPLOYEE::Calculate_Net_Salary()
{
float Gross_Sal;
DA = (52*basic)/100;
Gross_Sal = basic+DA;
IT = (30*Gross_Sal)/100;
net_sal = Gross_Sal-IT;
}

void EMPLOYEE::Display_Data()
{
cout << "Emp Name: " << employee_name << "\n";
cout<<"Emp Number: " <<employee_number<<\n";
cout << "Net Salary: " << net_sal << endl;
}

int main()
{
int n,i;
clrscr();
cin >> n; cout << endl;
EMPLOYEE Emp;
cout << "Enter employee data" << endl;
Emp.Read_Data();
Emp.Calculate_Net_Salary();
Emp.Display_Data();
}
}
- 87 -
Sample Input
Enter the employee data
Enter the Employee Number and Name: Ram Emp0010
Enter the Basic Salary: 8500

Sample Output
Emp Name : Ram
Emp Number: Emp0010
Net Salary: 9044

Result
Thus the C++ program to find the employee salary details have been
generated by using the concept of classes and executed successfully.
















- 88 -
References
[1] Goran Svenk (2002), Object-oriented Programming using C++ for
Engineering and Technology, Thomson Delmar Learning.
[2] Harvey M. Deitel and Paul J. Deitel (2004), Simply C++ An Application
Driven Tutorial Approach, Prentice Hall.
[3] E.Balagurusamy, Object Oriented Programming with C++, 4
th
edition,
Tata Mcgraw Hill.
[4] M.T.Somashekara, Programming in C++, July 2009, Prentice Hall of India
[5] K.R.Venugopal, Rajkumar, T.Ravishankar (2009), Mastering C++, Tata
Mcgraw Hill.
[6] D.S.Malik, C++ programming Language, 4
th
edition, Cengage Learning.
[7] Bruce Eckel (2000), Thinking in C++, 2
nd
edition, Prentice Hall.
[8] http://www.cplusplus.com
[9] http://cpptips.hyperformix.com
[10] http://www.learncpp.com/
[11] http://www.cpp4u.com/

Вам также может понравиться