C
C
C
C++
(BCA-321)
B.C.A.
EXPERTS COMMITTEE
Dr. Rahul Kulkarni (Member, Board of Studies, Computer Science, North Maharashtra University)
Dr. Anurag Seetha (Prof. & Dean, Computer Science & Engineering, Dr. C.V. Raman University)
SIM PREPARATION
COVER DESIGN
Mr. Chandrashekhar Kadam
2013 (Revised)
© Tilak Maharashtra Vidyapeeth, Pune - 411 037.
All rights reserved. No part of this work may be reproduced in any form, by mimeograph or any other
means, without permission in writing from the Tilak Maharashtra Vidyapeeth.
Friends, it is indeed with great pleasure that we are placing the material
for B.C. A. in your hands.
The outline given at the beginning of a chapter highlights the main points.
So you will come to know what the chapter is about.
For concentration, constant reading is not beneficial. Considering this,
every chapter has been split into subparts.
Read the sub-parts. If necessary take the help of the meanings of the
foreign or difficult words, signs and concepts given at the end.
The margin provided on each page is for noting down your points. Make
proper use of the same.
After you read one part of a chapters, stop for a while and solve the
objective type or short questions given in “Check your progress”. Check
your answers with those given at the end of the chapter and correct the
wrong answers, if any.
Before starting the reading of the next chapter, first of all, read your
answers to “Check your progress” and make corrections therein. By
this you will remember what you have read.
Study all the chapters in this way.
The field work given at the end of some chapters is to link your experience
and your observations. Before starting the next chapters make a quick
revision of what you have studied earlier. For this read the summary of
the previous chapters.
For a total comprehension of the subject, the study of the complete
book is essential.
About the Subject
Object orientation and object-orientated languages are playing an increasingly
important role in the computing industry today. C++ is the most widely used object-
oriented language. This book helps you in understanding the concept of object-
oriented programming.
This book has been divided into 12 chapters. The first chapter i.e., “Introduction
to Object Oriented Programming” gives a brief introduction about the history of C++
as an Object Oriented language, and its various features. It explains the
characteristics of object-oriented programming language and its advantages.
The third chapter deals with arrays and pointers. It explains the concepts of
array and pointers, manipulation of two-dimensional array and pointers and
how character array is defined in C++.
Contents
4. Functions 25
6. Operator Overloading 51
8. Inheritance 81
9. Polymorphism 99
Syllabus
INTRODUCTION
C++ programming Basic
Object Oriented programming, Characteristics, Advantages of object
Oriented programming
over procedural language.
INTRODUCTION TO C++, EXTENSION OF C
Data types, constants, references, Variable, Loops and decisions
Arrays, strings and Structures Revision
Classes and objects
INTRODUCTION TO C++ CLASSES:
Data Members, Functions, Scope resolution operator,
Access specifier
New, delete operator, Static members.
CONSTRUCTOR and DESTRUCTOR
Encapsulation, Inline functions, and default parameters
Pointers and ‘This’ pointer
OVERLOADING:
Function Overloading, Operator Overloading
Default Arguments
INHERITANCE:
Base class, derived class, Virtual Class, Abstract class.
POLYMORPHISM
Virtual functions, Pure Virtual functions and abstraction
Function Overloading and ambiguities
All remaining types of functions
STREAM CLASS, FILE INPUT/OUTPUT.
FStream classes, working with files with functions for reading and writing
EXCEPTION HANDLING.
Fundamental, Multiple catch statements, catching all exception
Templates concept
Revision and completion of all theory and practical assignments
Reference Books
1. Complete Reference C++
1.0 OBJECTIVES
Friends,
This chapter gives a brief introduction about the history and evaluation of C++
as an Object Oriented language, and its various features in detail. After reading this
lesson you will be able to
• describe programming background
• state structured programming
• state object oriented programming
• describe characteristics of object oriented programming
• state advantages of object oriented programming
1.1 INTRODUCTION
Object oriented languages are playing an increasingly important role in computer
industry. With the gradual decline in the hardware costs, the cost of computing systems
is largely dominated by software. Developments in software technology continue to be
dynamic. New tools and techniques are announced in quick succession. This has
forced software engineers and industry to continuously look for new approaches to
software design and development. As a result, the relative cost of software (both
development and maintenance) is increased substantially. These developments created
a situation of crises in the industry. To overcome the software crises is the Object
oriented paradigm.
• There were no facilities to reuse existing code. Wherever the same piece
code was required, it was simply duplicated.
• The control was transferred via go to statement. As a result, there was too
much jumping around in the program, often without any clear indication of
how, where and why the control is flowing.
• Writing, understanding and maintaining long programs became very difficult.
Programmers needed a new way of using high-level language as, one that
enabled them to partition their programming into logical section that represent general
task to be completed. Thus the structured programming paradigm was born.
C++ / 2
when changes occur in data types, modifications must be made at every
location that acts on those data types within the program. This is a time
consuming task for large sized programs.
• Another drawback is that it does not model real world problems very well.
Today the need for efficient programming methods is more important than ever.
The size of average computer program has grown dramatically and now consists of
thousands of code lines. With these huge programs reusability is critical. Again a better
way of programming is needed and that better way is object oriented programming.
The data of an object can be accessed only by the functions associated with
that object. However functions of one object can access the functions of other objects.
Some of the features of object-oriented programming are: -
• Emphasis on data rather than procedure.
• Programs are divided into what are known as objects.
• Functions that operate on the data of an object are tide together in the
data structure.
• Data is hidden and cannot be accessed by external functions.
• Objects may communicate with each other through functions.
• New data and functions can be easily added whenever necessary.
• Follows bottom-up approach in program design.
C++ / 4
Will create an object mango belonging to class the fruit.
Polymorphism: -
By using polymorphism you can create new objects that perform the same
functions as the base object but which perform one or more of these functions in
different way. For e.g. you may have a shape object that draws a circle. By using
polymorphism you can create a shape object that draws a rectangle instead. You do
this by creating a new version of methods that draws shape. Both the old circle drawing
and the new rectangle drawing method have the same name but accomplish the
drawing in different way.
Fig 1.4 illustrates that a single function name can be used to handle different
number and different types of arguments.
1.7 SUMMARY
In this chapter we have studied evaluation of C++ as an object oriented
programming language.
Developments in software technology are increasing dynamically. New tools and
techniques are announced in quick succession. These developments created a situation
of crises in the industry. To overcome the software crises is the Object oriented
paradigm.
In the earlier edges of computers, computer programs were written in binary. As
the need for more sophisticated programs grew so did the need for better ways to write
these programs. The flow was machine language, assembly language, procedure-
oriented language and object oriented language.
Then we studied what procedure oriented language. In procedure oriented
programming emphasis is on algorithms. Disadvantages of procedure oriented language.
Object oriented programming is designed around the data being operated upon
rather than upon the operations themselves. The sole purpose of the program is to
manipulate data. Advantages of object oriented programming.
At the end, characteristics of object oriented programming and advantages of
object-oriented analysis. Characteristics of object-oriented programming are objects,
classes, data abstraction, encapsulation, inheritance and polymorphism.
Source : http://www.wiziq.com(link)
C++ / 6
1.8 CHECK YOUR PROGRESS- ANSWERS
1.3 & 1.4 1. True
2. True
3. False
4. True
1.5 1. Data & code
2. Classes
3. Inheritance
4. Polymorphism
C++ / 8
CHAPTER 2
2.0 OBJECTIVES
In this chapter gives a brief introduction about the history and evaluation of C++ as an
object oriented language. After studying this chapter you will be able to
desirable evaluation of C++
state difference between C and C++
define fundamental data types
state operators
state programming constructs
2.1 INTRODUCTION
C++ is an extension of c with a major addition of the class construct feature of
simule 67, so it was initially named as ‘C with classes ’. Many new keywords have been
added has been explain. In this chapter how C++ program is written has been explain
then identifiers count & cin are predefined objects that represent the standard output /
input stream in c++. The ‘// ’ (double slash) symbol is used for single line comment.
Data type in c++ are classified under various categories fundamentals and user
defined.
C++ / 10
{
float r;
cout << “Program to calculate area of circle...\n”;
cout<< “specify the radius:”;
cin >>r;
cout << “Area of circle:”<< 3.1415926 * r * r; }
Variables
Variables are fundamental to any language. Values can be assigned to variables,
which can be changed during program execution. The value assigned to a variable is
placed in the memory allocated to that variable. Variables can be created using key
word float, int, and char.
Declaration of variables
The declarations of variables in the C language are allowed only in the beginning
of their block, prior to executable program statements. In C++, declarations of variables
can be interspersed with executable program statements. Variables can be declared
anywhere in the program or function as and when required. The scope of the variables,
however, remains the same- the block in which they are declared.
e.g.
# include<stdio.h>
int main (void) {
int X=10;
printf(“the value of X = % d\n”, X);
int Y = 0 ; // another variables can be declared here .
//this variable Y can be used anywhere
// after but not before this.
for(int Z = 0 ; Z< 10 ; Z++) // variable Z declared here
{.
printf(“\nz = %d”, Z) ;
Z++ ; // variable Z can be used here.
}
X++;
Y--;
}
Although, a deviation from the old style of declaring all variables in the beginning
of the block, this does save some amount of memory, i.e. a variable is not given
memory until the declaration statement. Also, since a variable can be declared just
before using, it is suppose to give a better control over variables.
2.6 OPERATORS
A variable, when declared of a particular type is a set of legal operations that can
be performed on it. For example, when integers are declared, operations such add,
subtract, multiply and divide can be performed them. Operators perform those operations
on the variables.
Different types of operators available in C++ are: -
1. Arithmetic operators- are +, -, /, * and % operator. ‘%’ Operator divides the
second value from the first and return the remainder.
2. Relational operators – are >, >=, <, <=, ==, !=. These operators compare
two values and return the appropriate result.
3. Logical operators- are && and ||. This operator evaluates two expressions,
and evaluation stops as soon as the true or false value of result is known.
C++ / 12
4. Unary operators: - The unary operators operate on one operand – variable
or constant. C++ provides the two unary operators ++ and - for incrementing
and decrementing variables. The increment operator adds 1 to its operand
while decrement operator subtracts 1. The operators can also be used
either as prefix or postfix operators.
Manipulators
Manipulators are the operators that are used to format the data display. The
most commonly used endl and setw.
The endl manipulator used to insert a new line. It has the same effect as using
the newline character “\n”.
For example: we have 3 variables x, y, z and values of variables are 1250, 56,
265
If we write
Cout << “X =” << x << endl;
Cout << “Y =” << y << endl;
Cout << “Z =” << z << endl;
Output will be
X=1250
Y=56
Z=265
If we want output as
X= 1250
Y= 56
Z= 265
Here numbers are right justified. This form of output is possible only if we can
specify a common field width for all the numbers. The stew manipulator does this job.
It is used as follows.
cout << stew(5) << “X=” << x << endl;
cout << stew(5) << “Y=” << y << endl;
cout << stew(5) << “Z=” << z << endl;
Type casting
C++ permits explicit type conversion of variables or expressions using the type
cast operator. Two different types of typecasting syntax are supported in C++.
int a=999, b= 365, c;
c= (a+1) * b; // error since integer range is exceeded on manipulation
c= (a+1) * (long) j; // C style casting, also supported by C++
c= (a+1)* long (j); // C++ style typecasting
2.5 & 2.6 Check your progress
Q. 1 State true or false
1. In C++, variables can be declared anywhere in the program
2. Arithmetic operator operate on single operand
3. The setw manipulator used to insert a line
# include <iostream.h>
void main()
{
int a, b;
cout << “Enter values for a and b\n”;
cin >> a;
cin >> b;
if(a>b)
{
cout << “value of a is more than b\n “;
else
{
cout << “Value of b is more than a\n”;
}
}
}
2. Switch -- case statement: - This is a multi- branching statement. This statement
tests the value of an expression against the list of constants. When a match is
found, control is transferred to that constant for execution.
Example
# include <iostream.h>
void main()
{
}
The break statement: -The break statement causes exit from switch body.
Control goes to the first statement following the end of the switch construct. If the break
statement is not used the control passes to the statement for the next case, and the
remaining statements in the switch construct are executed.
The conditional operator: - The expression ? : operator is called conditional
operator and takes the form.
Exp1? Exp2: Exp3;
Looping constructs: -
Loop causes a section of your program to be repeated a certain no of times or
until a particular condition is satisfied. When a condition becomes false, loop ends and
the control is passed to the statements following the loop.
C++ / 14
1. While loop: - following program illustrates the use of while constructs.
// program to find sum of first 10 numbers
# include <iostream.h>
void main()
{
int n, sum,
n=1;
sum=0;
While(n<11)
{
sum=sum+n;
n= n+1;
}
cout << “Sum of first 10 numbers is “<< sum;
}
In the above program loop is repeated till the value of n becomes 11.
Output of the program
Sum of first 10 numbers is 100.
2. Do - while loop: - in the while loop test expression is evaluated at the
beginning of loop where, in case of do while loop, test expression is
evaluated at the end of loop. Following program illustrate this.
# include <iostrem.h>
void main()
{
int n, sqr;
char reply=’y’;
do
{
cout<< “Enter a no”;
cin>> n;
sqr=n *n;
cout<< “Square of a no is” <<sqr;
cout << “Do you want find square of another no (y/n)?”;
cin>> reply;
} while(reply!=’n’)
}
Sample output of program
Enter a no 5
Square of a no is 25
Do you want to find square of another no (y/n) n
On entering ‘n’ the test expression becomes false and loop gets terminate
3. For loop: - For loop allows us to specify three things about a loop in a
single line. Setting a loop counter to an initial value, testing the loop
counter to determine whether its value has reached the number of repetitions
desired, increasing the value of loop counter each time the program segment
within the loop has been executed.
# include <iostrem.h>
void main()
{
int n, sum;
sum=0;
for (n=1; n<11; n++)
{
sum=sum+n;
}
cout<< “Sum of 10 numbers is”<< sum;
}
2.8 SUMMARY
In this we studied an object-oriented language C++. C++ is an extension of C
with a major addition of the class construct feature of Simula 67, so it was initially
named as ‘C with classes’.
What is a difference between C and C++? Many new keywords have been added;
it also defines new operators new and delete to manage dynamic allocation functions
they can be used in places of malloc () and free ().
We learnt, how C++ program is written. Then identifiers, cout and cin are predefined
objects that represent the standard output/ input stream in C++. The ‘//’ (double slash)
symbol is used for single line comment.
Data types in C++ are classified under various categories- fundamentals and
C++ / 16
user-defined.
C++ allows us to declare variables anywhere in the program. C++ permits
explicit type conversion of variables or expressions using the type cast operator. Then
we learnt about the programming and looping constructs.
C++ also provides manipulators to format data display. The most commonly
used manipulators are endl and setw.
C++ / 18
CHAPTER 3
3.0 OBJECTIVES
In this chapter we will discuss about arrays and pointers.After studying this you
will be able to
• state Introduction to arrays
• describe Array manipulation
• state Pointers
3.1 INTRODUCTION
In this chapter we are discussing about arrays & pointers. An array is the collection
of the similar data types , which can be referred to by a single name with a number,
known as the index, to access a particular field or data
Pointers are addresses of memory location. Any variable, which contains an address
is a pointer variable
3.2 ARRAYS
In every day life similar objects are commonly grouped into units. We buy fruits
in dozes or tablets in strip or bottle instead of one at a time. Similarly, in computer
language we need to group data items of the same type. In C++ the mechanism that
enables this is the array.
An array can be defined as the collection of the similar data types, which can
be referred to by a single name along with a number, known as the index, to access
a particular field or data.
Arrays can be of string or integers. It can be one-dimensional or two-dimensional.
Following program illustrates how array is declared. The program accepts five
numbers and stores it in array
# include <iostream.h>
void main ()
{
int num[5],c;
cout<< “Enter 5 numbers”;
for(c=0;c<5;c++)
cin<< num[c];
}
for (c=0;c<5;c++)
cout << “Number:”<< num[c] <<“\n”;
}
}
An array is declared like other variables are declared in C++. Arrays must be
defined before they can be used.
3.2.3 Strings
In C++ a string is defined as a character array terminated by a NULL character.
A NULL character is represented as \0. You must declare character arrays to be one
character longer than the largest string they are to hold since the last byte holds the
string terminator.
For example if you wish to declare an array arr that will hold 5-character string,
the declaration should be
char arr[5];
Initializing String array
Direct initialization is possible in two ways:
char cStr[5]={‘l’,’ u’,’c’,’ k’’\O’};
char cStr[5]={“luck”};
In the first case, individual elements are moved into the array, and therefore it
is essential that the string terminator be specified explicitly.
In the second case, the string terminator gets attached automatically since the
string has been assigned.
C++ / 20
Following program illustrates this.
#include <iostream.h>
void main()
{
char cWeekdays[7][10];
int a;
//loop to enter weekdays
for(a=0;a<7;a++)
{
cout<<“enter weekday “<<a+1 << “day”<<endl;
cin>>cWeekdays[a];
}
//loop, to display weekdays one by one
for(a=0;a<7;a++)
cout<<“weekday “<<a+1<< “is”<< cWeekdays[a]<<endl;
}
}
3.3 POINTERS
The computer memory is a collection of storage cells. These locations are
numbered sequentially and are called addresses.
Pointers are addresses of memory location. Any variable, which contains an
address is a pointer variable.
Pointer variables store the address of an object, allowing for the indirect
manipulation of that object. They are used in creation and management of objects that
are dynamically created during program execution.
C++ / 22
char *cPtr ,cVar =’A’;
cPtr=cStr // both cPtr and cStr point to the same location
cout<<*cPtr<<endl;
cPtr=.&cVar//cPtr is now pointing to cvar
cout<<*cPtr
}
3. The unary operator ‘*’ is used to obtain the value of whatever the pointer is
pointing to.
3.4 SUMMARY
in this chapter we learnt about the concept of array and pointers. An array is the
collection of the similar data types, which can be referred to by a single name along
with a number, known as the index, to access a particular field or data. How an array
is declared and initialized.
How string array is declared in C++. In C++ a string is defined as a character
array terminated by a NULL character. A NULL character is represented as \0. What
is two-dimensional array? A two dimensional array is a grid containing rows and columns
where each element can be accessed by specifying the row and column coordinates.
Then we learnt about pointers. Pointers are addresses of memory location. Any
variable, which contains an address is a pointer variable. How pointer is declared and
initialized.
C++ / 24
CHAPTER 4
Functions
4.0 Objectives
4.1 Introduction
4.2 Function prototype
4.3 Function call by value, reference
4.4 Function overloading
4.5 Default arguments in functions
4.6 Inline function
4.7 Summary
4.8 Check your progress- Answers
4.9 Questions for Self-Study
4.10 Suggested Readings
4.0 OBJECTIVES
During this chapter you will learnt about:
• describe use and concept of function.
• describe function prototype.
• state function call by value, reference
• discuss function overloading.
• describe inline functions.
4.1 INTRODUCTION
Dividing a program into functions is one of the major principles of top-down,
structured programming. Another advantage of using functions is that it is possible to
reduce the size of a program by calling and using them at different places in the
program.
Every program must contain function, main() which is the starting point for the
program execution. The main() function may call another function, which in turn, may
again call still another functions. When a function is called control is transferred to the
first statement in the called function. The statement following the function call, or
expression being evaluated with the function. After function is executed, control returns
to the calling function, and execution continues with the evaluation of expression in
which the call is made. A value can be returned when a function completes the
specified task.
Functions / 25
Float volume (int x, float b)
Note that each argument variable must be declared independently inside the
parentheses.
Function definition: - contains the code for the function. It consist of type of
value it returns, its parameters and statements that are executed when function call is
made.
Example
# include <iostream.h>
void main()
{
cout<< “Calling display function\n”;
display();
}
void display ()
{
cout<< “Function is called”;
}
The function definition for display () is
void display ()
{
cout<< “Function is called”;
}
C++ / 26
4.3.2 Function call by reference
Call by reference is a method in which the address of each argument is passed
to the function. By this method, the changes made to the parameters of the function
will affect the variables in the calling function.
For example:
# include <iostream.h>
void main ()
{
int a=5, b=10;
void swap (int *, int *);
swap (&a ,&b);
cout << “\n a= “ << a<< “b =” << b;
}
void swap (int *a, int *b)
{
int c;
c= *a;
*a= *b;
*b= c;
}
b= square(a);
e= square(f);
m= square(l);
cout<< b << e << m;
Functions / 27
}
int square(int x)
{
return (x * x);
}
float square(float x)
{
return (x * x );
}
long square(long x)
{
return (x * x);
}
# include <iostream.h>
void main ()
{
float amount;
float value(float p, int n, float r=0.15);
void printline(char ch= “*”, int len=40);
C++ / 28
while(year<=n)
{
sum= sum* (1+r);
year=year+1;
}
return(sum);
}
Sample output
* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
Final value= 10056.8
=================================
The program defines function called value. A function takes 3 parameters; amount,
no of years, rate and return final value. Default value for the parameter (rate) is specified.
In the program we call the function by passing 2 parameters i.e. amount (5000.00) &
no of years (5). Like this, program defines another function called printline. Function
takes 2 parameters character and for how many times character to be printed. Default
values for both the parameters have mentioned. First we have called this function using
default arguments and then by passing value for 1st parameter.
Default arguments are useful in two cases.
1. We can use default arguments to add new parameters to the existing
functions.
2. Default arguments can be used to combine similar functions into one.
Functions / 29
to put the code in the function body directly inside the code in the calling program. That
means replacing the function call with the actual body of the function itself.
It is possible in C++ by declaring the function as inline. An inline function is
almost like a normal function. The only difference is that, while writing the heading for
the function, you have to write the word inline at the beginning. When you define a
function to be an inline function, what happens is that, whenever this function is called
from somewhere else in the program, the entire code for the function is actually
expanded at the place where the function is called.
All inline functions must be defined before they are called. The syntax for inline
function is as follows.
Inline function- header
{
function body
}
# include <iostream.h>
# include <math.h>
void main()
{
float a=1, b=4, c=9;
cout<< “Square root of a = “<< root(a) <<“\n”;
cout<< “Square root of b = “<< root(b) <<“\n”;
cout<< “Square root of c = “<< root(c) <<“\n”;
}
Above program has inline function root (). When we call root (a) compiler substitute
the code corresponding to the root () function. Look at the program we are calling this
function 3 times. The compiler is actually going to substitute the entire code for function
at all these places. This is almost like macro substitution.
With a # define we can define a macro. When we define a macro, the entire
macro is expanded at every place where it is referenced. Inline functions are very
similar to that. But of course you have to remember that inline functions are functions
and not macros.
After compiling the source program is going to be bigger in size because the
code for function to be duplicated in all places when it is called. But then, you will find
that there are situations where speed is more important than size of program, and inline
function do speed up the execution of program because they eliminate certain overheads
that are involved in calling functions.
Sample output:
Square root of a= 1
Square root of b= 2
Square root of c= 3
You should use inline function qualifier only when the function code is small.
Some of the situations where inline expression may not work are:
1. For function returning values; if a loop a switch or a goto exists.
C++ / 30
2. For functions not returning values; if a return statement exists.
3. If functions contain static variables.
4. If inline functions are recursive.
4.7 SUMMARY
In this chapter we have studied that apart from main () function we can have user
defined functions. Advantage of using functions is that it is possible to reduce the size
of a program by calling and using them at different places in the program.
We learnt about function prototype. A function prototype is a declaration that
defines both: the arguments passed to the function and the type of value returned by
the function.
The call to the function can be by value or reference. Functions in C++ have an
ability to define default values for arguments that are not passed when the function call
is made.
We studied a new feature called inline function. Inline function is a function that
is expanded at the place where the function is called.
Functions / 31
number from user to test the function.
Q.5 write a function that performs the same operation as that of Q.4 but takes a
number instead of character to be printed. Both the function should have the
same name. Write a main that calls both the functions. Use the concept of
function overloading.
Q.6 write an inline function that returns largest of 3 numbers. Test the function using
a main.
C++ / 32
NOTES
Functions / 33
NOTES
C++ / 34
CHAPTER 5
5.0 OBJECTIVES
Friends,
This chapter gives a brief introduction about the most important features of C++
- classes and objects. After studying this chapter you will be able to know
• Differentiate between structure and classes
• state Introduction to classes
• explain access specifiers
• Declaring classes
• Creating objects for class
• describe constructors
• describe destructors
• describe structure vs classes
5.1 INTRODUCTION
The most important feature of C++ is the class. A class is an extension of the
idea of structure used in c. It is a new way of creating and implementing a user defined
data type.
The fundamental idea behind an object-oriented language is to combine into a
single unit both data and the functions that operate on the data. Such a single unit is
called object.
A class is a way to bind the data and its associated functions together. When
defining a class we are creating a new abstract data type also called user-defined.
struct Student
{
int Rollno;
char Name[15j;
int Marks[6];
float percent;
void Getdetails();
void Putdetails();
int ClacPercent();
};
There are three functions in the template given above. These functions have been
incorporated in the structure definition to make it a fundamental unit. The building
together of data and the functions that operate on that data is called as data
encapsulation. But the problem is that the member variables of this structure can be
accessed by functions other than the ones declared in the structure template. This
direct access of member variables of a structure by functions outside the structure is
not what OOP has to offer. The actual OOP methodology in this regard is implemented
in C++ not by the structure data type, but by the data type class. The data type class
is just like structures, but with a difference. It also has some access specifier, which
controls the access to member variables of a class.
C++ / 36
Genera! form of class declaration is.
Class class-name
{
private:
variable declaration;
function declaration;
public:
variable declaration;
function declaration;
}.
The class declaration is similar to a structure declaration. The keyword class
specifies that what follows is an abstract data of type class-name. The body of class
is enclosed within braces and terminated by semicolon. The class body contains the
declaration of variables and functions. These functions and variables collectively called
class members. They are usually grouped under two sections, namely private and
public to denote which of the members are private and which of them are public.
C++ / 38
cout <<05
cout<<“circle x... \n”;
y.getradius ();
y showradius ();
y.showarea ();
cout<< cr;
}
Circle y ...
Enter the radius: 10
Radius = 10
Area = 314.15926
5.7 CONSTRUCTORS
A constructor is a special member function that is invoked automatically whenever
a class object is created. The name of the constructor function is exactly same as the
name of the class.
Characteristics of constructor function
1) The name of constructor function should be the same as the name of the
class.
2) Constructor function is automatically called whenever an object of that
class is created.
3) Constructor function does not have return type. It’s not even void.
4) If no constructors are declared then compiler invoked is own constructor.
5) They can not be inherited, though a derived class can call the base class
constructor.
6) Like other C++ functions, they can have default arguments.
A constructor declared and defined as follows.
# include <iostream.h>
class score
C++ / 40
{
int marks;
public:
score ();
int showmarks ();
};
score:: score ()
{
while(1)
{
cout<< “Enter marks:”;
cin>> marks:
if(marks>= 0 && marks <=100)
break;
cout<< “*** Invalid marks ***\n”;
}
}
int score:: showmarks ()
{
return (marks);
}
void main ()
{
score a,b,c;
cout<< “Percentage =”;
cout<< (a.showmarks () + b.showmarks() + c.showmarks())/3;
cout << ‘\n’,
}
The program defines a class called score. This class has 3 members marks, and
two member functions score () and showmarks ().
Score is a constructor function as it has the same name as the class. Constructor
function does not have a return type so; we have no? specified any type such as int,
float... for function. The score function invoked automatically whenever an object of the
score class is created. The function contains while loop, the loop terminates if valid
value is enter. If marks are not within the range it prints message “*** Invalid marks***”.
The showmarks () functions return marks. If any function wants to know the value
of variable marks for an object of the score class, it must call the
showmarks (). The marks is private member of class sore it is not accessible
to any other functions which are not the member of that class.
The main functions declares three objects a, b & c of score class. As soon as
the objects are created constructor function is automatically executed to accept the
values. Then program calculates percentage and display it.
The program defines class called employee. It has 2 members such as name
defined as array and salary. If also has 2 member functions. First member function is
C++ / 42
constructor which takes 2 parameters, first parameter is string. It is defined as pointer
to character and second parameter is number which is integer. Second member function
is defined to print name of employee and salary.
Constructor function is defined to copy the string of characters specified by the
first parameter into the array and number into variable called salary. Strcpy () function
is used to copy the string.
The program defines a class called date. Class date has three members called
day, month and year. It has 2 member functions. First member function is date, which
is a constructor function. Default values have been specified for all three parameters
which are accepted by constructor function. If somebody creates an object of class
date, by default, that is, if no values are passed to the constructor function, it will create
date using default values i.e. 1/1/99.
Main function starts creating 4 objects called d1, d2, d3 and d4 belonging to date
class. The object d1 passes 3 parameters where as d2 and d3 passes two and one
parameters respectively. In this case default values are set for omitted parameters. In
case of ,d4 object no parameters have been passed, so, constructor will assign date
using default values.
C++ / 44
cout <<“Value of f “;<<f.display();
return 0;
}
5.8 DESTRUCTOR
A destructor, as the name implies, is used to destroy the objects that have been
created by a constructor. Like a constructor, the destructor is a member function whose
name is the same as the class name but is preceded by a tilde (~).
A destructor may be called either when the object goes out of scope or when
it is destroyed explicitly using delete operator. A class cannot have more than one
destructor. And a destructor cannot take arguments or specify a return value.
Program, which illustrates how destructor is declared and used
Before writing this program you have to create 2 text files called text1.txt and
text2.txt:
# include <iostream,h>
class example
{
public:
example ()
{
cout<< “\nlnside the constructor”;
}
~example()
{
cout<< “\nlnside the destructor”;
};
void main ()
{
example e;
}
Another example of destructor
# inciude <iostream.h>
# include <stdio.h>
# include <string.h>
class textfiie
{
FILE *fptr;
char name [30];
public:
textfile (char * filename);
void printfile ();
~textfiie ();
};.
Classes and Objects / 45
textfile;:textfile (char *filename)
{
fptr = fopen (filename, “r’);
strcpy(name, filename);
}
void textfile:: printfile ()
{
char c;
cout << “\n File “ << name << “: \n\n”;
while (1)
{
c= getc(fptr);
if(c = = EOF)
break;
putchar(c);
}
}
void textfile:: ~textfiie ()
{
fclose (fptr);
cout << “File “ << name << “closed, \n “;
}
void main()
{
textfiie f 1 (“text1.txt”), f2(“text2.txf);
f1.printfile();
f2.printfile();
}
C++ / 46
5.7 & 5.8 Check your progress
Q.1 State True or False
1. Member functions of a class have to be called explicitly, whereas the
constructor gets called automatically.
__________________
2. Constructor cannot be overloaded.
__________________
3. A constructor never returns a value.
__________________
4. When an object goes out of scope its destructor gets called automatically.
__________________
5.10 SUMMARY
In this chapter we have studied the new data type called class.
Class is really like a new type that is defined by the user. It is almost like a
structure in a C program. How class is declared and used. The keyword class specifies
that what follows is an abstract data of type class-name. The class body contains the
declaration of variables and functions.
Then we learnt about the access specifiers. Access specifiers control the visibility
status of the members of *a class. The keywords private, public and protected are
access specifiers. Generally, in the definition of class, member variables are declared
as private and member functions are declared as public.
An object is an instance of class. We learnt how object for the class created.
We learnt about constructor and destructor. A constructor is a special member
function that is invoked automatically whenever a class object is created. The name of
the constructor function is exactly same as the name of the class. A destructor is used
to destroy the objects that have been created by a constructor.
Lastly we learnt how a class is defined using keyword struct in C++.
Source : http://www.crazylearner.com(Link)
C++ / 48
Q5 Create a class called sum that has a int member data for two numbers, a
constructor function to have sum of two numbers and a member function which
will display addition of two numbers. Write a program for this.
Q.6 WAP to add. co-ordinates of the plane. The class contains x and y co-ordinates.
Create three objects. Use a constructor to pass one pair of co- ordinates and
a function to accept the second pair. Add these variables of two objects and
store the result in the third.
C++ / 50
CHAPTER 6
Operator Overloading
6.0 Objectives
6.1 Introduction
6.2 Defining operator overloading
6.3 Overloading binary operator
6.4 Overloading unary operator
6.5 Operator overloading using friend function
6.6 Operator overloading to multiply matrices
6.7 Rules for operator overloading
6.8 Conversion functions
6.9 Summary
6.10 Check your Progress- Answers
6.11 Questions for Self - Study
6.12 Suggested Readings
6.0 OBJECTIVES
Friends,
In this chapter you will learn about operator overloading.
• define operator overloading
• describe overloading unary and binary operators
• describe operator overloading using friend function
• describe operator overloading to multiply matrices
• describe rules for operator overloading
• state conversion functions
6.1 INTRODUCTION
Operator overloading is one of the most interesting features of C++. C++ has the
ability to provide the operators with a special meaning for data type. By overloading
operators we can give addition meaning to operators like ints and floats etc.
We can overload all the C++ operators except the following:
1. We can overload .,::,? and :.
2. Size operator (size of).
We cannot change the precedence of operator. For example * operator always
has a higher priority over the + operator. When an operator is overloaded, its original
meaning is not lost. That means operator + which has been overloaded to add two
vectors, can still be used to add two integers.
Operator overloading is one form of Polymorphism, an important feature of
object-oriented programming. Polymorphism means one thing having many forms, i.e.
here an operator can be overloaded to perform different operations on different data
types on different contexts. Operator Overloading is also called operational polymorphism.
Operator Overloading / 51
{
function body
}
Where return type is the type of value returned by the specified operation and
op is the operator being overloaded.
Operator functions must be either member functions or friend functions. A basic
difference between them is that a friend function will have only one-argument foe unary
operators and two for binary operators, while a member function has no arguments for
unary operators and only one for binary operators. This is because object used to
invoke the member function is passed implicitly but in case of friend functions; arguments
may be passed either by value or by reference.
C++ / 52
}
void main()
{
time t1(7,30),t2(1,45) t3;
t3=t1 + t2;
t1.printtime();
t2.printtime();
t3.printtime();
}
The program defines a class called time. It contains two member variables called
hours and mins. The constructor function accepts two parameters denoted by hh and
mm and the values are stored in member variables called hours and mins. The default
value for both the parameters is 0. Before storing the values, it ensures that the value
stored in mins is less than 60 and value stored in hours is less than 24. If the values
of two parameters are 2 and 70 respectively, mins will be stored as 10, and hours will
be stored as 3. The constructor function is described within class definition itself. So
it is obviously an inline function.
The next member function in the time class is printtime (). It Is used to display
time.
The next member of the class is a function denoted as operator+. This is an
operator function; it overloads the +operator for the objects of the time class. Look at
the function; it says time operator+ (time rhs) means that the value returned by the
function is going to be of type time. The operator)- function will be automatically called
whenever we write an expression that uses a + operator after a time object. That means
when we write t1+ t2 operator+ function gets called. T1 is the object that invokes the
operator+ function, so it is automatically available to the operator function. Since we
wrote t1 + t2, t2 is passed as a parameter to the operator+ function, The parameter
received by the function is denoted as time rhs. This means that the parameter received
is also an object of the time class. T2 object passed to the operator+ function stored
in the rhs.
Look at the operator+ function. It has one variable called result, which will store
addition of two time objects. The next statement result.mins= mins + rhs.mins; here
mins is the value of the t1 object, which is automatically available to the operator+
function and rhs.mins is value of t2 object. Similar calculation is dione for hours parts
of the objects. Next three statements normalize the mins and hours parts of the result.
It ensures that the value stored in mins is less than 60 and value stored in hours is
less than 24.
Sample output
7:30 Hours
1:45 Hours
9:15 Hours
It is possible to simplify the description of the operator+ function used in the
above program. It can be written as:
time operator+ (time rhs)
{
time result(hours+ rhs.hours, mins+ rhs.mins);
return(result);
}
It creates a new time object called result, by passing hours+ rhe.hours and mins
+ rhs.mins as parameters to the constructor function. Normalization of hours and mins
not required, since the constructor function normalize the values while creating the
object.
Operator Overloading / 53
6.4 OVERLOADING UNARY OPERATORS
Unary operators are those operators that act on a single operand. Examples for
unary operators include’++’ and ‘--’ operators.
Following program illustrates how unary operator gets overloaded.
# include <iostream.h>
class distance
{
int feet;
float inch;
public:
distance(int f, float i);
void operator ++(void);
void display();
};
distance:: distance(int f, float f)
{
f= feet;
i= inch;
}
void distance:: display()
{
cout<< “Distance in feet” <<feet << endl;
cout<< “Distance in inch” << inch << endl;
}
void distance:: operator++(void)
{
feet++;
inch++;
}
void main()
{
distance dt(10,10);
++dt;
dt.display();
}
The program defines class distance, which has two members called feet and
inch and 3-member function. Class has a constructor function to assign values to feet
and inch. It also has operator function ++ and display function that display values.
Prefix and postfix:
The ++ operator, overloaded in the above program cannot be used as a postfix
operator. The compiler invokes the operator function with an int argument for the postfix
application of the operator. For example
int operator ++ (int)
The int argument here is a dummy argument, which is used only to distinguish
between the prefix and the postfix operators.
x++ is translated to x.operator++(0);
++x is translated to x.operator++(0);
C++ / 54
6.3 & 6.4 Check your progress
Q.1 Fill in the blanks
The program defines a class called circle. It has just two members, radius and
showarea(). The function void main() is a friend of the class circle. This means that the
function main () will have access to the private members of the class just like the
member functions.
Now look at the main function. It creates an object x to class circle. The next
statement assign the value 5 to the to the radius member of x. this would normally be
not allowed. That is because, radius is private member of x and it can be accessed
only by member functions or friend function. We have declared main function as friend
so it can have access to the radius. This is not really a good programming practice.
Operator Overloading / 55
But in exceptional situations, it might be necessary to allow some functions to have
access to the private members of a class objects.
Now we will see how operator overloading is done using friend function. Following
program illustrates this.
# include <iostream.h>
class time
{
int hours, mins;
public:
time(int hh=0, int mm=0)
{
mins= mm% 60;
hours= (hh+mm/60) % 24;
}
void printtime()
{
cout<< hours<<“:”<< mins<< “Hours\n”;
}
friend time operator+ (time Ihs, time rhs);
};
This program is almost the same as the first program. The only difference is in
the description of the class time, and the operator+ function. In the earlier program, the
operator+ function was defined to be member of the class. In this program the operator
function is defined to be a friend of the class. Now look at the function, it is written
as time operator+ (time Ihs, time rhs). It returns a time. Function takes two parameters
Ihs and rhs. Let us suppose there are two objects called t1 and t2 belonging to the
time class. When we write an expression such as t1+ t2 the operator function is
automatically invoked. T1 is passed as first parameter and t2 is passed as second
parameter.
Now we will see how the operator+ function works. It starts by defining result to
be an object of the time class. While creating the object result, the constructor function
is automatically called, so the parameters to be passed to the constructor function are
specified in the brackets written after the name of the object. The first parameter is
Ihs.hours + rhs.hours. The second parameter is Ihs.mins + rhs.mins. The constructor
function creates a time object called result with these values.
C++ / 56
6.5 Check your progress
Q.1 Fill in the blanks
1. ...........................function allowed to have access to the private members
of the class.
2. A ...........................function can be either global function or can be a member
function of another class.
class matrix
{
int rows, cols;
float *ptr;
public:
matrix (int rr, int cc, float *data)
{
int i.j;
float *p;
rows= rr;
cols= cc;
ptr = new float[rows * cols];
p=ptr;
for(i=0; i<rows; ++i)
{
for(j=0; j<cols;++j)
{
if (data= = NULL)
{
*P=0;
}
else
{
*p= *data;
++data;
}
++p;
}
}
}
~matrix()
{
delete ptr;
Operator Overloading / 57
}
void setval(int i, int j, float value)
{
*(ptr+i*cols+j) = value;
}
float getval(int I, int j)
{
return (*(ptr+i*cols+j));
}
void print()
{
int i, j;
float *p;
char output[11];
p=ptr;
for(i=0; i<row;++i)
{
for(i=0; j<cols;+=j)
{
sprintf(output, “%10.2f”, *p);
cout<< output;
++p;
}
cout<< ‘\n’;
}
cout<<‘\n’;
friend matrix operator*(matrix mat1, matrix mat2);
};
matrix operator* (matrix mat1, matrix mat2)
{
matrix result (mat1.rows, mat2.cols,NULL);
int i.j.k;
float prod;
if(mat1.cols != mat2.rows) return(result);
for(l=0; l<result.rows; l++)
{
for(j=0; j<result.cois;j++)
{
for(k=0; k<mat1.cols,++k)
{
prod= mat1 .getval(i,k)* mat1 .getval(k.j)
result. setval(i, j, result. getval(i,j)+ prod);
}
}
}
return (result);
}
void main()
C++ / 58
{
static float data1[] ={1,2, 3, 4,5,6};
static float data2[] ={1, 2, 3, 4, 5, 6, 7, 8};
matrix m1(3, 2, data1), m2(2, 4, data2);
cout<< “Matrix t:\n\n’”
m1.print();.
cout<< “Matrix 2 : \n\n”’ m2.print();
cout<< “Product Matrix : \n\n’” (m1*m2).print();
}
The program defines a class called matrix to store matrices of any size. The
class has three member variables- rows, cols and ptr. Rows and cols denote no. of
rows and columns that are there in the matrix object. Ptr is a pointer to the floating-
point data values, which form the elements of the matrix. The constructor function
creates the matrix object by allocating required memory for storing the data in the
matrix.
The constructor function starts by coping the first two parameters rr and cc to
the member variables rows and cols. The next statement uses the new operator to
allocate memory for storing rows* cols floating point numbers and store the pointer to
the newly allocated memory in the member variable ptr. The next statement stores the
same pointer in a local variable called p. The constructor function now has two for loops
that copy the data pointed to by data to the newly allocated memory, pointed to by
p. inner for loop checks to see if data is null; if the third parameter to the constructor
specified as null. In that case, the newly allocated memory for the matrix is initialized
to 0.
The class also has a destructor function ~matrix (), which deallocate memory
that was allocated by the new operator. The class also has 3 other member functions
called setval (), getval () and print (). Setval () function can be used to set the value
of a particular element of the matrix object. Getval () can be used to get the value of
a particular element. Print () is used to print entire matrix, in the print function sprintf
() function is used to convert the floating-point value of the element into %10.2f format.
The converted value is not printed directly; it is stored by the sprintf() in the array called
output. The string stored in output is then printed using cout.
There is a friend function called operator * () that is used to overload the *
operator for the objects of the matrix class. The overload operator * () function takes
two matrix objects denoted by mat1 and mat2 as the parameters. The purpose of the
function is to multiply two matrices and return the resulting matrix. When you multiply
two matrices of size a*b and b*c the resulting matrix is of size a*c. Our function needs
a temporary matrix for storing the product of mat1 and mat2; so it starts by creating
a matrix object called result having mat1. rows and mat2.cols. Since null is specified
as the third parameter while creating result, all the elements of result are initialized to
0. Function starts by checking whether the number of columns in the first matrix
matches the number of rows in the second matrix. If it doesn’t the function simply
returns result without doing anything further.
If mat1.cols matches mat2.rows, the function proceeds. Three nested loops are
used for multiplication. The first two for loops assign all the possible values to i and
j corresponding to the rows and columns of the resulting matrix. For each combination
of values of I and j, the innermost for loop adds to result [i][j], the products of all the
elements of the ith row of mat1 with corresponding elements jth column of mat2. When
the execution of the innermost for loop is completed, result [i][j] contains the correct
value for the element in the ith row .and jth column of result matrix. Two outer loops
execute the innermost loop for every combination of values of j, thus defining the entire
result matrix and I. The last statement in the function returns the calculated result
matrix.
Operator Overloading / 59
6.7 RULES FOR OVERLOADING AN OPERATOR
This summarizes the most important points you need to know in order to do
operator function overloading.
• The only operators you may overload are the ones from the C++ list and
not all of those are available. You cannot arbitrarily choose a new symbol
(such as @) and attempt to “overload it.
• Start by declaring a function in the normal function fashion, but for the
function name use the expression:
Operator op
Where op is the operator to be overloaded. You may leave one or more spaces
before op
• The pre-defined precedence rules cannot be changed. i.e. you cannot, for
example, make binary V have higher precedence than binary ‘*’. In addition,
you cannot change the associativity of the operators.
• The operators that can not be overloaded are:
. direct member
* direct pointer to member
:: scope resolution
?: ternary
• No default arguments are allowed in overloaded operator functions.
• Friend functions can not be used to overload certain operators like =,(), [
] and ->.
• Unary operators overloaded by means of a member function take no explicit
argument.
• Binary operators overloaded through a member function take one explicit
argument and those that are overloaded through a friend function take two
arguments.
• Binary operators such as +, -, * and / must explicitly return a value.
Consider an example, which depicts overloading of += (Compound assignment),
<, >, = (Equality),!=, + (Concatenation) using String class.
# inc!ude<iostream.h>
class String
{
public :
String ();
String ( char str []);
void putstr();
String operator + (String);
String operator += (String s2);
int operator < (String s2);
int operator > (String s2);
int operator == (String s2);
int operator != (String s2);
private:
char s[100];
};
String::String () // CONSTRUCTOR WITH
{ // NO ARGUMENTS
s[0] = 0;
C++ / 60
};
s3 = s1 + s2;
Operator Overloading / 61
cout << endl <<“ s3 =”;
s3.putstr();
String s4;
cout <<endl<<“ *********************”;
s4 = s1 + = s2;
String s5 =” Azzzz”;
String s6 =” Apple “;
if( s5 < s6 )
{
s5.putstr();
cout <<“= “;
s6.putstr();
}
else if( s5 > s6 )
{
s5.putstr();
cout «” >”;
s6.putstr();
}
else if( s5 == s6 )
{
s5.putstr();
cout <<“ =”;
s6.putstr();
}
else if( s5 != s6 ?ý
{
s5.putstr();
cout <<“ < “;
s6.putstr();
}
}
Output:
S1 = welcome
S2 = to the world of C++
S3 = welcome to the world of C++
**************************
S4 = welcome to the world of C++
void display(void)
{
cout << “ Feet = “ <<feet <<“,”;
cout << “ Inches =” << inches << endl;
};
private :
int feet;
float inches;
};
Operator Overloading / 63
cout << “ 1.25 metres is :” « d1 .showdist();
cout << “ 2.0 metres is :” « d2.showdist();
}
Output:
1.25 metres is :FEET = 4 , INCHES = 1.199999
2.0 metres is :FEET = 6 , INCHES = 6.719999
The above program converts distance in metres ( basic data type) into feet and
inches ( members of an object of class Distance ).
The declaration of first object d1 uses the second constructor and conversion
takes place. However, when the statement encountered is d2 = 2.0;
The compiler first checks for an operator function for the assignment operator.
If the assignment operator is not overloaded, then it uses the constructor to do the
conversion.
Conversion from User-Defined to Basic data type
The following program uses the program in the previous section to convert the
Distance into metres(float).
class Distance
{
Public :
Distance(void) // Constructor with no
{ // argument
feet = 0
Inches = 0.0
};
Distance(float metres)
{
float f; // Constructor with
f = 3.28 * metres; // one argument
feet = int(f); // Also used for
inches = 12 * (f - feet); //conversion
};
operator float(void) // Conversion function
{ // from Distance to float
float f;
f=inches/12;
f = f + float (feet);
return (f/3.28 );
};
void display(void)
{
cout<<“ Feet =” <<feet <<“,”;
cout << “ Inches =” << inches << endl;
};
private:
int feet;
float inches;
C++ / 64
};
Output:
1.25 metres is :FEET = 4, INCHES = 1.199999
2.0 metres is :FEET = 6 INCHES = 6.719999
Operator Overloading / 65
{
public :
DistFeet(void) // Constructor with no
{ // argument
feet = 0;
Inches = 0.0
}
DistFeet(int ft,float in)
{
feet = ft;
inches = in
};
void ShowFeet(void)
{
cout<<“ Feet = “ <<feet<<“,”;
cout << “ Inches =” << inches << endl;
};
private:
int feet;
float inches;
};
class DistMetres
{
public:
DistMetres(void)
{
metres = 0 ; // constructor 1.
}
DistMetres(float m)
{
metres = m ; // constructor 2.
}
void ShowMetres(void)
{
cout << “ Metres = “ << metres << endl;
};
operator DistFeet(void) // conversion
{ // function
float ffeet, inches;
int ifeet;
ffeet = 3.28 * metres;
ifeet = int (ffeet);
inches = 12 * (ffeet - ifeet);
return(DistFeet(inches,ifeet);
};
private:
float metres;
};
C++ / 66
void main (void)
{
DistMetres dm1 =1.0;
DistFeet df1;
df1 = dm1 ; // OR df1 = DistFeet(dm1);
// Uses conversion function
dm1.ShowMetres();
df 1 .ShowFeet();
}
Operator Overloading / 67
};
DistFeet(int ft.float in)
{
feet = ft;
inches = in;
};
void ShowFeet(void)
{
cout <<“ Feet =” <<feet << endl;
cout <<“ Inches =” << inches << endl;
};
DistFeet( DistMetres dm) // Constructor 3
{
float ffeet;
This program works same as previous function. Here constructor is written in the
destination class. Also, we can see a new function GetMetres(). The function returns
the data member metres of the invoking object. The function is required because the
constructor is defined in the DistFeet class and since metres is a private member of
the DistMetres class, it cannot be accessed directly in the constructor function in the
DistFeet class.
Since you can use any of the above methods, it is strictly a matter of choice
which method you choose to implement.
C++ / 68
6.8 Check your progress
Q.1 State true or false
1. To carry out conversion from an object to a basic type or vice versa it is
necessary to provide the conversion function.
_____________________
2. To carry out conversion from object of one type to another it is necessary
to provide the conversion function.
_____________________
6.9 SUMMARY
In this chapter you learnt about the one of the most interesting features of C++
i.e. operator overloading. C++ has the ability to provide the operators with a special
meaning for data type. By overloading operators we can give addition meaning to
operators like ints and floats etc.
Operator overloading is one form of Polymorphism, an important feature of object-
oriented programming. Polymorphism means one thing having many forms. Then we
saw how unary and binary operators get overloaded.
Then we saw what is a friend function Friend functions are themselves not
members of the class. In other words, they don’t belong to the class. They are some
outside functions, which will be allowed to have access to the private members of the
class. How friend function is used in operator overloading.
We learnt about the conversion functions. Conversion functions are’ member
functions used for the following purposes: Conversion of object to basic data type,
Conversion of basic data type to object, Conversion of objects of different classes.
6.5
Q.1 1. Friend function
2. Friend
6.8
Q.1 1. True
2. False
Operator Overloading / 69
Q.2 What are the general rules of operator overloading?
Q.3 What is a conversion function?
Q.4 We have two classes x and y. if a is an object of x and b is an object of y and
we want to say a = b; what type of conversion routines should be used and
where?
Q.5 WAP to add, subtract and multiply 2 matrices using OOT.Sort an array of
objects. Each object has a string as a member variable. Overload >= or <=
operators to compare the two strings.
{ make use of constructors and destructors whenever possible }
Q.6 WAP to create a class called DATE . Accept 2 valid dates in the form of dd/
mm/yyyy. Implement the following by overloading the operators - and +. Display
the result after every operation.
a. no_of_dasy = d1 - d2, where d1 and d2 are DATE objects;
d1 > - d2 ; and no_of_days is an integer.
b. d1 = d1 + no_of_days - where d1 is a DATE object and no_of_days is an
integer.
C++ / 70
NOTES
Operator Overloading / 71
NOTES
C++ / 72
CHAPTER 7
7.0 OBJECTIVES
Friends,
In this chapter we will discuss about how dynamic allocation and de-allocation
of memory is done in C++ and various C++ Concepts. After studying this chapter you
will be able to
• describe new and delete operator
• discusses passing and returning objects
• state pointers to objects
• state this pointer
• describe array of objects
7.1 INTRODUCTION
In this chapter we learning various c++ concepts how dynamic allocation & de-
allocation of memory done in c++. An object can be created by using new , and
destroyed by using delete as and when required then we learnt about the this pointer
array of objects. The keyword ‘this’ is used to denote the pointer to the object that
invokes a member function of its class.
Objects can be passed to a function and returned back just like normal variables.
Object can also be passed by address.
e.g.
char arr[100];// Compile_time allocation of an array
char*arr; //Character pointer
More of C++ classes / 73
arr = new char[size]; //Run time allocation of an
//array. Size can be a
//constant or a variable,
In the above example, new returns a pointer to a block of size bytes. It is
synonymous with declaring a character array. However, declaring an array is an example
of static binding - the array is built at the compile-time. This array remains in existence
right from the beginning of the program to its end, even if not in use. Whereas, the array
declared by new operator can be allocated memory only when required and can be
released when over with, using the delete operator. This is an example of dynamic
binding.
It is possible that the system may not have enough memory available to satisfy
a request by the new operator. In this case, new returns a null pointer. Thus, the
returned value from the new should always be checked before performing any operations
on it, which otherwise may lead to an adverent system crashes.
Delete operator
This operator is used to free the block of memory allocated by the new operator.
The format of this operator is
Delete pointervariable;
C++ / 74
:
:
flag = GM.Compare(RM);
}
int Employee::Compare(Employee emp2)
{
return(strcmp(Name, emp2.Name));
}
Compare() function in the above example makes a reference to the data member
Name of two objects. One is passed to it as a parameter - RM, which requires the
name of the formal object - emp2, as a qualifier. And the other -GM, which is used to
invoke the function.
Sachin.getstats();
More of C++ classes / 75
Sachin.showstats();
player *Dravid;
Dravid->getstats();
Dravid->showstats();
}
class date
{
int day, month, year;
public:
date (int dd, int mm, int yy)
{
day = dd;
month= mm;
year = yy;
}
void showdate ()
{
cout << day << “/” << month << “/” << year<< “\n”;
}
date operator++()
{
++day;
if (day > days[month])
C++ / 76
{
day=1;
++month;
}
if (month > 12)
{
month =1 ;
year++;
}
return *this;
}
};
void main()
{
date today(24, 4, 95);
cout << “Today’s date:”;
today.showdate ();
The purpose of the program is to show you how the key word called this is used.
The program defines class called date to implement date arithmetic. It overloads the
++ operator to increment date objects. In order to carry out this operation, it uses a
global array called days that contains the information about the number of days per
month in the year.
Program defines a class called date for storing dates. A date consists of 3
members’ day, month and year. It also has member functions for manipulating date
objects. The first member function is a constructor which, accepts 3 parameters and
stores their values in the member variables day, month and year. The showdate ()
function is to display date.
The next member function overloads the ++ operator for the date class. The word
date, written before the name of the function, indicates that this function returns a date.
Name of function is written as operator++. But, of course to call the function, you just
have to use the ++ operator. The purpose of the function is to increment the date. In
order to that the function first increments the day number part of the date. However we
must ensures that the day number does not exceed the total number of days in the
month. If statement is used to check this. The days array is used to get the values
of the number of days in the month. When date is incremented the operator++ ()
function must return date. But there is no variable that refers to the date, we can refer
to the parts of the date as day, month and year. But there is no single variable that
denotes the full date object. The date object that invokes this operator++ () function is
implicitly passed to the function. It is not explicitly available. However, we can refer to
this object by writing *this.
This is a reserved keyword that denotes the pointer to the object that is invoking
C++ / 78
The main function defines a two-dimensional array called names that contains the
names of 5 stations. The next statement x[5]defines an array called x having 5 elements
of type station. That means this is an ‘array of objects belonging to the class station.
Each elements of this array is an object; thus this is an array of objects.
Look at the for loop it assigns the values 0,1,2,3,4 to the variable a. For each variable
of a, it calls the setstation function for the object x[0]. Thus when a is 0, it calls the
setstation function for the object x[0]. For this value of a, the statement inside the for
loop becomes x[0]. Setstation (name[0], distance[0]).Thus the setstation function is
called for x[0] and the value of name[0] and distance[0] is supplied to it. The setstation
function stores the value stores the value of name[0] and distance[0], that is “cst” and
0 respectively in the member variable x[0]. Name and x[0]. Distance. Similarly procedure
is carried out for all values of a.
Now main function proceeds to calculate the distance between all the pairs of stations.
To calculate distance from station 1 to station 4 two for loops are required. The
procedure contained inside the second for loop is executed for every combination of
values of a and j. The statement cout << abs (x[a].getdistance ()-x[j].getdistance ())
calculates and prints the distance between the station[a] and station[j]. abs()function
is used in order to get the magnitude of the difference between distance of x[a] and
distance of x[j]. thus how the for loop works.
7.7 SUMMARY
In this chapter we learnt various C++ concepts. How dynamic allocation and de-
allocation of memory done in C++.
We learnt about the new and delete operator. Delete operator is used to free the block
of memory allocated by the new operator.
Then we learnt about the ‘ this’ pointer, array of objects. The keyword “this” is used
to denote the pointer to the object that invokes a member function of its class.
Objects can be passed to a function and returned back just like normal variables.
Objects can also be passed by address.
C++ / 80
CHAPTER 8
Inheritance
8.0 Objectives
8.1 Inheritance
8.2 Defining derived classes
8.3 Protected members
8.4 Multilevel inheritance
8.5 Multiple inheritances
8.6 Hybrid inheritance
8.7 Virtual base class
8.8 Constructor and destructor in with derived classes
8.9 Summary
8.10 Check your Progress - Answers
8.11 Questions for Self - Study
8.12 Suggested Readings
8.0 OBJECTIVES
Friends,
After studying this chapter you will able to object oriented programming-
inheritance, as implemented by C++. You will also understand
• describe what is inheritance?
• state defining derived class
• explain protected members
• discuss multiple inheritance
• discuss multilevel inheritance
• state hierarchical inheritance
• describe hybrid inheritance
• explain virtual base class
8.1 INHERITANCE
Now we will see another important concept of C++ called inheritance. Inheritance
enables you to create a new class, called derived class, which is similar to a previously
defined class, called base class.
The derived class inherits all the properties of the base class but can add some
of its own properties.
A class can also inherit properties from more than one class. A derived class
with only one base class is called as single inheritance and one with several base
classes is called as multiple inheritance. The properties of one class may be inherited
by more than one class is known as hierarchical inheritance.
Following diagram illustrates different forms of inheritance.
One of the advantages of inheritance is that it permits code reusability. Reusability
is one of the features of C++. Once a base class is written and debugged, it can be
adapted to work in different situations. A programmer can use a class created by
another programmer without modifying it. He can derived other class from it to suit his
requirements. It saves time and money and increases program’s reliability.
Inheritance / 81
8.2 DEFINING DERIVED CLASSES
A derived class can be defined by specifying its relationship with the base class
in addition to its own details. The general form of defining a derived class is:
Class derived class name : visibility mode base class name
{
members of derived class
};
The colon indicates that the derived class name is derived from the base class
name. Visibility mode (access specifier) is optional, if present, may be private, public,
or protected. By default visibility mode is private.
Example:
Class abc
{
int a, b;
public:
void setdata();
};
class xyz: private abc
{
members of xyz // private derivation
};
class xyz: public abc
{
members of xyz //public derivation
};
class xyz: abc
{
members of xyz //private derivation by default.
};
When a derived class privately inherits a base class, public members of the base
class become private members of the derived class. That means the public members
C++ / 82
of the base class can only be accessed by the member functions of the derived class.
They are inaccessible to the objects of the derived class.
When a base class is publicly inherited. The derived class has only access to
the public members of the base class. It does not have access to the private members
of the base class.
Simple example, illustrates inheritance.
# include <iostream.h>
# include <string.h>
class employee
{
char name[30];
float salary;
public:
void set (char *s, float n);
void show ();
};
class officer: public employee
{
flaot hra;
public:
void sethra (float n);
void showhra ();
}
void empioyee::set (char *s, float n)
{
strcpy (name, s);
salary = n;
}
void employee:: show ()
{
cout<<“Name: “<<name<< “\n”;
cout<< “Salary: “<<salary << “\n”;
}
void officer:: sethra ()
{
hra=n;
}
void officer:: showhra()
{
cout<< “HRA: “<<hra << “\n”;
}
void main ()
{
officer a;
a.set (“Gandhi”, 12000);
a.sethra (2000);
a,show ();
Inheritance / 83
a.showhra ();
}
The program defines employee as base class. It has 2 members i.e. name an
array and salary as float variables. It also has 2 member function called set () and show
().
The program has officer as derived class. Officer class is publicly inherited. That
means officer class will only have access to the public members of the base class
(employee class). Thus, objects of the officer class will have access to the set () and
show () member functions of employee class. But the officer class does not have direct
access to the members, name and salary. In addition to this officer class have one
member called hra and 2-member functions sethra () and showhra ().
Officer class is derived from the employee class. That means, objects of officer
class will have all the characteristics of the employee class. Thus, objects of the officer
class will have name and salary. Name and salary to officer class is set through set
() function. And they also have set () and show () functions. In addition to this specifically
it also have hra and 2 member functions.
Look at the main () function. It defines an abject called a, that belongs to the
officer class. The statement a. set (“Gandhi”, 12000) calls set function of the employee
class.A is an object of the officer class but officer class inherits characteristics of the
employee class. So we can apply the set function to the object of the officer class.
Sample output of program
Name: Gandhi
Salary: 12000
HRA: 2000
C++ / 84
void set (char *s, float n);
void show ();
};
name and salary are the private members of the employee class. Look at the
officer class, which is derived from employee class.
Class officer; public employee
{
float hra;
public:
void sethra (float n);
void showhra ();
}
Officer class inherits all the public members of the employee class; but not the
private members, name and salary. Of course, an object of the officer class will have
name and salary but we can’t access them within the officer class. Functions defined
inside the officer class, don’t have access to the private members of the employee
class.
Protected members can be inherited. That means, if class have protected
members and if you derive class from this class, the derived class will have access
to the protected members.
The manner, in which protected and public members are inherited by a derived
class, depends on how the class is derived. There are two ways in which a class can
be derived from a base class.
1. class derived-class-name: public base-class-name
2. class derived-class-name: private base-class-name
In first case, all the protected and private members of the base class become
the protected and public member of the derived class.
In second case, we have used private access specifier. When we derived the
base class using the access specifier private, all the protected and public members of
the base class become the private member of the derived class.
Following program illustrates how protected members are inherited
# include <iostream.h>
# include <graphics.h>
# include <conio.h>
class Figure
{
protected:
int x, y;
public:
Figure ()
{
cout<<“X co-ordinate:”;
cin>> x;
cout <<“y co-ordinate:”;
cin>> y;
Inheritance / 85
}
};
class Line : public Figure
{
int dx, dy;
public:
Line ()
{
cout << “Displacement in x direction:”:
cin>> dx;
cout << “Displacement in y direction:”;
cin>> dy;
}
void draw ()
{
line (x, y, x+dx, y+dy); //this is a library function
}
};
class circle : public Figure
{
int r;
public:
Circle()
{
cout <<“Radius:”;
cin>> r;
}
void draw ()
{
circle (x, y, r);
}
};
void main ()
{
int gd, gm;
gd= DETECT;
l.draw ();
c.draw ();
C++ / 86
getch ();
closegraph ();
}
The purpose of the program is to draw some graphics objects such as line and
circle. Program starts by defining Figure class as base class. The figure class contains
the information that is common to all figures. All the variables of the Figure class have
been defined as protected. They won’t be accessible to functions that are not members
of the figure class. However, they can be inherited. That means the classes that are
derived from figure class will be able to use them., Figure class has a constructor
function to accept values for x and y.
Line class is derived from the figure class. While deriving the class, we have
specified the access as public. That means, all the protected and public members of
the figure class wilt become protected and public members of line class. So, the line
class will be able to use protected members x and y just as if they had been defined
inside the line class itself. Line class has two private members such as dx and dy. It
also has 2 member functions Line () and draw (). Draw () to draw a Sine and constructor
function Line () to accept values for dx and dy.
In general, when object of a derived class is created, the constructor function
for the base class is executed first, and then the constructor function for the derived
class is executed. But when an object of a derived class is destroyed, the destructor
function for the derived class is executed and then the destructor function for the base
class is executed. Notice that the order is reversed in case of destructor functions.
When we create an object of the Line class, first the constructor function of the
figure class is executed and then the constructor function of the line class gets
executed.
In any program where you want to use graphics, you have to initialize the
graphics system. This is done by calling the standard function called initgraph (). Now
look at the main () function, we have declare 2 integer variables called gd and gm. The
variable gd is used for storing a code number corresponding to the graphics device that
is used inside the computer. Gm is to be used to for storing a code number corresponding
to the graphics mode that we wish to use. These two variables are required, because
when we call the initgraph () function, we have to pass pointers to the graphics device
and graphics mode as parameters to the initgraph (). We have set value for gd as
DETECT. DETECT is a defined name. Its value is specified in graphics.h . When we
set gd to the value DETECT, and call the initgraph () function, it automatically detects
the type of graphics, and selects the graphics mode with the highest possible resolution.
The third parameter in initgraph.() is the path name for the graphics drivers. In other
words, it is the name of the directory in which the graphics driver files are stored.
Usually it is present in the path “c:\tc\bgi”. However it would be in different directory
you would be required to provide the appropriate path.
The next statement in main () function is l.draw () will call the member function
draw () of line class. The purpose of the draw () function is to draw a line from the point
specified by x and y, to other end points whose co-ordinates are x+ dx and y+ dy. This
is done by calling the line () function. Line function is a built-in function that available
in graphics.h. The line function () takes four parameters. The first two parameters are
the co-ordinates of the first point of the line; the last two parameters are the second
point of the line. In our program we have calculated second points as x +dx and y +dy.
Here we are using x and y variables of figure class, this become possible because they
are declared as protected members.
At the end we close graph calling closegraph () function
Inheritance / 87
8.4 MULTILEVEL INHERITANCE
When a class is derived from base class, which is again derived, by-some other
class is called multilevel inheritance. For example if class ‘A’ is a base class for derived
class ‘B’, and class ‘B’ is base class for class ‘C’ is called as multilevel inheritance.
Multilevel inheritance is declared as follows.
Class A
{
members of class; //base class Class A
};
class B public A
Class B
{
Class employee
{
protected :
char name [30];
int id;
public:
void getvalue(char *s, int i);
void showvalue ();
};
void employee:: getvalue(char *s, int i)
{
name- s;
id = i;
}
void employee:: showvalue ()
{
cout<< “Name of employee: “<<name << “\n”;
cout<<“Employee’s Id: “ << id << “\n”;
}
class salary: public employee
{
protected:
int basic, da, hra;
void getsal (int, int, int);
C++ / 88
};
void salary :: getsal (int b, int d, int r)
{
basic= b;
da= d;
hra=r;
}
class tax; public salary
{
int total;
public:
void showdetails ();
};
void tax;: showdetails()
{
showvalue();
total= basic+da+hra,
if(total) >60000)
cout<< “Employee has to pay tax\n”;
else
cout << “Employee need not pay tax\n”;
}
void main ()
{
clrscr();
tax emp1, emp2;
emp1.getvalue(“Seeta”,10);
emp1.getsal (15000, 5000, 5000);
emp 1.showdetails ();
cout<<“------------------------------------\n”;
emp2.getvalues(“Geeta”,12);
ernp2.getsal (55000, 5000,8000);
emp2.showdetails ();
getch();
}
In the above program tax class is derived from salary class, which is derived from
employee class. So tax class can also have access to employee class members.
Inheritance / 89
8.3 & 8.4 Check your progress
Q.1 Fill in the blanks
1. ...........................members are inherited by a derived class.
2. When a class is derived from base class, which is again derived, by some
other class is called................................................................
C++ / 90
}
viod c::display(void)
{
cout<< “M “ << m<<“\n”;
cout<< “N =” <<n<<“\n”;
cout<< “M+N = “<< m+n<<“\n”;
}
void main()
{
c d;
clrscr();
d.getval(10);
d.getnum(15);
d.display();
}
The class c in the above example is derived from two classes – a and b –
therefore the first line of its class definition contains the name of two classes, both
publicly inherited. The c class contain all the members of a and b in addition to its own
members.
class Aclass
{
public :
void put()
{
:
}
};
class Bclass
{
public :
void put()
{
:
}
};
Inheritance / 91
void main()
{
A objA;
B objB;
C objC;
objA.put(); // From Class A
objB.put(); // From class B
objC.put(); // AMBIGUOUS -RESULTS IN ERROR
}
The above example has a class C derived from two classes A and B. Both these
classes have a function with the same name - put(), which assume, the derived class
does not have. The class C inherits the put() function from both the classes. When a
call to this function is made using the object of the derived class, the compiler does
not know which class it is referring to. In this case, the scope resolution operator has
to be used to specify the correct object. Its usage is very simple. The statement giving
an error from the above example has to be replaced with the following:
objC.A::put();// for class A
objC.B::put();//for class B
class base
{
:
:
};
C++ / 92
:
};
Aclass and Bclass are two classes derived from the same base class. The class
derived has a common ancestor- class base. This is multiple inheritance with a common
base class. However, this subtlety of class inheritance is not all that simple. One
potential problem here is that both, Aclass and Bclass, are derived from base and
therefore both of them, contains a copy of the data members base class. The class
derived is derived from these two classes. That means it contains two copies of base
class members - one from Aclass and the other from Bclass. This gives rise to
ambiguity between the base data members. Another problem is that declaring an object
of class derived will invoke the base class constructor twice. The solution to this
problem is provided by virtual base classes.
Inheritance / 93
class B : virtual public A
{
…………
};
class C: virtual public A
{
…………
};
class D: public B, public C
{
…………
};
When class is declared virtual base class, C++ takes necessary care to see
that only one copy of that class is inherited, regardless of how many inheritance paths
exist between virtual base class and a derived base class.
Abstract class:
An abstract class is one that is not used to create objects. An abstract class
is designed only to act as a base class to be inherited by other classes
base::~base()
{
cout << “base destructor”;
}
int base::get__base_number()
{
return base_ number;
}
public :
derived(int b=0, int d =0): base(b),derived._number(d);
~ derived();
int get_derived_number();
private :
int derived _number;
};
derived::derived(int b=0, int d =0): base(b),derived_number(d)
{
cout<<“ derived constructor”;
}
derived::~ derived()
{
cout << “derived destructor”;
}
int derived::get_derived_number()
{
return derived_number;
}
void main()
{
derived d(1,2);
cout < “ d= “ <<d.get_base_number()<<“,”;
cout<< d.get_derived_nurnber();
}
Inheritance / 95
Output:
Base constructor
Derived constructor
D = 1,2
Derived destructor
Base destructor
As can be seen from the above example, the constructor for the base class is
invoked before invoking the constructor for the derived class. This is like building the
first story of the building before proceeding for the second. With destructors, it is the
other way round. Destructors for the derived class are invoked first, so that they can
clean up the mess done by the constructor of the derived class. Then the destructor
for the base class is called. It is like demolishing the top floor of a building before going
for the lower one. A destructor for the derived class is to be defined only if its constructor
allocates memory. Otherwise it can be just an empty function.
8.9 SUMMARY
In this chapter we learnt about one of the most important aspects of object
oriented programming- inheritance, as implemented by C++.
inheritance enables you to create a new class, called derived class, which is
similar to a previously defined class, called base class. The derived class inherits all
the properties of the base class but can add some of its own properties. How derived
class is defined.
Then we saw the different forms of the inheritance that are: single inheritance,
multiple inheritance, multilevel inheritance, and hybrid inheritance. A class can also
inherit properties from more than one class. A derived class with only one base class
is called as single inheritance and one with several base classes is called as multiple
inheritance. The properties of one class may be inherited by more than one class is
known as hierarchical inheritance.
Then we learnt about the protected members. The difference between private
members and protected members is that, private members are not inherited by a
derived class; but protected members are inherited by a derived class.
What are virtual base class and abstract class? In a virtual base class, only one
copy of the base class is inherited by subclasses. An abstract class is designed only
to act as a base class to be inherited by other classes.
C++ / 96
8.6 & 8.7
Q.1 1. Virtual base class
2. Abstract
Inheritance / 97
NOTES
C++ / 98
CHAPTER 9
Polymorphism
9.0 Objectives
9.1 Introduction
9.2 Virtual function
9.3 Pure virtual function
9.4 Limitations of virtual function
9.5 Virtual constructor and destructor
9.6 Summary
9.7 Check your Progress - Answers
9.8 Questions for Self - Study
9.9 Suggested Readings
9.0 OBJECTIVES
Friends,
After classes and inheritance, polymorphism is the third essential feature of an
object-oriented programming.This chapter will give you a brief introduction about,
• discuss what is virtual functions
• describe pure virtual function
• describe limitations of virtual functions
• describe virtual constructor and destructor
9.1 INTRODUCTION
Polymorphism allows one name to be used for different purposes. It refers to the
property by which objects belonging to different classes are able to respond to the
same message, but in different forms.
Overloading functions and operators are one kind of polymorphism. C++ supports
polymorphisms at compile time, as well as run time. In compiler time polymorphisms
compiler itself decides which version of a function is to be used. Run time polymorphism
means, the version of a function to be used in a particular situation is decided at the
time of executing the program. The complier does not decide which version is to be
used. It is only decided at run time.
In order to understand run time polymorphism, we have to know how pointers to
a base class and derived classes can be used.
Following program illustrates how pointers to a base class can be used as
pointers to the derived classes.
# include <iostream.h>
# include <string.h>
# class employee
{
public:
char name[30];
float salary;
};
class officer: public employee
{
public:
Polymorphism / 99
float hra;
};
class staff: public employee
{
public:
float bonus;
};
void main()
{
officer a;
staff b;
employee *p;
p=&a;
strcpy(p->name, “Gandhi”);
p->salary= 5000;
a.hra= 1500;
p= &b;
strcpy(p->name, “Patel”);
p->salary= 4000;
a.hra=1000;
p=&a;
cout << “Officer (a) :\n”;
cout << “Name- “<< p->name <<“\n”;
cout << “Salary- “ << p->salary << “\n”;
cout <<“Hra- “ << a.hra << “\n”;
cout<<“\n”;
p= &b;
cout << “staff (b) :\n”;
cout << “Name- “<< p->name <<“\n”;
cout << “Salary- “ << p->salary << “\n”;
cout<< “Bonus- “ << b.bonus << “\n”;
cout<<“\n”;
}
The program defines a base class called employee, which is used to derive two
other classes called officer and staff. Base class employee has two members called
name and salary for storing data. Two derived classes officer and staff have single
members called hra and bonus.
The main function starts creating an object called a, belonging to officer class,
and an object called b, belonging to staff class. Then it defines p to be a pointer to
employee. Although p is declared to be pointer to employee, it can, in fact be used
as pointer to objects of the officer or staff class also. That’s because, in C++ a pointer
to the base class can also be used as a pointer to the derived classes.
The statement p= &a stores the pointer to the object a, in the variable p. a is
an object of the officer class but officer class is derived from the employee class. So,
C++ / 100
pointer to a can be stored in p. the next statement uses the pointer to access the
name part of a. it says strcpy (p->name, “Gandhi”); -> operator is the structure pointer
member reference operator. P->name means, the name part of the object that p is
pointing to a (as p is pointing to a), strcpy function copies the string “Gandhi” to officer
as name part of object. Same with salary we have written it as p->salary= 5000. The
next statement a.hra=1500 notice that we haven’t said p->hra. In fact, we can’t say p-
>hra because, p is really a pointer to employee class, so although we are allowed to
use p as pointer the officer class, we can use it to access only those members of the
officer class that are inherited from the employee class. So, we can access name and
salary. But hra is not inherited from employee class, so we can’t use p to access hra.
We can refer hra by simply writing a.hra. After storing values to a and b, program
displays these values.
class Figure
{
protected:
int x, y;
public:
Figure ()
{
cout<<“X co-ordinate:”;
cin>> x;
cout<<“y co-ordinate:”;
cin>> y;
}
virtual void draw ()
{
cout << “Derived class has not defined its draw function. \n”;
}
}:
Polymorphism / 101
cout << “Displacement in x direction:”;
cin>> dx;
cout << “Displacement in y direction:”;
cin>> dy;
}
void draw ()
{
line (x, y, x+dx, y+dy); //this is a library function
}
};
Circle ()
{
cout <<“Radius:”;
cin».r;
}
void draw ()
{
circle (x, y, r);
}
};
void main ()
{
int gd, gm;
gd= DETECT;
Line I;
cout<< “Creating a circle object………..\n”;
Circle c;
Figure *p;
p= &l;
p->draw ();
p=&c;
p->draw ();
getch ();
C++ / 102
closegraph ();
}
In the above program we have defined Figure as base class and two derived
classes Line and Circle. All three classes have draw () function Now look at the main
function first we have defined Line object called I, and circle object called c. we have
declared p to be a pointer to Figure. It can also be used as a pointer to objects of the
derived classes, Line and Circle. Look at the statements
p= &I;
p->draw();
It stores the pointer to I in p. So, p now points to I. The next statement says
p->draw(). That means we want to call the draw function for the object that p is pointing
to. But p is pointing to I. Therefore, effectively, this calls the draw function for the object
I. But remember that p was declared as a pointer to Figure. We are using it to access
members of a Line object. In the last program we saw that pointer to base class can
be used to access only those members of the derived class, which are inherited from
the base class. So, if we have to access draw () function using the pointer p, draw ()
function must be inherited from the base class by the Line class. That means, first of
all, the base class must have a draw () function. That’s why we had a draw () function
in the base class. But really we can’t have a sort of universal draw () function in the
Figure class, which will be capable of drawing any graphics object such as lines and
circles. For instance the draw() function in the Figure class won’t be able to draw line
as-it knows only x and y coordinates for the first point of line. That is why it is
impossible to have universal draw function in the base class. That means, we must
have separate draw function in each derived class. But you can’t have draw function
in based class and derived class also, if their parameter list is identical. That is
because if you have draw function in both class (base and derived) the derived class
will have two draw function one defined by itself and one inherited, compiler won’t be
able to decide which function to be used at particular situation.
In short, we want to have draw function in both class but compiler will not allow
that. To overcome this difficulty, we have made the draw function in the base class
virtual. By making the draw function of the base class virtual, we ensure that if the
derived class has its own draw function then that will be used otherwise, it derived class
won’t have draw function then function from base class will be used. By making draw
function of the base class virtual; we are giving it second priority. So, p->draw () will
call draw function of Line class as p is pointing to i and I is an object of Line class.
The statement p= &c; p->draw () will call draw function of Circle class as p is
pointing to c and c is an object of Circle class.
Rest of the program we have already discussed in earlier chapter.
Polymorphism / 103
Pure virtual function is defined by writing the word virtual, followed by the type
of the function, followed by the name of the function, and the arguments that it take.
The =0 written at the end makes this a pure virtual function.
If the base class contains a pure virtual function, all the derived classes should
have an actual function with the same name, and the same type of arguments.
A class that contains a pure virtual function is an abstract class. An abstract
class can’t have objects. But classes derived from an abstract class can have objects.
Although you can’t have objects belonging to abstract class, you can have pointer to
the abstract class.
Following program illustrates the concept of pure virtual function
# include <iostream.h>
# include <graphics.h>
# include <conio:h>
class Figure
{
protected:
int x, y;
public:
Figure ()
{
cout<<“X co-ordinate:”;
cin>> x;
cout<<“y co-ordinate:”;
cin>> y;
}
virtual voiddraw () = 0;
};
Line()
{
cout << “Displacement in x direction:”;
cin>> dx;
cout << “Displacement in y direction:”;
cin>> dy;.
}
void draw ()
{
line (x, y, x+dx, y+dy); //this is a library function
}
};
C++ / 104
class circle : public Figure
{
int r;
public:
Circle ()
{
cout<<“Radius:”;
cin>> r;
}
void draw ()
{
circle (x, y, r);
}
};
void main ()
{
int gd, gm;
gd= DETECT;
Figure *p;
P=&l;
p->draw ();
p=&c;
p->draw ();
getch ();
closegraph ();
}
The program is almost the same as the previous program. Look. at the class
Figure, it defines virtual function called draw (). In the previous program, we saw why
it is necessary to have such a function in base class. We also have draw function in
derived classes. So, the draw function in base class actually has no use, and there
is no reason why we should describe the function. When you don’t want to describe
a virtual function, you have to simply write =0 at the end. This makes a virtual function
pure virtual function. Basically a Pure virtual function is a virtual function for which no
description is given. A class that contains a pure virtual function is known as an
abstract class. The Figure class in our program is abstract class as it contains pure
virtual function called draw.
Polymorphism / 105
The reason for calling this class an abstract class is that, the definition of the
class is not really complete. It contains one pure virtual function for which no description
is given. Therefore it won’t be possible to have objects of the Figure class. Of course,
we could derive classes based on the Figure class, and those classes can have object;
but the Figure class itself can’t have objects. That’s why we called this is an abstract
class.
9.6 SUMMARY
In this chapter we learnt about the third essential feature of an object-oriented
programming polymorphism. Polymorphism refers to the property by which objects
belonging to different classes are able to respond to the same message, but in different
forms.
Overloading functions and operators are one kind of polymorphism. C++ supports
polymorphisms at compile time, as well as run time.
Then we saw what is meant by virtual function. Virtual function is a function that
is declared as virtual in a base class and redefined in the derived class.
Pure virtual function is a virtual function for which no description is given. Pure
virtual function is defined by writing the word virtual, followed by the type of the function,
followed by the name of the function, and the arguments that it take.
C++ allows declaration of destructor as virtual but one can’t have a constructor
to be virtual.
C++ / 106
2. Virtual
Polymorphism / 107
NOTES
File Handling
10.0 Objectives
10.1 Introduction
10.2 Hierarchy of stream classes
10.3 Stream insertion/extraction
10.4 File input and output
10.5 Reading and writing text files
10.6 Detecting end of file
10.7 Binary input/ output
10.8 File pointers
10.9 Error handling
10.10 Summary
10.11 Check your Progress - Answers
10.12 Questions for Self - Study
10.13 Suggested Readings
10.0 OBJECTIVES
Friends,
This chapter deals with stream and binary manipulation of files. After studying
this chapter you will be able
• explain what is a stream,
• describe stream insertion/extraction class hierarchy
• state stream insertion/extraction
• state use stream classes for file input or output
• state use Text binary file input and output
• discuss read and write through the get() and put() -file pointers
• discuss randomly access of data files through seekg() seekp() tellg()
tellg() functions.
10.1 INTRODUCTION
You have come across cout and cin statements in C++, which are nothing but
Streams. A Stream is a sequence of characters (strings) some people refer to it as
channels also. When you start the execution of a C++ program, several streams are
opened automatically. They are: cin, cout, cerr, clog.
Streams are of two types
1. Output streams-, which allow to write or store characters (Insertion).
2. Input streams-, which allow to read or fetch characters (Extraction).
The input and output streams so far dealt with only the standard input and output
streams .The User -defined streams are in the form of files supported by specific
Classes in C++.
The file handling techniques of C++ support file manipulation in the form of
stream objects. The stream objects are predefined in the header file, iostrean.h that is
a part of the C++ language. There are no predefined objects for disk files. All classes
los
lstream ostream
Lostream
Fstream base
The ios class defines the basic formatting and error control capabilities The class
ios is a virtual base class for the istream (input stream) and ostream(output stream).
The iostream (input and output stream) is a class with multiple inheritance from both
istream and ostream. The definitions for these classes are in the header file fstream.h.
These classes are used for output to the screen (stdout) and input from the keyboard
(stdin).
void main()
{
ofstream out(“student”); // create stream object associated with
a file
char name[20];
int marks;
clrscr();
cout<<“Enter marks:”;
cin >>marks;
out<<marks<<“\n”;
out.close(); //close the file
getch();
}
In the above example an object called out of class ofstream is created and
associated with a file The file name is given within quotes and parenthesis and a new
file is created in the hard disk. The program accepts student name and marks and then
void main()
{
ifstream inf(“student”);
char name[20];
int marks;
clrscr();
inf.close();
getch();
}
The program opens the file student in the input mode. The input stream reads
the values into the variables. The values are displayed using the cout statement.
Note:
When a file is opened for writing only, a new file is created if there is no file of
that name. If a file by that name exists already, then it contents are deleted and the
file is presented as a new file.
Another program which creates a file and writes some values in it. Then open
the file and contents of file are displayed on screen.
#inc!ude<iostream.h>
#include<fstream.h>
#include<conio.h>
void main()
{
ofstream out(“items”); // create output stream char item[20];
int cost;
clrscr();
out<<“Cd-Rom”<<500<<endl;
out<<“Printer”<<3000<<endl;
out<<“Scanner”<< 4500<<endl;
out. close();
inf>>item >>cost;
cout<<item<< “ “<<cost<<“\n”;
inf>>item >>cost;
cout<<item <<“ “<<cost<<“\n”;
inf>>item >>cost;
cout<<item <<“ “<<cost<<“\n”;
inf.close();
getch();
}
void main()
{
of stream out;
out.open (“country”);
out<<“lndia\n”;
out<<“Australia\n”;
out<<“United states of America\n”;
out.close();
// Reading the file ifstream inf;
const int n= 80;
char line[n];
inf.open(“country”);
The above program first opens the file country for output. The values are stored
into the file using the output stream out. Then the file is opened in the input mode. We
have used the getline () function in the program. The function is used to read one line
at a time. The function is a member of istream. It reads characters until it encounters
the end of line character, ‘\n’, and places the resulting string in the buffer line supplied
as an argument. The maximum size of the buffer is given as the second argument. The
contents of the buffer are displayed after each line is read using cout. This goes till all
the lines have been read (end of file is encountered).
#include<fstream.h>
#include<string.h> // string.h is used for strlen function to use it
char cstr[]=”one fine day”;
void main()
{
ofstream ost(“fex.txt”);
int i;
for(i=0;i<strlen(cstr);i++)
{
ost.put(cstr[i]);
}
ost.put(‘\0’);
// note
The following program illustrates the use of the get () function for binary operation-
to read character by character from the file.
#include<fstream.h>
//note:string.h is not required in this case
void main()
{
char svtr;
ifstream ist(“fex.txt”); while(ist)
{ ist.get(svtr);
cout<<svtr<<endl;
}
}
In the above program ist stream checks for the value end-of -file (false) if not
(means if the value is true) then the program keeps reading in the variable svtr in the
while loop followed by a condition.
To read and write more than one characters the following function is used
get(char *str,int len,char delimit=’\n’) where get fetches characters from the input stream
into the array str and it stops fetching if the no of characters fetched reaches the length
len ,fetching also stops if the delimiter character is encountered as stated in the
defination/declaration.
The following program illustrates the use of the get() function
#inciude<fstream.h>
void main()
{ char svtr[10];
//does not extract string terminator
cin.get(svtr, 9);
cout<<svtr;
}
NOTE:
There is also a getline( ) function which also extracts the string terminator the
remaining parameter remains the same.
It is possible to input and output the numeric values by the read( ) and write (
) functions.
The read ( ) function has to be called with 2 arguments namely
- the address of the buffer into which the data is to be read
- the size of the buffer
The write functions requires similar arguments
The following is the example of write
#include<fstream.h>
void main()
{ ofstream srt(“integer.txt”);
void main()
{
student stvar;
fstream fil(“sample.txt”,ios::in);
fil.seekg(0,ios::end); //end of the file
int chek;
chek=fil.tellg();
cout<<“the size of the file is”<<chek<<endl;
cout<<“size of one record “<<sizeof(student)<<endl;
int crec=chek/sizeof(student);
cout<<“no of records are”<<crec<<“in the file sample txt”<<endl;
}
Program
NOTE:
seekg and tellg belongs to istream
seekp and tellp belongs to ostream
File Handling / 119
10.8 Check your progress
Q.1 State true or false
1. The tellg () function takes no argument.
_________________
2. The ios::end in the seekg (), positions the get pointer at the end of the file.
_________________
10.10 SUMMARY
In this chapter we learnt about the stream class and file handling.
A Stream is a sequence of characters (strings). When you start the execution
of a C++ program, several streams are opened automatically. They are: cin, cout, cerr,
clog. Then we learnt about the hierarchy of stream class.
The file handling techniques of C++ support file manipulation in the form of
stream objects. The stream objects are predefined in the header file, iostrean.h. Then
we learnt about stream insertion and extraction.
To perform file I/O, the header file fstream.h must be included in the program.
It defines several classes, including ifstream, ofstream and fstream. These classes are
derived from ios, so ifstream, ofstream and fstream also have full access to all operations
defined by ios. We saw how file be write and read. Then we saw open () and close
function.
How end of file is detected. Function ifstream::eof() is used to detect end of file.
The function returns zero if end of file is reached. How error handling is done.
10.3 &10.4
Q.1 1. fstream.h
2. cin
3. ios::binary
10.6
Q.1 1. ifstream::eof()
2. getline ()
10.8
Q.1 1. True
2. False
C++ / 124
CHAPTER 11
Exception Handling
11.0 Objectives
11.1 Introduction
11.2 Exception handling fundamentals
11.3 Multiple catch statement
11.4 Throw statement
11.5 Summary
11.6 Check your Progress - Answers
11.7 Questions for Self - Study
11.8 Suggested Readings
11.0 OBJECTIVES
Friends,
After studying this chapter you will be able to
• discuses meaning of exception
• describe exception handling fundamentals
• state multiple catch statement
• state throw statement
11.1 INTRODUCTION
Exceptions are the errors that occur at runtime. The reasons why exceptions
occur are numerous. Some of the more common reasons are-inability to open a file,
exceeding the bounds of an array, falling short of memory etc.
Using, C++ exception handling, the program can automatically invoke error-
handling routines when an error occurs. The user can specify a list of exceptions that
a function may throw as a part of a function declaration.
void main()
{
int a,b,c;
clrscr();
The above program catches division by zero problems. We check weather the
second no i.e. divider, is not zero. If no is zero or less than zero an exception is thrown
using b object. Since the exception object is an int type, the catch statement containing
int type argument catches the exception and display message.
C++ / 126
11.3 MULTIPLE CATCH STATEMENTS
As stated earlier, code for handling exceptions is included in catch blocks. You
can have more than one-catch statements, but each catch statement must catch a
different data-type. The number of catch statements cannot exceed the number of data-
types supported by the language.
Following program illustrates this.
# include<iostream.h>
#include<conio.h>
void test(int i)
{
try
{
if(i!=0)
throw i; // int type exception
else
throw “Zero”; // char type exception
}
Catch (int a)
{
cout<< “Caught an int”<< a << endl;
}
catch (char *s)
{
cout<<“Caught a string”<<st<< endl;
}
}
void main()
{
cout<<“Testing multiple catch statements”;
test(1);
test(23);
test(0);
}
The above program has 2 catch statements. First catch statement have an
integer data-type and second have character data-type. When the program is executed,
it invokes the test function with i=1 and it checks whether it is equal to zero or not.
It is not equal to zero, it throws an int exception and it matches with first catch handler.
So, first catch statement is executed. In the last test function is invoked with i=0. This
time it throws a character type exception so second catch statement is executed.
Catching all exceptions
in some situations, we may not be able to anticipate all possible types of
executions and therefore may no be able to design independent catch handlers to
catch them. In such cases we require a catch statement that will catch any exception
instead of a particular data type. Defining catch statement using ellipses as follows can
do this.
catch(...)
#include<iostream.h>
#include<conio.h>
void test(int i)
{
try
{
If (i!=0)
throw i; // int type exception
else
throw “Zero”; // char type exception
}
catch(...) //catch all
{
cout<< “Caught an exception”<< a << endl;
}
}
void main()
{
cout<<“Catching all exceptions in single catch statement”;
test(1);
test(2);
test(0);
}
It is good practice to catch all exceptions using catch (...), as there is no need
to handle exceptions explicitly. By catching all exceptions unhandled exceptions causing
abnormal termination of program can be prevented.
C++ / 128
void test(int a) throw(int, double)
{
if (a= =0) throw a;
if(a==1) throw 23.36;
}
void main()
{
try
{
test(0);
}
catch(int i)
{
cout<< “Integer exception”;
}
catch(double d)
{
cout<< “Caught double exception”;
}
}
11.5 SUMMARY
In this chapter we learnt what is an exception? Exceptions are unusual events
that happen in a program under certain circumstances. The common reasons are-
inability to open a file, exceeding the bounds of an array, falling short of memory etc.
C++ exception is built upon three keywords try, catch, and throw. Exceptions
thrown by try block are caught by catch block. You can have more than one-catch
statements, but each catch statement must catch a different data-type. The number
of catch statements cannot exceed the number of data-types supported by the language.
While calling a function from within a try block, the type of exceptions thrown
by that function can be restricted. The function can be prevented to throw an exception
at all. This can be accomplished by adding a throw clause to the function definition.
C++ / 130
NOTES
C++ / 132
Appendix
During this session you will learnt about
• Static class members
• Static member functions
• Overriding insertion and extraction operator
• How to write a global inline function
• The Preprocessor Directives
• Manipulators
• Templates
int counter::getcount()
{
return (count);
}
int counter :: count = 0;// INITIALIZATION OF STATIC MEMBER.
void main()
{
counter c1,c2;
counter c3;
Appendix / 133
cout << “ Count =” << c3.getcount() << endl;
counter c4,c5;
Output:
Count = 2 // not 1 because 2 objects are already created.
Count = 2
Count = 3
Count = 5
Count = 5
In the above example, the class counter demonstrates the use of static data
members. It contains just one data member count. Notice the initialization of this static
class member. For some compilers it is mandatory. Even though the data member is
in the private section it can be accessed in this case as a global variable directly, but
has to be preceded by the name of the class and the scope resolution operator. This
example contains a constructor to increment this variable. Similarly, there can be a
destructor to decrement it.
You can use these to generate register numbers for student objects from a
student class. Whenever an object is created, he will be automatically assigned a
register number if the register number is a static variable and a constructor is used to
write an equation to generate separate register numbers in some order. You could
initialize the variable to give the first register number and then use this in the constructor
for further operations.
C++ / 134
private:
static int count;
};
counter::counter ()
{
count++;
}
int counter: :getcount() {
{
}
int counter:: count = 0; // INITIALIZATION OF
STATIC MEMBER.
void main()
{
counter c1,c2;
cout << “ Count =” << counter:: getcount() << endl;
cout << “ Count = “ << counter:: getcount() << endl;
counter c3;
cout << “ Count = “ << counter:: getcount() << endl;
counter c4,c5;
cout << “ Count =” << counter:: getcount() << endl;
cout << “ Count = “ << counter:: getcount() << endl;
}
Output:
Count = 2
Count = 2
Count = 3
Count = 5
Count = 5
Appendix / 135
cout<< “Enter marks in 4 subjetcs :\n”;
for( int k=0; k<4; ++k)
{
s1>> s2.marks[k];
}
cout<<“\n”;
return s 1;
}
ostream &operator<< (ostream &s1, student s2)
{
s 1<< “Names : “ << s2.name << “‘\n”;
s1<< “Marks:”;
for(int sum=0, k=0; k<4; ++k)
{
s1<<s2.inaiks[k]<<“ “;
sum+= s2.marks[k];
}
float percents = sum/4.0;
s 1<< “// percentage of marks = “ << percents << “\n\n”;.
return s1;
}
void main ()
{
student x;
cin>> x;
cout<<x;
}
C++ / 136
}
}
When the call to the abs ( ) function is encountered, the compiler, instead of
making a function call, generates this assembly code.
void main()
{
cout<< PI;
}
This program is equivalent to :
void main()
{
cout<< 3.14285;
}
The # define directive works strictly on the basis of substitution of a text string
for the macro names.
The #undef Directive
This directive undefines a previously defined macro. For, example the following
will give an error since PI is undefined.
#define PI 3.14285
void main()
{
cout<< PI; // no error here
# undef PI;
cout<<PI; //error after undef.
}
#ifdef condition
statements;
#else
statements;
#endif;
#ifdef condition 1
statements;
#elif condition2
statements;
#endif;
#ifdef condition 1
statements;
#elif condition2
statements;
#else
statements;
#endif;
Just like #ifdef there is also #ifndef which negates the condition.
These directives control which portions of the code will be passed to the compiler.
For example, these directives can be used for compiling the program written for two
different machines. On MSDOS machines, the program can make use of certain
MSDOS features. Otherwise, some other code depending on the machine is executed.
e.g.
void main()
{
#ifdef ___MSDOS____
DOS-fn();
#else
UNIX_fn();
#endif;
}
MANIPULATORS
As discussed earlier, there are several classes in the iostream.h header file. One
of them is ios class. This class stores the format state. For instance, some bits define
the base in which the numbers will be printed, some bits define the field width. This
header file has functions called manipulators, using which the output format can be
controlled. There are 3 manipulators dec(), oct(), hex() to set the base in which a given
number will be printed. These manipulators are called in two ways :
hex(cout); // Pass the object name
cout<< hex; // use the insertion operator.
But since these manipulators are not member functions of the class, it cannot
be used as follows:
cout.hex(); // Not allowed.
e.g.
void main(void)
{
int i =110;
cout << “ Default Base Decimal:”<< i << endl;
Appendix / 139
{
cout<<“ default width=”<< cout.width()<<endl;
cout<<“[“;
cout.width(10); Set width to 10
cout<<“A”;
cout<<“]”;
}
Output:
Default width = 0;
[ A]
This is very useful in preparing reports.
Padding the Extra Places
By default, C++ pads spaces to extra places, if the width specified is more than
the actual output . ostream contains a function fill() to set a new fill character. The
function prototypes are :
char fill(void) //Returns current fill character
char fill(char c) //Set a new fill character.
e.g.
void main()
{
int amt1 = 100, amt2= 12345;
cout.fill(‘*’) ;
cout << “ Amount 1 : [“;
cout.width(5);
cout<< amt1 <<“]\n”;
cout << “Amount 2 :[“;
cout.width(5);
cout << amt2 << “]\n”;
}
Output:
Amount 1 : [**100]
Amount 2 : [12345]
Setting a precision
By default, C++ prints six decimal places after the decimal point, except for
trailing zeroes. The function precision() can be used to change this default behavior. The
function does not merely truncate the trailing digits, it rounds them up. This function
has the following prototype :
int precision(void); //Returns a Current Value.
int precision(int p); // set a new precision
e.g.
void main()
{
float f1 =123.43;
float f2 = 10.0/3.0;
float f3 = 10.0/6.0;
cout <<“Default f1 =[“<<f1 <<“]\n”;
cout << “ Default f2 = [“<< f2 <<“]\n”;
C++ / 140
cout << “ Default f1 = [“<< f3 <<“]\n”;
cout.precision(2);
FUNCTION TEMPLATES
Function templates provide you with the capability to write a single function that
is a skeleton, or template, for a family of similar functions.
In function overloading technique it relieves someone who is using your functions
from having to know about different names for various functions that essentially do the
same task. Unfortunately, overloaded functions are not the ultimate solution to the
problem that is inherent when writing functions that are similar in their behavior.
Consider the following example:
int max(int x, int y)
{
return (x>y)?x:y;
}
float max(float x, float y)
{
return ( x > y) ? x : y ;
}
long max( long x, long y)
{
return ( x > y) ? x : y ;
}
char max(char x, char y)
{
return ( x > y) ? x : y ;
}
void main()
{
cout << max( 1,2) << endl;
cout << max( 4L,3L) << endl;
cout << max( 5.62,3.48) << endl;
cout << max(‘A’ ‘a’)<< endl;
}
Appendix / 141
The output is;
2
4
5.62
a
Even though function overloading is used, the problem with this example is that
there is still too much repetitious coding. In other words, each function is essentially
doing the same task. Now, instead of you having to write many functions, it would be
nice if were to write only one function and can accommodate almost any type of input
argument.
How a Function Template solves this problem
A function template solves the problem by allowing you to write just one function
that serves as a skeleton, or, template, for a family of functions whose tasks are all
similar.
This function template does not specify the actual types of the arguments that
the function accepts; instead, it uses a generic, or parameterized type, as a “ place
holder”, until you determine the specific types. The process of invocation of these
functions with actual parameter types is called the template instantiation.
How to write a function template
A function template should be written at the start of the program in the global
area, or you may place it into a header file. All function templates start with a template
declaration.
The syntax is :
The C++ keyword template
A left angle bracket ( < )
A comma separates a list of generic types, each one. A generic type consists
of two parts
the keyword class ( this usage of class has nothing to do with the key word
class used to create user-defined type.)
a variable that represents some generic type, and will be used whenever this
type needs to be written in the function definition. Typically the name T is used, but
any valid C++ name will do.
A right angle bracket ( > ).
e.g.
template < class T>
T max(char x, char y)
{
return ( x > y) ? x : y ;
}
void main()
{
cout << max( 1,2) << endl;
cout << max( 5.62,3.48) <<endl;
cout << max(‘A’,’a’) << endl;
cout << max( 4,3) << endl;.
}
The output is :
2
C++ / 142
5.62
a
6
Each of first three max () function class causes a template function to be
instantiated, first with an int, then with a double and then with a char. The last call using
two integers does not cause another instantiation to occur because this call can use
the instantiated function that was generated as a result of the first class that also uses
two integers.
The template needs to have parameters, either a template type representing a
type or a template non-type parameter representing a constant expression.
e.g.
template < class Hello, const int size >
Hello min ( const Hello ( & array)[size])
{
Hello min_val = array [0];
for(int i=1; i<size; ++i)
{
if( array[i] < min_val)
min_val = array[i];
}
return (min_val);
}
Where Hello can be built in or user defined type and size is always constant and
integer.
A template type specifier can be used for variable declaration ( in the above
example , it is used to declare min_val), casts etc., just like normal variable.
We can have more than one template parameter type in the same template.
e.g.
template < class T1, class T2, class T3>
T3 min (T1 a , T2 b);
We can even overload function templates,
e.g.
template <class T>
T min ( T *, int);
Class Templates
In addition to function templates, C++ also supports the concept of class templates.
By definition, a class template is a class definition that describes a family of related
classes. The philosophy is essentially the same as that of function templates, i.e., the
ability to create a class (or structure) that contains one or more types that are generic,
Appendix / 143
or parameterized.
A class template is defined in a manner similar to that of a function template.
You start by writing a template declaration followed by the class definition:
e.g.
Template <class T>
class test
{
private : T item;
// data and functions
};
The generation of a class from class definition is called template instantiation.
We can declare variables of this class as follows:
void main()
{
test<int> intobj;
test<double> doubleobj;
}
In the first instantiation the entire template types i.e. variables of type T will be
converted as integers. In the second case they are converted as double variables.
Of course, you may have more than one parameterized type between the angle
brackets.
Template < class T1, class T2, class T3>
class classname;
Each parameter should be preceded with the keyword class.
Template < classT, U> // Error
Template < class T, class U> // O.K.
In this session we have seen how a static variable and static function combination
can be used for variables, which are shared by all the objects and hence can be given
a single memory location and how objects are not required to invoke them. We also
learnt how to share our private details with friends, which though should not be overused,
but becomes extremely necessary sometimes. Using the manipulators and iostream
objects we can enhance the way our output appears on the screen. Functions can
be made as inline functions if they are small. These are substituted in place of
function calls and are faster compared to calling and returning as compared to-normal
functions. We also learnt how the shortcomings of function overloading could be overcome
using template functions.
A non-type parameter represents a constant value.
Template < class T, const int buffer > class classname;
The functions of the template classes obey the rules of the function templates.
C++ / 144