Programming in C++ and Data Structure Vol1
Programming in C++ and Data Structure Vol1
UNDERGRADUATE COURSE
BCA - COMPUTER APPLICATIONS
SECOND YEAR
THIRD SEMESTER
CORE PAPER - V
PROGRAMMING IN C++ AND
DATA STRUCTURES
VOLUME - I
I invite you to join the CBCS in Semester System to gain rich knowledge leisurely at
your will and wish. Choose the right courses at right times so as to erect your flag of
success. We always encourage and enlighten to excel and empower. We are the cross
bearers to make you a torch bearer to have a bright future.
DIRECTOR
(i)
BCA, COMPUTER APPLICATIONS CORE PAPER - V
SECOND YEAR PROGRAMMING IN C++ AND
THIRD SEMESTER DATA STRUCTURES
VOLUME - I
COURSE WRITER
Mr. K. Rajasekaran
Lecturer in Computer Science
D.B. Jain College
Chennai - 600 096.
Dr. S. Sasikala
Assistant Professor in Computer Science
Institute of Distance Education
University of Madras
Chepauk, Chennai - 600 005.
Printed by: Publication Section, Institute of Distance Education IIDE), University of Madras,
Chennai - 600 005, Website:- www.ideunom.ac.in
(ii)
BACHELOR OF COMPUTER APPLICATIONS
SECOND YEAR
THIRD SEMESTER
CORE PAPER - V
PROGRAMMING IN C++ AND DATA STRUCTURES
VOLUME - I
SYLLABUS
Objective of the course
This course introduces the basic concepts of programming in C++ and Data
Structures
Course outline
Unit 3: Working with Files: Classes for File Stream Operations Opening and Closing
a File End of File Deduction File Pointers Updating a File Error Handling during File
Operations Command line Arguments. Data Structures: Definition of a Data structure
primitive and composite Data Types, Asymptotic notations, Arrays, Operations on Arrays,
Order lists.
(iii)
Unit-5: Trees and Graphs: Binary Trees Conversion of Forest to Binary Tree,
Operations Tree Traversals; Graph Definition, Types of Graphs, Hashing Tables and
Hashing Functions, Traversal Shortest Path; Dijkstra’s Algorithm.
1. Recommended Texts :
2. Reference Books:
i.) Robert Lafore, Object Oriented Programming in Microsoft C++, Galgotia publication.
iii) R. Kruse C.L. Tondo and B. Leung ,1997, Data Structures and Program design in C,
PHI.
(iv)
BACHELOR OF COMPUTER APPLICATIONS
SECOND YEAR
THIRD SEMESTER
CORE PAPER - V
PROGRAMMING IN C++ AND DATA STRUCTURES
VOLUME - I
SCHEME OF LESSONS
Sl.No. Title Page No.
9 Inheritance 153
(v)
1
LESSON - 1
1.1 Introduction
1.6 Summary
1.1 Introduction
Developments in software technology continue to be dynamic. New tools and techniques are
announced in quick succession. This has forced the software industry and software engineers
to continuously look for new approaches to software design and development. Which is becoming
more and more critical in view of the increasing complexity of software systems as well as
highly competitive nature of the industry. These rapid advances appear to have created a serious
crisis within the industry. The following issues need to be resolved to overcome this crisis:
Figure 1.1
delivered but neverxused. It is interesting to note that only 2% were used as delivered, without
being subjected to any changes.
3
Changes in user requirements have always been a major problem. Another study (Figure 1.2)
shows that more than 50% of the systems required modifications due to changes in user
requirements and data formats. It only illustrates that, in a changing world with a dynamic business
environment, requests for change are unavoidable and therefore systems must be adaptable
and tolerant to changes.
Figure 1. 2
Breakdown of maintenance costs
These studies and other reports on software implementation suggest that software products
should be evaluated carefully for their quality before they are delivered and implemented. Some
of the quality issues that must be considered for critical evaluation are:
1. Correctness
2. Maintainability
3. Reusability
5. Portability
6. Security
7. Integrity
8. User friendliness
Selection and user of proper software tools would help achieve some of these objectives.
4
Ernest Tello, a well-known writer in the field of artificial intelligence, compared the evolution of
software technology to the growth of a tree, the software evolution has had distinct phases or
"layers" of growth. These layers were built up one over the last four decades as shown in Figure
1.3, with each layer representing an improvement over the previous one. However, the analogy
fails if we the life of these layers. In software systems, each of the continues to be functional,
whereas in the case of trees, only the uppermot layers in functional.
Figure 1.3
Alan Kay, one of the promoters of the object-oriented paradigm and the principal designer of
Smalltalk, has said: "As complexity increases, architecture dominates the basic material". To
build today's complex software it is just not enough to put together a sequence of programming
statements and set of procedures and modules, we need to incorporate sound construction
techniques and program structures that are easy to comprehend, implement and modify.
Since the invention of the computer, many programming approaches have been tried. These
included techniques such as modular programming, top-down programming, bottom- up
programming and structured programming. The primary motivation in each case been the
concern to handled the increasing complexity of programs that are reliable and maintainable.
These techniques became popular among programmers over the last two decades.
With the advent of languages such as C, structured programming because very popular and
was the main techniques of the 1980s. Structured programming was a powerful tool that enabled
5
programmers to write moderately complex programs fairly easily. However, as the programs
grew large, even the structured approach failed to show the desired results in terms of bug-free,
easy-to-maintain, and reusable programs.
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
Decomposition has been used to specify the task to be completed in order to solve a problem.
6
Figure 1.4
While we concentrate on the development of functions, very little attention is given of the data
that are being used by various functions. What happens to the data? How are they affected by
the functions that work on them?
In a multi-function program, many important data items are placed as global so that they may be
accessed by all the functions. Each function may have its own local data. Figure 1.5 shows the
relationship of data and functions in a procedure-oriented program.
7
Figure 1.5
Global data more vulnerable to an inadvertent change by a function. In a large program it is very
difficult to identify what data is used by which function. In case we need to revise an external
data structure, we should also revise all functions that access the data. This provides an
opportunity for bug to creep in.
Another serious drawback with the procedural approach is that it does not model real world
problems very well. This is because functions are action-oriented and so not really correspond
to the elements of the program 209
The data of an object can be accessed only by the functions associated with the object. However,
functions of one object can access the functions of other objects.
Figure 1.6
• Data structures are designed such that they characterise the objects.
9
• Functions that operate on the data of an object are tied together in the data structure.
Object-Oriented programming is the most recent among programming paradigms and still means
different things to different people. It is therefore important to have a working definition of object-
oriented programming before we proceed further. Our definition of object- oriented programming
is as follows: "Object-oriented programming is an approach that provides a way of modularizing
programs by creating partitioned memory area for both data and functions that can be used as
templates for creating copies of such modules on demand"
That is an object is considered to be partitioned area of computer memory that stores data and
set operations that can access that data. Since the memory partitions are independent, the
objects can be used in a variety of different programs without modifications.
2. Expantion of OOPS___________
1.6 Summary
In this lesson we have discussed about Software Evolution, Structure of Procedure- Oriented
Programs and Object Oriented Programming Paradigm. Object Oriented Programming is an
approach that provides a way of Modularizing programs by creating partitioned memory area for
both data and functions that can be used as templates for creating copies of such modules on
Demand.
10
II 1) C, Cobol, Fortran
2) Object-Oriented Programming
2. Briefly discuss the software evolution during the period from 1950 to 1990.
LESSON - 2
BASIC CONCEPTS OF
OBJECT-ORIENTED PROGRAMMING
Structure
2.1 Introduction
2.7 Summary
2.1 Introduction
In this lesson we will discuss about Basic Concepts of OOPS, Benefits of OOPS and
Applications of OOPS. Object-Oriented Programming is the most recent concept among
programming paradigms.
• Benefits of OOPS
• Object-oriented languages
• Applications of OOPS
12
1. Objects
Objects are the basic run-time entities in an object-oriented system. They may represent a
person, a place, a bank account, a table of data or any item that the program must handle. They
may also represent user-defined data such as vectors, time and lists. Programming problem is
analyzed in terms of objects and the nature of communication between them. Program objects
should be chosen such that they match closely with the real-word objects. As pointed out earlier,
objects take up space in the memory and have an associated address like a record in pascal, or
a structure in C.
When a program is executed, the objects interact by sending messages to one another. For
example, if "customer" and "account" are two object in a program, then the customer object
may send a message to the account object requesting for the bank balance. Each object contains
data and code to manipulate the data. Objects can interact without having to know details of
each other's data or code. It is sufficient to know the type of message accepted and the type of
response returned by the objects. Although different authors represent them differently, Figure
2.1
Shows two notations that are popularly used in object-oriented analysis and design.
Figure2.1
Two ways of representing an object
13
2. Classes
We just mentioned that objects contain data and code manipulate that data. The entire set of
data and code of an object can be made a user-defined data type with the help of a class. In fact,
objects are variables of type class. Once a class has been defined, we can create any number
of objects belonging to that class. Each object is associated with the data of type class with
which they are created. A class is thus a collection of objects of similar type. For example,
mango, apple and orange are member of the class fruit. Classes are user-defined data types
and behave like the built-in type of a programming languages. For example, the syntax uses to
create an object is no different than the syntax uses to create an integer object in C. If fruit has
been defined as a class, then the statement
Fruit mango;
The wrapping up of data and functions into a single unit (called class) is known as encapsulation.
Data encapsulation is the most striking feature of a class. The data is not accessible to the
outside world and only those functions which are wrapped in the class can access it. These
functions provide the interface between the object's data and the program. This insulation of the
data from direct access by the program is called data hiding.
Abstraction refers to the act of representing essential without including the background details
or explanations.
Classes use the concept of abstraction and are defined as a list abstract attributes such as
size, weight and cost, and functions to operate on these attributes. They encapsulate all the
essential properties of the objects that are to be created. Since the classes use the concept of
data abstraction, they are knows as Abstract Data Types(ADT)
4. Inheritance
Inheritance is the process by which objects of one class acquire the properties of objects of
another class. It supports the concepts of hierarchical classification. For example, the bird robin
is a part of the class flying bird which is again a part of the bird. As illustrated in figure2.2, the
principal behind this sort of division is that each derived class shared common characteristics
with the class from which it is derived.
14
In OOP, the concept of inheritance provides the idea of reusability. This mean that we can add
additional features to an existing class without modifying it. This is possible by deriving a new
class from the existing one. The new class will have the combined features of both the classes.
The real appeal and power of the inheritance mechanism is that it allows the programmer to
reuse a class that is almost, but not exactly, what he wants, and to tailor the class in such a way
that it does not introduce any undesirable side effects into the rest of the classes.
Note that each sub-class defines only those features that are unique to it. Without the use of
classification, each class would have to explicitly include all of its features.
Figure 2.2
Property Inheritance
5. Polymorphism
Polymorphism means the ability to take more than one form. For example, an operation may
exhibit different behaviour in different instances. The behaviour depends upon the types of data
used in the operation. For example, considered the operation of addition. For two numbers, the
operation will generate a sum. If the operands are strings, then the operation would produce a
third string by concatenation. FigureJ2.3 illustrates that a single function name can be used to
15
handle different number and different types of arguments. This is something similar to a particular
world having several different meaning depending on the context. 22
Polymorphism plays an important role in allowing objects having different internal structures to
share the same external interface. This means that a general class of operations may be
accessed in the same manner even through specific actions associated with the each operation
may differ. Polymorphism is extensively used in implementing inheritance.
Figure2.3
Polymorphism
6. Dynamic Binding
Binding refers to the linking of a procedure call to the code to be executed in response to the call.
Dynamic binding means that the code associated with a given procedure call is not known until
the time of the call at run-time. It is associated with polymorphism and inheritance. A function
call associated with a polymorphic reference depends on the dynamic type of that reference. i
Consider the procedure "draw" in figure 2.3. By inheritance, every objectwill have this procedure.
Its algorithm is, however, unique to each object and so the draw procedure will be redefined in
each class that defines the object. At runtime, the code matching the object under current
referencef.
7. Message Communication
An object-oriented program consists of a set of object that communicate with each other. The
process of programming in an object-oriented language therefore involves the following basic
steps:
16
Objects communicate with one another by sending and receiving information much the same
way as people pass messages to one another. The concept of message passing makes it
easier to talk about building systems that directly model or simulate their real- world counterparts.
A message for an object is a request for execution of a procedure, and therefore will invoke a
function(procedure) in the receiving object that generates the desired result. Message passing
involves specifying the name of the object, the name of the function(message) and the information
to be sent. Example neq u veep al
object information
message
Objects have a life cycle. They can be created and destroyed. Communication with an object is
feasible as long as it is alive.
2. The Wrapping up of data and functions into a single unit is known as__________.
• Through inheritance, we can eliminate redundant code and extend the use of existing
classes.
17
• We can build programs from the standard working modules that communicate with the
another, rather than having to start writing the code from scratch. This leads to saving of
development time and higher productivity.
• The principle of data hiding helps the programmer to built secure programs that cannot
be invaded by code in other parts of the program.
• interference. It is possible to map objects in the problem domain to those object in the
• program.
• Message passing techniques for communication between objects makes the interference
descriptions with external systems much simpler.
While it is possible to incorporate all these features in an object-oriented system, their importance
depends on the type of the project and the benefits stated above. For, instance, object libraries
must be available for reuse. The technology is still developing and current products may be
superseded quickly. Strict controls and protocols need to be developed it reuse is not be
compromised.
Developing a software that is easy to use makes it hard to build. It is hoped that the object-
oriented programming tools would help manage this problem.
The languages should support several of the OOP concepts to claim that they are object-oriented.
Depending upon the features they support, they can be classified into the following two categories:
• Data encapsulation
• Operator overloading
RDO Languages that support programming with objects are said to be object-based programming
languages. They do not support inheritance and dynamic binding. Ada is a typical object-based
programming language.
Object-based features + inheritance + dynamic binding. Languages that support these features
include C++, Smalltalk and Object Pascal. There are a large number of object- based and
object-oriented programming languages. Table 2.1 lists some popular general purpose OOP
languages and their characteristics.
As seen from the Table 12:1 all languages provide classes, objects and data hiding, but many of
them do not provide facilities for concurrency, persistence and genericity. Eiffel and Ada provide
generic facility. This is an important construct for supporting reuse. Persistence, a process of
storing objects, is not fully supported by any of them. In Smalltalk the entire current execution
state can be saved to disk. Yet, individual objects cannot be saved to an external file.
19
The field is so new, however, that is should not be judged too harshly. Commercially, C++ is only
five year old, Smalltalk and objective C only eight year old. Although Simula has existed has
existed for more than two decades, it has spend most of its life in a research environment.
Real business eyetems are offer mut more complies and contain many more objects with
complicated after and methods OOP his hoe of application because I can simply a compres
prim. The promising as for colleation of OOP includes
20
Table 2.1
• Real-time Systems
• Object-oriented databases
• CIM/CAM/CAD System
21
The object-oriented paradigm sprang from the language, has matured into design and has recently
moved into analysis. It is believed that the richness of OOP environment will enable the software
industry to improve not only the quality of software systems but also its productivity. Object-
oriented technology is certainly going to change the way engineers will think, analyse, design
and implement systems in the future. software
2.7 Summary
In this lesson we have covered Basic Concepts of OOPS, Benefits of OOPs and Applications of
OOPs. Objects are the basic run-time entities in an Object-Oriented System.
2) encapsulation
3) polymorphism
LESSON - 13
INTRODUCTION TO C++
Structure
3.1 Introduction
3.3 Tokens
3.4 Operators
3.5 Summary
• Tokens
3.1 Introduction
C++ is an object-oriented programming language. Initially named 'C' with classes', C++ was
developed by Bjarne Stroustrup at AT&T Bell Laboratories in Murray Hill, New Jersey, USA, in the
early eighties. Stroustrup, an admirer of SimulaG? and a strong supporter of C, wanted to combine
the best of both languages and create a more powerful language that could support object-
oriented programming features and still retain the power and elegance of C. The result was
C++. Therefore, C++ is an extension of C with a major addition of the class construct feature of
Simula67. Since the class was a major addition to the original C language, Stroustrup called the
new language 'C with classes'. However, later in 1983, thename was changed to C++. The idea
of C++ comes from the C increment operator++, thereby suggesting that C++ is an augmented
(incremented) version of C.
C++ is superset of C. Most of what we already know about C applies to C++ also. Therefore,
almost all C programs are also C++ programs. However there are few minor differences that
23
will prevent a C program to run under C++ compiler. We shall see these differences later as and
when they are encountered.
The three most important facilities at C++ adds on to C are classes, function overloading, and
operator overloading. These features enable us to create abstract data types, inherit properties
from existing data types and support polymorphism, thus making C++ a truly object-oriented
language.
The object-oriented features in C++ allow programmers to build large programs with clarity,
extensibility and ease of maintenance, incorporating the spirit and efficiency of C.
The addition of new features has transformed C from a language that currently facilitates top
down, structured design, to one that provides bottom-up, object-oriented design.
3.3 Tokens
As we know, the smallest individual units in a program are known as tokens. C++ has the
Following tokens:
Keywords
Identifiers32
Constants
Strings
Operators
A C++ program is written using these tokens, white spaces, and the syntax of the language.
Most of the C++ tokens are basically similar to the C tokens with the exception of some additions
and minor modifications.
1. Keywords
The key words implement specific C++ language features. They are explicitly reserved identifiers
and cannot be used as names for the program variables or other user-defined program elements.
The below table gives the complete set of C++ keywords. The keywords not found in ANSI C are
shown in boldface. These keywords have been added to the ANSI C Keywords in order to
enhance its features and make it an object-oriented language.
24
C++ Keywords
2. Identifiers
Identifiers refer to the names of variables, functions, arrays, classes, etc. created by the
programmer. They are the fundamental requirement of any language. Each language has its
own rules for naming these identifiers. The following rules are common to both c and C++:
A major difference between C and C++ is the limit on the length of a name. While ANSI C
recognizes only the first 32 characters in a name, C++ places no limit on its length and therefore,
all the characters in a name are significant.
25
Care should be exercised while naming a variable that is being shared by more than one file
containing C and C++ programs. Some operating systems impose a restriction on the length of
such a variable name.
3. Declaration of Variables
We know that, in C, all the variables to be defined at the beginning of a scope. When we read a
C program, we usually come across a group of variable declarations at the beginning of each
scope level. Their actual use appears else where in the scope, sometimes far away from the
place declaration. Before using a variable, we should go back to the beginning of the program to
see whether it has been declared and, if so, of what type it is.
C++ allows the declarations of a variable anywhere in the scope. This means that a variable can
be declared right at the place of its first use. This makes the program much easier to write and
reduces the errors that may be caused by having to scan back and forth. It also makes the
program easier to understand because the variables are declared in the context of their use.
The example below illustrates this point.
main()
float x; //declaration
float sum=0;
cin>>x;
sum sum+x;
The only disadvantage of this style of declaration is that we cannot see at a glance all the
variables used in a scope.
26
One additional feature of C++ is that it permits initialization of the variables at run time. This is
referred to as dynamic initialization. Remember that, in C, a variable must be initialized using a
constant expression and the C compiler would fix the initialization code at the time of compilation.
However, in C++, a variable can be initialized at run time using expressions at the place of
declarations. For example, the following are valid initialization statements:
........................
........................
int n=strlen(string);
........................
This means that both the declaration and initialization of a variable can be done simultaneously
at the place where the variable is used for the first time. The following two statements in the
example of the previous section tod lo sulsy Ill 015
average=sum/i; 36
Reference Variables
C++ introduces a new kind of variable know as the reference variable. A reference variable
provides an alias(alternative name) for a previously defined variable. For example, if we make
the variable sum a reference to the variable total, then sum and total can used interchangeably
to represent that variable. A reference variable is created as follows:
27
Example:
total is a float type variable that has already been declared, sum is the alternative name declared
to represent the variable total. Both the variables refer to the same data object in the memory.
Now, the statements
cout<<total;
and
cout<<sum;
total total+10;
will change the value of both total and sum to 110. Likewise, the assignment
sum=0;
A reference variable must be initialised at the time of declaration. This establishes the
correspondence between the reference and the date object that it names. Note that the
initialization of a reference variable is completely different from assignment to it.
Note that C++ assigns additional meaning to the symbol &. Here, & is not an address operator.
The notation float & means reference to float. Other examples are:
int n[10];
The variable x is an alternative to the array element n[10]. The variable a is initialized to the new
line constant. This creates a reference to the otherwise unknown location where the new line
constant \n is stored.
28
(i) int x;
int *p=&x:
stebint &m=*p;
The first set of declarations causes m to refer to x which is pointed to by the pointer p and the
statement in (ii) creates an int object with value 50 and name n.
| {
| }
| main()
| {
| int m =10;
When the function call f(m) is executed, the following initialization occurs:
f(m).
Such function call are known as call by reference whose implementation is illustrated in Figure.
Since the variable x and m are aliases, when the function increments x, m is also incremented.
The value of m becomes 20 after the function in executed. In traditional C, we accomplish this
operation using pointers and dereferencing techniques.
29
3.4 Operators
C++ is very rich in built-in operators. In fact, it places more significance on operators than do
most other computer languages. There are four main classes of operators as follows.
• Arithmetic
• Relational
• Logical
• Bitwise.
1. Assignment Operator
We can use the assignment operator within any valid expression. The general form is as follows:
Variable_name=expression; 3(0*.2
2. Arithmetic Operators
There are four arithmetic operators. They are +, -, *, ./. in addition to that C++ also provides the
remainder or modulo operator represented by the % symbol. The modula operator returns the
remainder when an integer is divided by another. The following program illustrates the use of the
modulo operator.
void main()
{
int a, b;
30
a=5, b=2;
clrscr();
printf("%d", a/b); Twill display 2V
printf("%d", a%b): Twill display 1, the remainder of the integer division "/
getch( ),
}
C++ includes two useful operators not generally found in other cnmnuter lanmianeR These are
the increment and decrement operators, ++ and --. The operator ++ adds .1 to its operand, and
--subtracts one. In other words:
Both the increment and decrement operators may either precede (prefix) or follow (postfix) the
operand: For example,
There is, however, a difference between the prefix and postfix forms when you use these operators
in an expression. When an increment or decrement operator precedes its operand, the increment
or decrement operation is performed before obtaining the value of the operand for use in the
expression. If the operator follows its operand,
Operator Action
+ Addition
* Multiplication
/ Division
% Modulus
-- Decrement
++ Increment
31
the value of the operand is obtained before incrementing or decrementing it. For instance, The
precedence of the arithmetic operators are as follows:
Highest ++ - •
- (unary minus)
- *1 %
Lowest +-
Operators on the same level of precedence are evaluated by the compiler from left to right. Of
course, you can use parentheses to alter the order of evaluation. C++ treats parentheses in the
same way as virtually all other computer languages. Parentheses force an operation, or set of
operations, to have a higher level of precedence.
Relational operators are used to compare two values. The result of the comparison is either
true(1) or false(0).
Operator Meaning
== Equal to
!= Not equal to
The equal to (==) operator is not the same as the assignment operator (=). Both are different.
5. Logical Operators
Logical operators are used to combine two or more test expressions. C++ provides ..the
AND(&&), the OR(II) and the NOT(!) logical operators.
32
AND(&&) operator
The && operator combines two condition expressions and evaluates to true only if both conditions
are fulfilled.
#include<iostream.h>
#include<conio.h>
void main()
inta;
cout<<"Enter a number";
cin>>a;
if((a!=0)&&(a%2)==0))
cout<<"Even number";
cout<<"Even number";
else
The above displays the output as "Even number" only if both the conditions are true. Otherwise
the statement following the else is executed.
33
OR (II) operator
The logical operator || combines two conditional expressions, and evaluates to true if any one of
the condition is fulfilled.
#include<iostream.h>
#include<conio.h>
void main()
char c;
cout<<"Enter A or a";
cin>>c;
if(c=='a' || c=='A')
else
In the above if any one of the test expressions A or a is true then the statement
The logical operator ! is a unary operator. It takes only one operand. The effect of the ! is that the
logical value of its operand is reversed.
34
The test expression if((a!=0)&&(a%2) «0)) in the program for demonstrating && operator can
be changed as if ((!(a=0)) && ((a%2)==0))
6. Bitwise Operators
C++ supports a full complement of bitwise operators. Bitwise operation refers to testing, setting,
or shifting the actual bits in a byte or word, which correspond to the char and int data type and
variants. YOU cannot use bitwise operations on float, double, long double, void, bool, or other,
more complex types. The following figure lists the operators that apply to bitwise operations.
These operations are applied to the individual bits of the operands
Operator Action
& AND
| OR
^ Exclusive OR(XOR)
Exp 1 ? Exp 2: and Exp 3 are expressions. Notice the use and placement of the colon.
The ? operator works like this: Exp1 is evaluated. If it is true, Exp2 is evaluated and becomes the
value of the expression. If Exp1 is false, Exp3 is evaluated and its value becomes the value of
the expression. For example, in
x= 10;
y=x>9? 100:200;
y is assigned the value 100. If x had been less than 9, y would have received the value 200. The
same code written using the if-else statement is
x = 10;
if (x>9)y= 100;
else y = 200;
35
A pointer is the memory address of some object. A pointer variable is a variable that is specifically
declared to hold a pointer to an object of its specified type. Knowing a variable's address can be
of great help in certain types of routines. However, pointers have three main functions in C++.
They can provide a fast means of referencing array elements. They allow functions to modify
their calling parameters. Lastly, they support linked lists and other dynamic data structures.
The first pointer operator is &, a unary operator that returns the memory address of its operand.
(Remembers, a unary operator only requires one operand). For example,
m = &count;
places into m the memory address of the variable count. This address is the computer's internal
location of the variable. It has nothing to do with the value of count. You can think of & as meaning
"the address of." Therefore, the preceding assignment statement means "m receives the address
of count."
To better understand this assignment, assume that the variable count is at memory location
2000. Also assume that count has a value of 100. Then, after the previous assignment, m will
have the value 2000.
The second pointer operator is *, which is the complement of &. The * is a unary operator that
returns the value of the variable located at the address that follows it. For example, if m contains
the memory address of the variable count,
q = *m;
places the value of count into q; Now q has the value 100 because 100 is stored at location
2000, the memory address that was stored in m. Think of as meaning "at address." In this case,
you could read the statement as "q receives the value at address m."
Unfortunately, the multiplication symbol and the "at address" symbol are the same, and the
symbol for the bitwise AND and the "address of" symbol are the same. These operators have no
relationship to each other. Both & and have a higher precedence than all other arithmetic operators
except the unary minus, with which they share' equal precedence.
Variables that will hold memory addresses (i.e. pointers), must be declared by putting: * in front
of the variable name. This indicates to the compiler that it will hold a pointer. 'For example, to
declare ch as a pointer to a character, write
36
char *ch;
Here, ch is not a character but a pointer to a character - there is a big difference. The type of
data that a pointer points to, in this case char, is called the base type of the pointer. However, the
pointer variable itself is a variable that holds the address to an object of the base type. Thus, a
character pointer (or any pointer) is of sufficient size to hold an address as defined by the
architecture of the computer that it is running on. However, remember that a pointer should only
point to data that is of that pointer's base type.
You can mix both pointer and non-pointer variables in the same declaration statement. For
example,
declares x and count as integer types and y as a pointer to an integer type. The following program
uses* and & operators to put the value 10 into a variable called target. As expected, this program
displays the value 10 on the screen.
#include<stdio.h>
int main(void)
int*m;
source* 10;
m = & source;
target = *m;
printf("%d", target);
return 0;
The comma operator strings together several expressions. The left side of the comma operator
is always evaluated as void. This means that the expression on the right side becomes the
value of the total comma-separated expression.
37
First assigns y the value 3 and then assigns x the value 4. The parentheses are necessary
because the comma operator has a lower precedence than the assignment operator. Essentially,
the comma causes a sequence of operations. When you use it on the right side of an assignment
statement, the value assigned is the value of the last expression of the comma-separated list.
The comma operator has somewhat the same meaning as the word "and" in normal English as
used in the phrase, "do this and this and this."
In C++, the dot and arrow operators also used to access the member of a class.
The dot operator is used when working with a structure or union directly. The arrow operator is
used when a pointer to a structure or union is used. For example, given the fragment
struct employee
char name[80];
int age;
float wage;
}emp;
you would write the following code to assign the value 123.23 to the wage member of structure
variable emp:
emp.wage 123.23;
Parentheses are operators that increase the precedence of the operations inside them. Square
brackets perform array indexing. Given an array, the expression within square brackets provides
an index into that array. For example,
38
#include<stdio.h>
char s[80];
int main(void)
s[3]='X';
printf("%c", s[3]):
return 0;
first assigns the value "X" to the fourth element (remember, all arrays begin at 0) of array s, and
then prints that element.
3.5 Summary
In this lesson we have covered tokens and opertors. An operator, in general is a symbol that
operates on a certain data type.
2) C
II 1) +, -, *, /, %
LESSON - 14
MANIPULATORS AND CENTRAL STATEMENTS
Structure
4.1 Introduction
4.3 Manipulators
4.4 Expression
4.6 Pointers
4.7 Summary
4.1 Introduction
C++ is a superset of C and therefore most constructs of C are legal in C++ with their meaning
unchanged. However, there are some exceptions and additions. In this lesson. we shall discuss
these exceptions and additions with respect to tokens and central structures.
• Mainpulators
• Expression
• Control Statements
• Pointers
40
4.3 Manipulators
Manipulators are operators that are used to format the data display. The most commonly used
manipulators are endl and setw.
The end! manipulator, when used in an output statement, causes a linefeed to be inserted. It
has the same effect as using the newline character"\n". For example, the statement
.............
.............
<<"n=" «n «<endl
<<"p=" «p «<endl;
.............
.............
would cause three lines of output, one for each variable. If we assume the values of the variables
as 2597, 14 and 175 respectively, the output will appear as shown below:
m = 2597
n = 14
P = 175
Note that this form is not the ideal output. It should appear rather as follows:
m = 2597
n = 14
p = 175
Here, the numbers are right-justified. This form of output is possible only if we can specify a
common field width for all the numbers and force them to be printed right justified.
41
The manipulator setw(5) specifies a field widths for printing the value of the variable sum. This
value is might justified within the files as shown below:
_ _345
Use of Manipulators
#include <iostream.h>
main()
cout
Allowance «<endl
«<setw(10)<<" Total"
<<endl;
Basic 950
Allowance 95
Total 1045
42
4.4 Expression
An expression is a combination of operators, constants and variables arranged as per the rules
of the language. It may also include function calls which return values. An expression may
consist of one or more operands and zero or more operators to produce a value. Expression
may be of four types, namely, constant expressions, integral expressions, float expressions,
and pointer expressions.
Example
35
40-9/3.0
'y'
Integral expressions are those, which produce integer results after implementing all the automatic
and explicit type conversions.
Example
A* B-8
A+ int (7.0)
Float expressions are those which, after all conversions, produce floating-point results.
Example
A+B
A*B/10
8+float(10)
19.76
43
Example
&m
ptr
ptr+1
"xyz"
A= 8+9.5: 56
Is a valid statement. Wherever data types are mixed in an expression, C++ performs the
conversions automatically. This process is known as implicit or automatic conversion.
Whenever the compiler encounters an expression, it divides the expressions into sub-
expressions consisting of one operator and one or two operands. For a binary operator, if the
operands type differ, the compiler converts one of them to match with the other using a certain
rule. The rule is that the "smaller" type is converted to the "wider" type. The "waterfall" model
show below illustrates this rule. For example, if one of the operand is an int and the other is a
float, the int is converted into a float because a float is wider than an int.
44
Whenever a char or short int appears in an expression, it is converted to an int. this is called
integral widening conversion. The implicit conversion is applied only after completing all integral
widening conversions.
1. Operator Overloading
The input/output operators «and» are good examples of operator overloading. Although the built-
in definition of the << operator is for shifting of bits, it is also used for displaying the values of
various data types. This has been made possible by the header file iostream.h where a number
of overloading definitions for << are included. Thus the statement
45
cout<<56.78; invokes the definition for displaying a double type value and
cout<<"very good morning"; invokes the definition for displaying a char type Value. R
Remember, none of these definitions in iostream.h affect the built-in meaning of the operator.
Similarly, we can define additional meanings to other C++ operators. For example, we can
define + operator to add two structures or objects. Almost all C++ operators can be overloaded
with a few exceptions such as the member-access operators (.and.*), conditional operator(?:),
scope resolutions operator(::) and the size operator (sizeof).
2. Operator Precedence
Although C++ enables us to add multiple meanings to the operators, their association and
precedence remain the same. For example, the multiplication operator will continue having
higher precedence than the add operator. The following table gives the precedence and
associativity of all the C++ operators. The groups are listed in the order of decreasing precedence.
Note that the labels prefix and postfix distinguish the uses of ++ and --. Also, the symbols +, - *,
and & are used as both unary and binary operators. "The unary operations assume higher
precedence.
Operator Associativity
:: Left to right
- - -! unary+unary -Unary *
+- left to right
== != left to right
^ left to right
| left to right
|| left to right
?: left to right
The following diagram show how these structures are implemented using one-entry, one-exit
concept, a popular approach used in modular programming.
It is important to understand that all program processing can be coded by using only these three
logic structures. The approach of using one or more of these basic control constructs in
programming is know as structure programming and important techniques in software
engineering.
Using these three basic constructs, we may represent a function structure either in detail or in
summary form as show in the following figure.
Like C, C++ also supports all the three basic control structures and implements them using
various control statements as show in the following figure. This shows that C++ combines the
power of structured programming with the object-oriented paradigm.
The if statement
1. Simple if statement
2. if....else statement
Figure 4.3
Examples
Form1
If(Expression is true)
{
action 1;
}
action 2;
action 3;
Form2
If(expression is true)
{
action 1;
}
else
50
{
action 2;
}
action 3;
Switch(expression)
case1:
action1;
case2:
action2;
case3:
action3;
default:
{
51
action4;
action5;
The do-while is an exit-controlled loop. Based on a conditions, the control is transferred back to
a particular point in the program. The syntax is as follows:
do
action1;
while(condition is true);
action2;
This is also a loop structure, but is an entry-controlled one. The syntax is as follows:
While(conditions is true)
action1;
action2;
The for is an entry-enrolled loop and is used when an action is to be repeated for a predetermined
number of times. The syntax is as follows:
52
For(initial value;test;increment)
action1;
action2;
4.6 Pointers
A Pointer is a variable that holds a memory address. This address is the location of another
object(typically another variable) in memory. For example, if one variable contains the address
of another variable, the first variable is said to point to the second. The following figure illustrates
the situation.
1) Pointer Variables
A pointer declaration consists of a base type, an*, and the variable name. The general form for
declaring a pointer variable is
53
Type *name;
Type-> base type of the pointer and may be any valid type.
The base type of pointer defines what type of variable the pointer can point to. Any type of pointer
can point anywhere in memory.
& -> is a Unary operator that returns the memory address of its operand. A unary operator
requires one operand. 21969 A
For example
M = &count;
places into m the memory address of the variable count. This address is the computer's internal
location of the variable. It has nothing to do with the value of count. You can think of & as returning
"the address of". The preceding assignment statement means "m receives the address of count".
To understand the above assignment better, assume that the variable count uses memory location
2000 to store its value. Also assume the count has a value of 100. Then, after the preceding
assignment, m will have the value 2000.
The second pointer operator, *, is the complement of &. It is a unary operator that returns the
value located at the address that follows. For example, if m contains the memory address of the
variable count
Q = *m;
places the value of count into q; Thus, q will have the value 100 because 100 is stored at
location 2000, which is the memory address that was stored in m. You can think of* as "at
address." In this case, the preceding statement means" q receives the value at address m."
Both & and * have a higher precedence than all other arithmetic operators except the unary
minus, with which they are equal.
54
3) Pointer Expressions
Pointer expressions conform to the same rules as other expressions. This section examines a
few special aspects of pointer expressions.
4) Pointer Assignments
As with any variable, you may a pointer on the right-hand side of an assignment statement to
assign its value to another pointer. For example,
#include<stdio.h>
int main(void)
int x;
p1 = &x;
p2 = p1;
return 0;
Both p1 and p2 now point to x. The address of x displayed by using the %p printf() to display an
address in the format used by the host computer.
5) Pointer Arithmetic
There are only two arithmetic operations that you may use pointers: additions and subtraction.
The understand what occurs in pointer arithmetic, let p1 be an integer pointer with a current
value of 2000. Also, assume integers are 2 bytes long.
p1 contains 2002, not 2001. The reason for this is that each time p1 is incremented, it will point
to the next integer. The same is true of decrements. For example, assuming that p1 has the
value 2000,
Each time a pointer is incremented, it points to the memory location of the next element of its
baste type. Each time it is decremented, it points to the location of the previous element. When
applied to character pointers, this will appear as "normal" arithmetic because characters are
always 1 byte long. All other pointers will increase or decrease by the length of the data type they
point to. This approach ensure that a pointer is always pointing to an appropriate element of its
base type. The following figure illustrates this concept.
You are not limited to the increment and decrement operators. For example, you may add or
subtract integers to or from pointers. The expression p1=p1+12;
Besides addition and subtraction of a pointer and an integer, only one other arithmetic operation
is allowed: You may subtract one pointer from another in order to find the number of objects of
their base type that separate the two. All other arithmetic operations are prohibited. Specifically,
you may not multiply or divide pointers; you may not add two pointers; you may not apply the
bitwise operators to them; and you may not add or subtract type float or double to or from
pointers.
Char*ch 3000;
Int *i=3000;
56
6) Pointer comparisons
You can compare two pointers in a relational expression. For instance, given two pointers p and
q, the following statement is perfectly valid
Generally, pointer comparison are used when two or more pointers point to a common object,
such as an array. As an example, a pair of stack routines are developed that store and retrieve
values. A stack is a list that uses first-in, last-out accessing. It is often compared to a stack of
plates on a table - the first one set down is the last one to be used. Stacks are used frequently in
compilers, interpreters, spreadsheets, and other system-related software.
The push() function places values on the stack and pop() take them off. These routines are
shown here with a simple main() function to drive t them. The program puts the values you enter
in to the stack. If your enter 0, a values is popped from the stack. To stop the program, enter -1.
#include<stdio.h>
#include<stdio.h>
57
#define SIZE 50
int pop(void);
int main(void)
int value;
do
printf("Enter value;")
scanf*%d" &value);
while(value !=-1);
return 0;
void push(int I)
p1++;
{
58
printf("Stack overflow.\n");
exit(1);
*p1=1;
int pop(void)
if(p1 == tos) {
printf("stack underflow.\n");
exit(1);
p1-;
return *(p1+1);
You can see that memory for the stack is provided by the array stack. The pointer p1 is set to
point to the first element ins stack. The p1 variable accesses the stack. The variable tos holds
the memory address of the top of the stack. It is used to prevent stack overflows and underflows.
Once the stack has been initialized, push() and pop() may be used. Both the push() and pop()
functions perform a relational test on the pointer p1 to detect limit errors. In push(), p1 is tested
against the end of stack by adding SIZE (the size of the stack) to tos. This prevents an overflow.
In pop(), p1 is checked against tos to be sure that a stack underflow has not occurred.
In pop(), the parentheses are necessary in the return statement. Without them, the statement
would look like this: this!
return *p1 + 1;
which would return the value at location p1 plus one, not the value of the location p1+1.
59
1. Pointer Arithmetic
2. Aray Indexing
The two versions of putstr()-one with array indexingt and one with pointers illustrate how you
can use pointers in place of array indexing. The putstr() function writes a string to the standard
out put device one character at a time.
/* Index s as an array. */
register int t;
/* Access s as a pointer.*/
8) Arrays of Pointers
Pesu Pointers may be arrayed like any other data type. The declaration for an int pointer array of
size 10 is
Int *x[10];
To assign the address of an integer variable called var to the third element of the pointer array,
ere dit on!
If you want to pass an array of pointers into a function, you can use the same method that you
use to pass other arrays-simply call the function with the array name without any indexes. For
example, a function that can receive array x looks like this:
int t;
printf("%d", *q[t]);
Remember, q is not a pointer to integers, but rather a pointer to an array of pointers to integers.
Therefore you need to declare the parameter q as an array of integer pointers, as just shown.
You cannot declare q simply as an integer pointer because that is not what it is.
Pointer arrays are often used to hold pointers to strings. You can create a function that outputs
an error message given its code number, as show here: laboM CAF
"Read Error\n",
"Write Error\n"
};
printf("%s", err[num]);
}
61
The array err holds pointers to each string. As you can see, printf() inside syntax_error() is
called with a character pointer that points to one of the various error messages indexed by the
error number passed to this functions.
4.7 Summary
An expression is a combine of operators, constration and variables arrangee as per the rules of
the language. And the pointer is a variable that holds memory address.
3) Define Pointers
4) Define Expressions
62
LESSON - 5
FUNCTIONS AND FUNCTION PROTOTYPES
Structure
5.1 Introduction
5.7 Summary
5.1 Introduction
A function a groups a number of program statements into a single unit and gives it a name. This
unit can be called from other part of the program. The purpose of using function is to reduce the
size of the program. The repeated set of statements can be defined ass a function and the user
can call the function any number of times, anywhere from the program.
• Definition of function
• Inline functions
1) Function Declaration
The first step is to tell the compiler what the function is. The variables are declared before using
it, IN the same manner the function also declared before calling. The function declaration gives
the instruction to the compiler that the function body comes later.
2) Function Definition
The function definition contain actual coding of the function. The function body start with declarator,
followed by the function body. The function body should be enclosed within curly braces. The
body may contain local variables. Also.
Local declarations;
.........................................
.........................................
return <expression>;
The return statement is used to terminate function and return a value to its caller. The function
may or may not return value. Without returning value this statement may also used to exit from
a function. This statement may or may not include an expression. The general form of return is
return; or return<expression>;
64
3) Function prototyping
In c++ all functions must be declared before they are used. This is normally accomplished
using a function prototype. Function prototypes were not part of the original C language. They
were, however, added when C was standardized. While prototypes are not technically required
by standard C, their use is strongly encouraged. Prototypes have always been required by c++.
In this book, all examples include full function prototypes.
Prototypes enable both C and C++ to provide stronger type checking, somewhat like that provided
by languages such as pascal. When you use prototypes, the compiler can find and report any
illegal type conversions between the type of arguments used to call a function and the type
definition of its parameters. The compiler will also catch differences between the number of
arguments used to call a function and the number of parameters in the function.
Type(parm_nameN);
The use of parameter names is optional. However, they enable the compiler to identify and type
mismatches by name when an error occurs, so it is a good idea to include them.
The following program illustrates the value of a function prototypes. It produces an error message
because it contains an attempt to call sqr_it() with an integer argument instead of the integer
pointer requied. (it is illegal to convert an integer into a poiner).
int main(void)
int x;
x = 10;
return 0;
*| = *| **|;
a function's definition can also serve as its prototypes if the definition occurs prior to the function's
first use in the program. For example, this is a valid program.
#include<stdio.h>
printf("%d", a % b);
int main(void)
f(10,3);
return 0;
in this example, since f() is defined prior to its used in main(), no separate prototypes is required.
The only function that does not require a prototype is main(), since it is the first function called
when your program begins. Function prototype help you trap bugs before they occur. In addition,
they help verify that your program is working correctly by not allowing functions to be called with
mismatched arguments.
66
4) Function Arguments
If a function is to use arguments, it must declare variables that accept the values of the arguments.
These variables are called the formal parameters of the function. They behave like other local
variables inside the function and are created upon entry into the function and destroyed upon
exit. As shown in the following function, the parameter declarations occur after the function
name:
while(*s)
if(*s==c) return 1;
else s++;
return 0;
The function is_in () has two parameters: s and c. This function returns 1 if the character c is
part of
As with local variables, you may make assignments to a function's formal parameters or use
them in an expression. Event thought these variables perform the special task of receiving the
value of the arguments passed to the function, you can use them as you do any other local
variable. nemuge art to enlevert to you attendmema
In a computer language, there are two ways that arguments can be passed to a subroutine. The
first is known as call by value. This method copies the value of an argument into the formal
parameter of the subroutine. In this case, changes made to the parameter have no effect on the
argument.
67
Call by reference is the second way of passing arguments to a subroutine. In this method, the
address of an argument is copied Into the parameter. Inside the subroutine, the address is
used, to access the actual argument used in the call. This means that changes made to the
parameter affect the argument.
#incude<stdl.h>
int main(void)
int t=10;
return 0;
X=X*X;
return(x);
In the above example, the value of the argument to sqr(), 10 is copied into the parameter x.
When the assignment x=x*x takes place, only the local variable x is modified. The variable t,
used to call sqr(), still has the value. Hence, the output is 100 10.
Remember that is a copy of the value of the argument that is passed into the function. What
occurs inside the function has no effect on the variable used in the call.
68
Though we use call by value for passing parameters, we can create a call by reference by
passing a pointer to an argument, instead of the argument itself. Since the address of the argument
is passed to the function, code within the function can change the value of the argument outside
the function.
Pointers are passed to functions just like any other value. Of course, you need to declare the
parameters as pointer types. For example, the function swap(), which exchanges the values of
the two integer variables pointed to by its arguments, shows how.
int temp;
x = y; /* put y into x */
swap() is able to exchange the value of the tow variable pointed to by x and y because their
addresses (not their values) are passed. Thus, within the function, the contents of the variables
can be accessed using standard pointer operations, and the contents of the variables used to
call the function are swapped.
Remember that swap() (or any other function that uses pointer parameters) must be called with
the addresses of the arguments. The following program shows the correct way to call swap();
Int main(void)
int l,j;
| = 20;
69
j = 30;
return 0;
In this example, the variable I is assigned the value 20 and j is assigned the value 30. Then
swap() is called with the addresses of i and j. Therefore, the addresses of i and j are passed into
the function
swap()
Inline Functions
1. _____________is a number of program statements into a single unit and gives it a name.
One solution to this problem is to use macro definitions, popularly known as macros. Pre-
processor macros are popular in C. The major drawback with macros is that they are not really
functions and therefore, the usual error checking does not occur during compilation.
C++ has a different solution to this problem. To eliminate the cost of calls to small functions,
C++ proposes a new feature called inline function. An inline function is a function that is expanded
in line.
When it is invoke. That is, the compiler replaces the function call with the corresponding
70
function code (something similar to macros expansion). The inline functions are defined as
follows:
inline function-header
function body)
Example
return (a*a*a);
c = cube(3.0);
d = cube(2.5+ 1.5);
On the execution of these statements, the value of c and d will be 27 and 64 respectively. If the
arguments are expression such as 2.5+1.5, the function passes the alue of the expression, 4 in
this case. This makes the inline feature far superior to macros.
It is easy to make a function inline. All we need to do is to prefix the keyword inline tothe function
definition. All inline functions must be defined before they are called.
We should exercise care before making a function inline. The speed benefits of inline functions
diminish as the function grows in size. At some point the overhed of the function call becomes
small compared to the execution of the function, and the benefits of inline functions may be lost.
In such cases, the use of normal functions will be more meaningful. Usually, the functions are
made inline when they are small enough to be defined in one or two lines.
Remember that the inline keyword merely sends a request, not a command, to the compiler.
The compiler may ignore this request if the function definition is too long or too complicated and
compile the function as a normal function.
Some of the situation where inline expansion may not work are:
Note: Inline expansion makes a program run faster because the over head of a function call and
return is eliminated. However, it makes the program to take up more memory because the
statements that define the inline function are reproduced at each point where the function is
called. So, a trade-off becomes necessary.
#include<iostream.h>
#include<stdio.h>
return (x * y)
FUNCTION
return(p/q);
}
72
main()
float a = 12.345;
float b = 9.82;
cout<<mul(a,b)<<"\n;
cout<<div(a;b)<<"\n";
To make an outside function friendly to a class, we have to simply declare this function as a
friend of the class as shown below:
Class ABC
....................
....................
public:
....................
....................
};
73
The function declaration should be preceded by the keyword friend. The function is defined
elsewhere in the program like a normal C++ function. The function that are declared with the
keyword friend are known as friend functions.
• It is not in the scope of the class to which it has been declared as friend.
• Since it is not in the scope of the class, it cannot be called using the object of that class.
It can be invoked like a normal function without the help of any object.
• Unlike member functions, it cannot access the member names directly and has to use
an object name and dot membership operator with each member name. (e.g.A.x).
• It can be developed either in the public or the private part of a class without effecting its
meaning.
#include<iostream.h>
class sample
int a;
int b;
public:
};
float mean(sample s)
{
74
main()
sample X; //object X
X.setvalue();
The output of the above program will be Mean value: 32.5 nm for eldsne
Note that the friend function accesses the class variables a and b by using the dot operator and
the object passed to it. The function call mean (X) passes the object X by value to the friend
function.
Member functions of one class can be friend functions of another class. In such cases, they are
defined using the scope resolution operator as shown below:
Class X:
....................
....................
....................
};
class Y
{
75
....................
....................
//is friend of Y
....................
};
We can also declare all the member functions of one class as the friend functions of another
class. In such cases, the class is called a friend class. This can be specified as follows:
Class Z
....................
};
#include<iostream.h>
class Base
76
public:
};
public
main()
Bptr=&B;
Bptr = &D;
}
77
Display base
Show base
Display base
Show derived
Note that when bptr is made to point to the object D, the statement
Bptr ->display();
Calls only the function associated with the Base(i.e. Base :: display()) where as the
statement
Bptr ->display();
Calls Derived version of show(). This is because the function display() has not been made
virtual in the Base class.
One important point to remember is that, we must access virtual functions through the use of a
pointer declared as a pointer to the base class. Why can't we use the object name (with the dot
operator) the same way as any other member function to call the virtual functions? We can, but
remember, runtime polymorphism is achieved only when a virtual function is accessed through
a pointer to the base class.
Let us take an example where virtual functions are implemented in practice. Consider a book
shop which sells both books and video-tapes. We can create a class know as media that stores
the title and price of a publications. We can then create two derived classes, one for storing the
number of pages in a book and another for storing the playing time of a tape.
The following figure shows the class hierarchy for the book shop.
78
The classes are implemented in the following program. A function display() is used in all the
classes to display the class contents. Notice that the function display() has been declared virtual
in media, the base class.
In the main program we create a heterogeneous list of pointers of type media as shown below:
The base pointers list[0] and list[1] are intialised with the addresses of objects book1 and tape1
respectively.
#include<iostream.h>
#include<string.h>
class media
protected:
char title[50];
float price;
public:
strcopy(title, s);
price = a;
function
};
int pages;
public:
pages = p;
};
float time;
public:
{time = t; }
void display()
};
cout<<"\n Title:"<<<title;
cout<<"\n pages:<<pages;
cout<<"\n price:<<price;
main()
char *title;
int pages;
Media * list[2];
List[0]= &book1;
List[1] = &tape1;
Cout<<"\n.............BOOK..............";
Cout<<"\n.............TAPE...
Title: Programming_in_ANSI_C
Price: 88
Pages: 400
Title: Computing_Concepts
Price: 90
Play time(mins): 55
MEDIA DETAILS
.................BOOK..............
82
Title: Programming_in_ANSI_C
Page: 400
Price: 88
.............TAPE................
Title: Computing_Concepts
Price: 90
When virtual functions are created for implementing late binding, we should observe some
basic rules that satisfy compiler requirements:
5. A virtual function in a base class must be defined, even though it may not be used.
6. The prototypes of the base class version of a virtual function and all the derived class
versions must be identical. If two functions with the same name have different prototype,
C++ considers them as overloaded functions, and the virtual function mechanism is
ignore.
8. While a base pointer can point to any tape of the derived object, the reverse is not true.
That is, we cannot use a pointer to a derived class to access an object of the base type.
9. When a base pointer points to a derived class, incrementing or decrementing it will not
make it to point to the next object of the derived class. It is incremented or decremented
83
only relative to its base type. Therefore, we should not use this method to move the
pointer to the next object.
10. If a virtual function is defined in the base class, it need not be necessarily redefined in the
derived class. In such cases, call with invoke the base function.
1. _____________function has access to all private and protected member of the class for
which it is a friend.
5.7 Summary
In this lesson we have covered functions, Inline functions, friend function and virtual functions.
And also we discussed about rules for forming the virtual functions.
II 1) Friend
2) member
LESSON - 6
CLASSES AND OBJECTS
Structure
6.1 Introduction
6.6 Summary
6.1 Introduction
Objects are the basic run time entities in an object-oriented system. Objects contain data and
code to manipulate that data. The entire set of data and code of an object can be made a user-
defined data type with the help of a class.
first part of the program. Later, in main(), we define two objects s1 an s2 that are instances of
that class.
Each of the two objects is given a value, and each displays its value. Here's the output of the
program:
Data is 143
Data is 1343
We'll begin by looking in detail at the first part of the program-the declaration for the class smallobj.
Later we'll focus on what main() does with objects of this class.
1) A Simple Class
The first program contains a class and two objects of that class. Although it's simple, the program
demonstrates the syntax and general features of Classes in C++. Here's the listing for the
SMALLOBJ program:
//smallobj.cpp
#include<iostream.h>
Class smallobj
Private:
Int somedata;
Public:
Void setdata(int d)
somedata=d;
86
void showdata()
cout<<"Data is"<<somedata<<endl;
};
int main()
smallobjc s1,s2;
s1.setdata(143);
s2.setdata(1343);
s1.showdata();
s2.showdata();
return 0;
The Class SMALLOBJ declared in this program contains one data item and two member
functions. The two member functions provide the only access to the data item from outside
class. The first member function sets the data item to a value, and the second displays the
value. Placing data and function and together into a single entity is the central idea of object
oriented programming.
Here's the declaration for the class smallobj, copied from the SMALLOBJC listing:
87
Class smallobj
Private:
Int somedata;
Public:
Void setdata(int d)
somedata=d;
Void showdata()
cout<<"Data is <<somedata<<endl;
};
The declaration starts with the keyword Class, followed by the class name-smallobj in this
example. Like a structure, the body of the class is delimited by brace and terminated by a
semicolon. stil teril tedmeme? dolleme zelo to Sale todo o contad
The body of the class contains two unfamiliar keywords: Private and Public. A key feature of
OOP is data hiding. This term does not refer to the activities of particularly paranoid programmers;
rather it means that data is concealed within a class, so that it cannot be accessed mistakenly
by functions outside the class. The primary mechanism for hiding data is to put it in a class and
make it private. Private data or functions can only be accessed from within the class. Public
data or functions, on the other hand, are accessible from outside the class.
88
Data hiding, on the other hand, means hiding data from parts of the program that don't need to
access it. More specifically, one class's data is hidden from other classes. Data hiding is designed
to protect well-intentioned programmers from honest mistakes. Programmers who really want
to figure out a way to access private data, but they will find it hard to do so by accident.
Usually the data within a class is private and the functions are public. This is a result of how
classes are used. The data is hidden so t will be safe from accidental manipulation, while the
function operate on the data are public so they can be accessed from outside the class.
Now that the class is declared, let's see how main() makes use of it. We'll see how objects are
defined, and, once defined, how their member functions are accessed.
7) Defining objects
Smallobj s1,s2;
Defines two objects s1,s2 of class smallobj. Remember that the declaration for the class smallobj
doesn't create any objects. It only describes how they will look when they are created, just as a
structure declaration describes how a structure will look but doesn't create any structure
variables.
Defining objects in this way means creating them. This is also called instantiating them. The
term instantiating arises because an instance of the class is created. An object 'is an instance
of the class. Objects are sometimes called as instance variables.
The next two statements in main() call the member functions setdata():
S1.setdata(143);
S2.setdata(1343);
89
These statements don't look like normal functions calls. Why are object names s1 and s2
connected to the function names with a period? This strange syntax is used to call a member
function that is associated with a specific object. Because setdata() is a member function of the
smallobj class, it must always be called in connection with an object of this class.
S1.setdata(143);
Executes the setdata() member function of the s1 object. This function sets the variable some
data in object s1 to the value 143.
S2.setdata(1343);
Similarly, the following two calls to the showdata() function will cause the two objects to display
their values:
S1.showdata();
S2.showdata();
In many programming situations, objects in programs represent physical objects: things that
can be felt or seen. These situations provide vivid examples of the correspondence between the
program and the real world.
Circles as objects
The program creates three circles with various characteristics and displays them. Here's the
listing of CIRCLES
//circle.cpp
#include "msoftcon.h"
90
Class circle
Protected:
Int xco,yco;
Int radius;
Color fillcolor;
Fstyle fillstyle;
Public:
XCOEX;
yco=y;
raidus=r;
fillcolor=fc;
fillstyle=fs;
void draw()
set_color(fillcolor);
set_fill_style(fillstyle);
draw_circle(xco,yco,radius);
}
91
};
int main()
init_graphics();
circle c1;
circle c2;
circle c3;
c1.set(15,7,5,Cblue,X_FILL); da
c2.set(41,12,7,CRED,O_FILL);
c3.set(65,18,4,cGREEN,MEDIUM_FILL);
c1.draw();
c2.draw();
c3.draw();
set_cursor_post(1,25);
return 0;
#include<iostream.h>
Class item
int number;
float cost;
92
public:
void putdata(void)
cout<<"Number:"<<number<<endl;
cout<<"Cost:"<<cost<<endl;
};
number=a;
cost-b;
main()
item x;
x.getdata(100,200.25);
x.putdata();
item y;
y.getdata(200,300.25;
93
y.putdata();
Output:
Object x
Number:100
Cost:200.25
Object y
Number:200
Cost:300.25
The program features the class item. This class contains two private variables and two public
functions. The member function getdata(), which has been, defined outside the class supplies
values to both the variable. Note the use of statement such as
Number=a;
In the function definition of getdata(). This shows that a member functions can have direct
access to the private data items.
The member function putdata() has been defined inside the class and behaves therefore as an
inline function. This function displays the values of the private variable number and cost. The
program creates two objects x and y in to different statements. This can be combined in one
statement, Item x,y;
One of the objectives of the Oop is to separate the details of implementation from the class
definitions. It is therefore good practice to define the member functions outside the class. We
can define a member function outside the class and still make it inlined by just using the qualifier
INLINE in the header line of the function definition.
94
Example
Class item
Public:
};
number=x;
cost=y;
Although it is normal practice to place all data items in a private section and all member functions
in public, some situations may require certain functions to be hidden from outside calls. Like,
deleting an account number in a customer file. Such functions are placed in private sections.
Private member functions can only be called by another function that is a member of its class.
Even an object cannot invoke a private function using the dot operator. Consider the class as
defined below:
Class sample
int m;
void read(void);
Public:
95
Void modify(void);
Void print(void);
};
s1.read();
is illegal. However, the function read can be called by the function modify() to modify the value of
m.
void sample::modify(void);
read();
2. The body of the class contains two unfamiliar keywords. There are___________
lo sedme If you have nested local scopes, the scope resolution operation doesn't provide access
to variables in the next outermost scope. It provides access to only the global variables.
Example
#include(iostream.h>
int amount=100;
void main()
96
int amount=200;
cout<<::amout;
cout<<endl;
cout<<amout;
The example has two variables named amount. The first is global and contains the value 100.
The second is local to the main. The two colons tell the compiler to use the global variables
value rather a local.
Output
100
200
A data member of a class can be qualified as static. The properties of a static member variable
are similar to that of a C static variable. A static member variable has certain special
characteristics.
It is initialized to zero when the first object of its class is created. No other initialization is permitted.
Only one copy of that member is created for the entire class and is shared by all the objects of
that class, no matter how many objects are created.
It is visible only within the class but its lifetime is the entire program.
#include<iostream.h>
class value
int number;
public:
void getdata(int x)
number=x;
count++;
Void getcount(void)
cout<,"Count:";
cout<<count<<end1;
};
int value::count;
main()
value a,b,c;
a.getcount();
b.getcount();
c.getcount();
a.getdata(111);
a.getdata(222);
98
a.getdata(333);
a.getcount();
b.getcount();
c.getcount();
return 0;
Output:
Count: 0
Count: 0
Count: 0
Count: 3
Count: 3
Count: 3
The static variable count is initialized to zero when the objects are created. The count is
incremented whenever the data is read into an object. Since the data is read into the object
three times, the variable count is incremented three times. Because there is only one copy of
count shared by all.
Like static member variables, we can also have member functions. A static member function
has the following properties:
A static member can have access to only other static members declared in the same class.
99
Class-name:: function-name;
#include<iostream.h>
class exam
int code;
public:
void setcode(void)
code= ++count;
void showcode(void)
cout<<"object number:"<<code<<end1;
cout<<"count"<<count<<end1;
};
int exam::count;
100
main()
exam s1,s2;
s1.setcode();
s2.setcode();
exam::showcount();
exam s3;
s2.setcode();
exam::showcount();
exam s3;
s2.setcode();
exam::showcount();
s1.showcode();
s2.showcode():
s3.showcode();
return;
Output:
Count: 2
Count: 3
Object number: 1
Object number: 2
Object number: 3
101
The above program illustrates the implementation of static member function. The static function
showcount() displays the number of objects created till that moment. A count of number of
objects created is maintained by the static variable count.
Code=++count;
Is executed whenever setcode() function is invoked and the current value of count is assigned
to code.
3) Arrays of Object
An array can be any data type. An array of variable of type class are called array of objects.
Consider the following definition,
Class emp
Char name[20];
Float age;
Public:
Void get(void);
Void put(void);
};
void emp::get(void)
cout<<"Enter name";
cin>>name;
cout<<"Enter name";
cin>>age;
102
void emp::put(void)
cout<<"Name:"<<name<<end1;
cout<<"Age:"<<age<<end1;
main()
emp manager[size];
manager(1).get();
cout<<end1;
cout<<"\n Manager"<<1+1<<endl;
manager[1].put();
return 0;
103
It is not in the scope of the class to which it has been declared as friend.
Since it is not in the scope of the class, it cannot be called using the object of that class. It can
be invoked as normal function without the help of any object.
Unlike member functions, it cannot access the member name directly and has to use an object
name and a dot membership operator with member name.
It can be declared in public or private part of a class without affecting its meaning.
#include<io.stream.h>
Class sample
int x;
int y;
Public:
Void enter()
x=20;
y=30;
104
};
return float(sam.x+sam.y)/2.0;
main()
sample x;
x.enter();
cout<<"Mean Value="<<mean(x)<<endl;
return 0;
Output:
if noanal If a member function does not alter any data in the class, then we may declare it as a
const member function as follows:
The qualifier constant is appended to the function prototype. The compiler will generate an error
message if such function tries to alter the data values.
105
6.6 Summary
In this lesson we have covered objects and classes. And also we have discussed about scope
resolution operator and friend function.
5. What is a friend function? What are the merits and demerits of using a friend function?
106
LESSON - 7
CONSTRUCTOR AND DESTRUCTORS
Structure
7.1 Introduction
7.3 Constructor
7.5 Destructors
7.6 Summary
7.1 Introduction
The process of initializing objects created from C++ classes is much more involved than initializing
variables in c. Objects are designed to be more general purpose than c variables; Therefore we
need to develop techniques for Encapsulating initialization code and here come Constructors
and Destructors.
• Constructor
• This Pointer
• Destructor
7.3 Constructor
C++ variable is the ability to have a special user-defined initialization routine attached to it.
Including a special member function called a constructor function in the class to which the
variable belongs does this. A constructor can do a variety of things, like initialize internal variables,
allocate dynamic memory and so on.
107
A class can also have a corresponding Destructor function. This function is called when the
program execution leaves the scope of a class variable. It can also do a variety of housekeeping
tasks and typically is used to free dynamically allocated memory associated with the variable.
1) Constructor functions
Any member function that has the same name as the class itself is treated as a Constructor
function. This function enables an object to initialize itself when created. The Constructor is
invoked whenever an object of its associated class is created. It is called Constructor because
it constructs the value of data numbers of the class, balso ad feur
Class integer
int m,n;
Public:
Integer(void);
................
................
};
integer::integer(void)
m=0;n=0;
When a class contains a Constructor like the one defined above, it is guaranteed that an object
created by the class will be initialized automatically.
108
Restrictions
Constructors cannot be friend functions and they cannot be virtual. Destructor, however can be
virtual.
Member objects can have Constructors, but if they do, the member objects Constructor must
be called first.
Unions can have Constructors and Destructors. However, members of unions cannot.
Objects that will be stored in arrays must have either a Constructor that does not use arguments
or no Constructor at all.
2) Overloading Constructors
A Constructor can be overloaded like any other C++ function. This feature allows us to provide
several versions of Constructor for a single class. Each version can have different number of
types of arguments. This technique is useful for object that have more than one kind of external
representation. For example, you might want to use hours, minutes and seconds.
#include<iostream.h>
Class clock
long data;
Public:
Clock(long s)
{
109
data=s;
Void display(void);
};
data=(long_h*3600+m*60+s:
h=data/3600;
s=data-h*3600;
s=s/60;
s=m*60;
void clock::display(void)
int hr,min,sec;
hms(hr,min,sec);
printf("%02d:%02d:%02d\n",hr,min,sec);
110
void main()
titan.display();
rado.display();
Output
13:55:46
03:25:45
Class members can be user-defined types as well as basic types. If such as member also has
Constructor, the Constructor must be called before the enclosing classes Constructor. If the
member has a Constructor that does not use arguments, this call is easily made. What happens
if the constructor requires argument? How they are passed? The following code shows how:
Class gallery
Public:
Image &picture_of_my_dog;
Image Picasso;
Image vangogh;
Gallery(image *I); };
};
111
gallery::gallery(image *I)
:Picasso(640,440);
vangogh(300,200)
picture_of_my_dog=l;
The members Picasso and vangogh are initialized by placing calls to their Constructors directly
after the colon. The calls come immediately after the Constructor parameter list and before the
opening brace. Note how we call the member Constructor by using the object names. The
arguments are supplied just as they are in a standard Constructor call. Because we declare the
auxiliary member picture_of_my_dog as a pointer, we did not have to call a Constructor for it.
Constructors can be used to initialize unions. This class definition provides an example:
Union node_elem
list &next;
int data;
node_elem(list *n)
next=n;
node_elem(int d)
data=d;
}
112
The trick here is to make sure that the compiler knows which member of the union to initialize.
In this case, we used two Constructors, one for each type of member, unlike structure, has a
restriction on the kind of members it can have.
Constructors and Destructors provide a powerful and convenient method for initializing and
destroying the objects. However, like and powerful tool, they can be misused. You will want to
know when they are actually called so that you can use them properly. Here are different life
spans and object can have:
Automatic objects: These are objects local to a function and as such are stored on the stack.
They exist for the duration of a function.
Static Objects: These are objects declared outside of a function. They are created when the
program begins and exists for the duration of the program.
Dynamic Objects: Theses are objects residing on the heap. They are created using new and
destroyed using delete.
Unnamed objects: These are objects created temporarily to support and internal expression
calculation. Their life span is implementation-dependent.
Member objects: These are objects that are created and destroyed when the object to which
they belong is created and destroyed.
Derived class objects: These are objects created from a derived class. In this case, the base
class constructor is called first, before the derived class constructor.
Copy constructor: As we discussed, you can define and at the same time initialize an object
the value of another object with two kinds of statements:
Copy Constructors are Constructors that are used to copy objects. A default copy constructor,
which is provided automatically by the compiler for every object, performs a member-by-member
113
copy. This is similar to what the assignment operator does; the difference is that the copy
constructor also creates a new object.
Like the assignment operator, the copy constructor can be overloaded by the user
#include<iostream.h>
Class alpha
Private:
Int data;
Public:
Alpha()
{} //no-arg constructor
data=d;
data=a.data;
Void display()
114
cout<<data;
data=a.data;
};
Void main()
alpha a1(30);
alpha a2;
a2=a1;
cout<<"\n a2=";
a2.display();
alpha a3(a1);
cout<<"\n a3";
a3.display();
This program overload both the assignment operator and the copy constructor. The copy
constructor takes one argument an object of type alpha, passed by reference.
115
Output:
A2=30
A3=30
Alpha a3 (a1);
Alpha a3=a2
#include<iostream.h>
Class where
Private:
Char chararry[10];
Public:
Void reveal()
};
Void main()
where w1,w2,w3;
w1.reveal();
w2.reveal();
w3.reveal();
The main() program in this example creates three objects of type where. It then asks each
object to print its address, using the reveal () member function. This function prints out the value
of the pointer.
Output:
Since the data in each object consists of an array of 10 bytes, the objects are spaced 10 bytes
apart in memory.
Function overloading, by writing two or more functions with the same name but with different
parameters. Class member functions can be overloaded as well, in much the same way.
The rectangle class, shown below, has two drawshape() function. One, which takes no
parameters, draws the rectangle based on the class's current values. The other takes two
values, width and length, and draws the rectangle based on those values, ignoring the current
class values.
117
#include<iostream.h>
Class rectangle
public:
//constructors
~rectangle()
const;
private:
USHORT itswidth;
USHORT itsheight;
};
//constructor implementation
itswidht=width;
itsheight=height;
}
118
drawshape(itswidht,itsheight);
cout<<"*";
cout<<"\n";
}}
int main()
rectangele therect(6,5);
cout>>"drawshape();\n";
119
therect.drawshape();
cout<<"\n drawshape(10,2):\n";
therect.drawshape(10,2);
33return 0;
Output:
Drawshape();
&&&&&&
&&&&&&
&&&&&&
&&&&&&
&&&&&&
drawshape(10,2):
&&&&&&&&&&&&
&&&&&&&&&&&&
The compiler decides which method to all based on the number and type of parameters entered.
One can imagine a third overloaded function named drawshape() that takes one dimension and
an enumeration for whether it is the width or height at the user's choice.
1. _____________ is a special member function whose task is to initialize the objects of its
class.
2. _______________Is a member function whose name is the same as the class name
but is preceded by a tide.
120
7.6 Summary
In this lesson we have covered constructor and Destructors. And also we have discussed about
this pointer and different types of constructors.
2) Destructors
3. What are copy constructor & when we have to overload the copy constructor?
LESSON - 8
OPERATION OVERLOADING
Structure
8.1 Introduction
8.6 Summary
8.1 Introduction
Operator overloading is one of the many exciting features of C++ languages. It is an important
technique that has enhanced the power of extensibility of C++. C++ tries to make the user
defined data types behave in much the same way as the built-in types. C++ permits to add two
variables to user-defined types with the same syntax that is applied to the basic types. The
mechanism of giving such special meaning to an operator is known as operator overloading.
• Operator overloading
• e Function overloading
122
• Conditional operator(?:).
• It is not possible to create new operators we can only overload the existing one
The meaning of how an operator works on objects of built-in types cannot be change by operator
overloading. The meaning of how + adds two integers cannot change.
To define an additional task to an operator. We must specify what it means in relation to the
class to which the operator is applied. This is done with the help of a special function called
operator function, which describes the task. The general form of an operator function is:
Function body
}
123
Where return type is the type of value returned by the specific operation and op is the operator
being overloaded. The op is preceded by the keyword operator, operator op is the function
name.
• First create a class that defines the data types that is to be used in the overloading
• operation. Declare the operator function function operator op() in the public part of the
class. It may be either a member function or a friend function.
Let us consider the unary minus operator. A minus operator, when used a a unary, takes just one
operand. We know that this operator changes the sign of an operand when applied to a basic
data item. How to overload this operator so that it can be applied to an object in much the same
way as is applied to an int or float variable. The unary minus when applied to an object should
change the sign of each of its data items.
#include<iostream.h>
class space
int x;
124
inty:
int z;
Public:
Void display(void);
y=b;
z=c;
Void space::display(void)
cout<<x<<" ";
cout<<<<" ";
cout<<<<<" ";
Void space::operator-()
x = -Z;
y = -y;
Z = -Z;
}
125
main()
space s;
cout<<":";
s.display();
cout<<":";
s.display();
-s;
Output
S: 100-200 300
S:-100 200-300
The function operator -()takes no argument. It changes the sign of data members of the object
S. Since this function is a member function of the same class, it can directly access the members
of the object which activated it.
A statement like
S2=-S1;
Will not work because the function operator-()does not return any value. It can work if the function
is modified to return an object.
{
126
S.X=S.X;
s.y=s.y;
S.Z=S.Z;
Argument is passed by reference. It will not work if we pass argument by value because only
copy of the object that activated the call is passed to operator-(). Therefore, the changes made
inside the operator function will not reflect in the called object.
How to add two complex numbers using a friend function.? A statement likes
C=sum(A,B);
Was used. The functional notation can be replaced by a natural looking expression
C=A=B;
//overloading + operator//
#include<iostream.h>
class complex
Public:
Complex()
{}
x=real;
y=imag;
void display(void);
};
complex temp;
temp.x=x+c.x;
temp.y=y+c.y;
return(temp);
void complex::display(void)
cout<<x<<"+j<<<<"\n";
main()
compelx c1,c2,c3;
c1 = complex(3.5,4.5);
c2 = complex(4.5,5.5);
c3 = c1+c2;
128
cout<<"C1=";
c1.display();
cout<<"C2=";
c2.display();
cout<<"C3=";
c3.display();
Output:
C1 = 3.5+j4.5
C2=4.4+j5.5
C3 = 8.0+j10.0
Complex temp;
Temp.x+c.x;
Temp.y=y+y.c;
Return(temp);
Friend functions may be used in the place of member function for overloading a binary operator.
The only difference being that a friend function requires two arguments to be explicitly passed to
it while a member function requires only one.
The complex number program discussed in the previous section can be modified using the
friend operator function as follows:
Replace the member function declaration by the friend function declaration. Friend complex
operator +(Complex, Complex); Redefine the operator function as follows:
return complex((a.x+b.x),(a.y+b.y));
C3=C1+C2;
Is equivalent to
In most cases, we will get the same results by the use of either friend function or a member
function.
class vector
int v[size];
Public:
130
Vector();
Vector(int * x);
}:
vector::vector()
v[1]=0;
vector::vector(int * x)
v[1]=x[1]
vector c;
c.v[I]=a*b.v[i];
131
return c;
vector c;
c.v[l]=b.v[l]*a;
return c;
din>>b.v[I];
return (din);
dout<<","<<b.v[!];
dout<<")";
return (dout);
}
132
int x[size]={3,6,9};
main()
vector m;
vector n=x;
cin>>m;
cout<<"\n";
cout<<"m="<<m<<"\n";
vector p,q;
p=2*m;
q=n*2;
cout<<"\n";
329
cout<<"p="<<p<<"\n";
cout<<"q="<<q<<<"\n";
Output:
246
m=(2,4,6)
133
p=(4,8,12)
q=(6,12,18)
Analysis:
Vector();
Vector m;
Creates a vector m and initializes all its elements to 0, the second constructor.
Vecor(int *x);
Creates a vector and copies the elements pointed to by the pointer argument x into it,
Int x[3]={3,6,9};
Vector n=x;
We have used vector variables like m and n in input and output statements just like simple
variables. This has been made possible by overloading the operator >> and << using the functions:
Istream and ostream are classes defined in the iostream.h file which has been included in the
program.
It is possible to overload new and delete. You might choose to do this if you want to use some
special allocation method. For example, you may want allocation routines that automatically
begin using disk file as virtual memory when the heap has been exhausted.
134
#include<iostream.h>
#include<stdlib.h>
class loc
Public:
loc();
longitude=lg;
latitude=lt;
Void show()
cout<<longitude<<" ";
331
cout<<latitude<<"\n";
};
return malloc(size);
free(p);
main() of hatua bi
loc p1,p2;
p1=new loc(10,20);dolny
if(!p1)
cout<<"Allocation error\n";
exit(1);
p2=new loc(-10,-20);
if(!p2)
136
exit(1);
p1->show();
p2->show();
delete p1;
delete p2;
return 0;
When new and delete are overloaded relative to a specific class, the use of these operators on
any other type of data causes the original new or delete to be employed.
Main drawbacks of string manipulations in C are that whenever a string is to be copied, the
programmer must first determine its length and allocate the required amount of memory. Although
these limitations exist in C++ as well, it permits us to create our new definitions of operators that
can be used to manipulate the strings very such similar to the decimal numbers
String3-string1+string2;
Strings can be defined as class objects, which can be then manipulated, like the build-in types.
Since the strings vary greatly in size, we can use the new to allocate the memory for each string
and a pointer variable to point to the string array. Thus we must create string objects that can
hold these two pieces of information, namely length and location, which are necessary for string
manipulations. A typical string class will look as follows:
137
#include<string.h>
#include<iostream.h>
class string
char *p;
int len;
Public:
String()
len=0;p=0;
~string()
delete p;
{
138
len=strlen(s);
p=new char[len+1];
strcpy(p,s);
len=s.len;
p=new char[len+1];
strcpy(p,s.p);
string temp;
temp.len-s.len+t.len;
temp.p=new char[temp.len+1];
strcpy(temp.p,s.p);
strcat(temp.p,t.p);
return(temp);
it m=strlen(s.p);
139
int n-strlen(t.p);
if(m<=n)
return(1)
else
return(0);
cout<<s.p;
main()
string s1="New";
string s2="York";
string s3="Delhi";
t1=s1;
t2=s2;
t3=s1+s2;
t4=s1+s3;
cout<<"\n t1=";
show(t1);
140
cout<<"\n t2";
show(t2)
cout<<"\n t3=";
show(13)
cout<<"\n t4=";
show(14)
cout<,\n n\";
if (t3<=14)
336
show(13);
Show(14);
Cout<<"\n";
else
show(14);
show(t3);
cout<<"\n";
141
Output:
T1=New
T2=York
T3-New York
T4-New Delhi
1. Conversion functions
The conversions from basic type to class is easy to accomplish. For example, a constructor
was used to build a vector object from int type array. Similarly we used another constructor to
build as string type object from a char* type variable.o poligno shy &
length=strlen(a);
Stripy (pea);
}
142
This constructor builds a string type object from a char *type variable a. The variable length and
P are data members of the class string. Once this constructor has been defined in the string
class, it can be used for conversion from char * type to string type.
Example
String s1,s2;
S1-string(name1);
S2=name2;
The statement
S1-string(name1);
First converts name1 from char * type to string type and then assign the string type values to the
object s2. The statement
S2=name2;
The constructors did a fine job in type conversion from basic to class type. The constructor
function does not support this operation. C++ allows us to define an overload casting operator
that could be used to convert a class type data to a basic type. General form of a casting
operator function usually referred to as conversion function is:
Operator typename()
...............................
...............................
}
143
This function converts a class type data to typename. For example, the operator double() converts
a class object to type double, the operator int() converts a class type object to type int, and so on
Vector::operator double()
Doube sum=0;
Sum=sum+v[I]*v[I];
Return sqrt(sum);
This function converts a vector t the corresponding scalar magnitude. The operator double()
can be used as follows:
Or
Double length=v1;
Where v1 is an object of type vector. Both the statement has exactly the same effect. When the
compiler encounters a statement that requires the conversion of class type to the basic type it
calls the casting operator function to do the job.
Let us consider an example of an inventory of products in the store. One way of recording the
details of the products is to record their code number, total items in the stock and the cost of
each item. Another approach is to just specify the item code and the value of item in the stock.
144
//data conversion///
#include<iostream.h>
class invent1
int code;
int items;
float price;
Public:
code=1;
item=b;
price=c;
void put()
cout<<"Code :"<<code<<endl;
cout<<"Items :"<<items<<endl;
cout<<"Price :"<<Price<<endl;
int getcode()
{
145
int getitems()
return items;
int getprice()
return price;
operator float()
return(items price);
class invent2
int code:
float value;
Public:
Invent2();
code=0;
146
value=0;
invent2(int x, float y)
code=x;
value=y;
void put()
cout<<"Code :"<<code<<endl;
cout<<"Value :"<<value<<endl;
invent2 (invent p)
code=p.get();
value=p.getitems() * p.getprice();
and if ther>"egid
main()
invent s1(100,10,200,0);
invent2 d1;
float total;
147
total=s1;
d1=s1;
s1.put();
cout<<"value="<<total<<"\n \n";
d1.put();
Output:
Code: 100
Items: 10
Value: 200
Stock value
Value: 2000
Code: 100
Value: 2000
Analysis
Operator float()
In the class invent1 to convert the invent1 type data to a float. The constructor
148
Invent2 (invent1)
Is used in the class invet2 to convert invent1 type data to the invent2 type data.
Operator Invent2()
In the class invent2 to convert invent1 type to invent2 type. However, it is important that we
do not use both the constructor and the casting operator for the same type conversion, as
this introduces an ambiguity as to how the conversion should be performed.
Int myfunction(long);
My cuntion() is overload with three different parameter lists. The first and second versions differ
in the type of the parameters, and the third differs in the number of parameters.
The return types can be the same or different on overloaded functions. You should note that two
functions with the same name and parameter list, but different return types, generate a compiler
error.
Function overloading is also called function polymorphism. Poly means many, and morph means
from: a polymorphic function is many_formed.
////function overloading///
#include<iostream.h>
int double();
long double(long);
float double();
149
int main()
int myint=6500;
long mylong-65000;
float myfloat-6.5f;
doube mydouble=6.5e20;
int doubledint;
long doubledlong;
float doubledfloat;
double doubledouble;
cout<<"Myint:"<,myint<<endl;
cout<<"Mylong:"<<,mylong<<endl;
cout<<"myfloat:"<,myfloat<<endl;
cout<<"mydouble:"<,mydouble<<endl;
doubledint=double(myint);
doubledlong-double(mylong);
doubledfloat-double(myfloat);
one doubleddouble-double(mydouble);
cout<<"Doubledint:"<<doubledint<<endl;
cout<<"Doubledlong:"<<doubled long<<endl;
cout<<"Doubledfloat:"<<doubled float<<endl;
cout<<"Doubleddouble:"<<doubleddouble<<endl;
150
return 0;
return2* original;
cout<<"InDouble(long) \n";
return 2 original;
cout<<"InDouble(float) \n";
return 2* original;
cout<<"InDouble(double) \n";
return 2* original;
Output:
Myint: 6500
151
Mylong:65000
Myfloat:6.5
Mydouble:6.5e+20
InDouble(int)
InDouble(long)
InDouble(float)
InDouble(double)
Doubledint:13000
Doublelong:130000 Doubledfloat:13
Doubledouble:1.3e+21
The double() function is overload with int, float and double. The prototypes and the definitions
are defined. In the body of the main program eight local variables are declared. Four of the
values are initialized; the other four are assigned the results of passing the first four to the
double() function. Note that when double() is called, the calling function doesn't distinguish which
one to call: it just passes in an argument, and the correct one is invoked.
The compiler examines the arguments and chooses which of the four double() functions to call.
The output reveals that each of the four was called in turn, as you would expect.
1) ____________provides a flexible optim for the creation of new definitions for most of the
C++ operators.
2) _____________ To create more than one function with the same name.
8.6 Summary
In this we have discussed about operator overloading and function overloading. And also we
have discussed about different type operator overloading.
152
2) Function Overloading
3. What is the difference in overloading when done via friend function and one without it?
LESSON - 9
INHERITANCE
Structure
9.1 Introduction
9.4 Inheritance
9.5 Summary
9.1 Introduction
Reusability is yet another important feature of OOP. It is always nice if we could reuse something
that already exists rather than trying to create the same all over again. It would not only same
time and money but also reduce frustration and increase reliability. For instance the reuse of a
class that has already been tested, debugged and used many times can save us the effort of
developing and testing the same again.
For example, consider father, son and public relationship. The son is the direct descendant of
father who is considered to be the base class and the son the derived class. The public is
somebody else who is third person to the father-son family. Now consider the visibility modes as
following:
The father written a bond which allows all his wealth are to public. So his descendant son and
third person public can access his wealth. So anybody including his descendants and others
can access his wealth. i.e. The members which are declared in the public section can be
accessed by any function.
The father felt unsafe for his wealth due to the disturbances from his relations and written a bond
to protect his wealth which are only for himself and his son. So the public cannot be able to
access his wealth. i.e. protected in an access specifier under which members are visible to
derived classes, but or otherwise private.
The father felt unsafe for his wealth and he is not ready to believe his son so he written a bond
which makes all the wealth only to father. So no one including son cannot be able to access his
wealth. It is only for the father. i.e. In private section, the member can be accessed by the
member function and friends of this class. eleving
9.4 Inheritance
Fortunately, C++ strongly supports the concept of reusability. The C++ classes can be reused
in several ways. Once a class has been written and tested, it can be adapted by other programmers
to suit their requirements. This is basically done by creating new classes, reusing the properties
of the existing ones. The mechanism of deriving a new class from an old one is called inheritance
(or derivation). The old class is referred to as the base class and the new one is called the
derived class.
Whenever a derived class is defined, we have to specify the relationship with the pildur Healeva
base class.
155
data members;
member function;
};
The colon indicated that the derived class name is derived from the base class name. The
visibility mode is optional. It may be
Example
Class basioc-info
private:
char name[20];
char sex;
public;
void getdata();
void display();
}
156
private:
351
float height;
public:
void getd();
};
The derived class inherits the properties of its base classes including the data member and
member functions. If a base class is privately inherited by a derived class, public member of the
base class become private members of the derived class. Hence the public members of the
base class cannot be accessed by the object of the derived class. Therefore, a public member
of the base class can be accessed by the member function of the derived class.
If a base class is publicly inherited by a derived class, public members of the base class become
public members of the derived class. So, the objects and member functions of the derived
class can access to the public members of the base class.
1. Single Inheritance: When a subclass inherits only from one base class, it is known as
single inheritance.
2. Multiple Inheritance: When a subclass inherits from multiple base classes, it is known
as multiple inheritance.
3. Hierarchical Inheritance: When many subclass inherit from a single base classe, it is
known as Hierarchical inheritance.
157
4. Multiplelevel Inheritance: When a subclass inherits from a base class that itself inherits
from another base class, it is known as multilevel inheritance.
5. Hybrid Inheritance: When a subclass inherits from multiple base classes and all of its
base classes inherits from a single base class, this form of inheritance is known as
Hybrid inheritance.
1) Single Inheritance
By deriving a class from a base class, we can extend the base class by adding a new data
members and member functions. The following program illustrates the idea of the extending
class
#include<iostream.h>
class B
sad public;
int b;
void get_ab()
{a=5;
b=10;
int get_a(void)
BOqdib blov
return a;
void show_a()
cout<<"a="<<<a"<<endl;
{
158
int C
public:
void mul()
c=b'get_a();
void display()
cout<<"a="<<get_a()<<endl;
cout<<"b="<<b<<endl;
cout<<"c"<<<<endl;
Case 1
a-> is accessible from B. Not from outside or from D.er Inpanseforsa
Get_ab()
Get_a()
Show_a()
Anywhere.
Mul()
Display()
Case 2
If we change the inheritance as
Class D:protected B{
get_ab()}
show_a() }
Display() }
If we further inherit D the B's data and member function will become protected to 'D' and the
same to next level.
Case 3
If we change the inheritance as
Class D: private B{
.....................
But the difference lies in the further inheritance of D. All the public data and member function will
become private to D. So the direct descendant cannot be able to access these. Other are same
as the previous case.
2) Multiple Inheritance
In multiple inheritance two or more classes are inherited to a single derived class. In real life
example it is similar to the son inheriting the physical features of father and mother.
160
Multiple inheritance is process of creating a new class from more than one base classes. That
is, a class can inherit the attributes of two or more classes as shown in the following figure.
//
#include<iostream.h>
classM
protected:
int m;
public:
void get_m(int);
};
class N
protected:
Int n;
public:
void get_n(int);
356
public:
void display(void);
void m::gel_m(int x)
m=x;
}
161
void n;:get_n(int y)
n=y;
void p::djsplay(void)
cou<<"M="<<m<<endl;
cout<<"n"<<endl;
cout<<"M*n"=<<m*n<<endl;
main()
P p;
p.get_m(10);
p.get_n(29);
p.display();
output
m=10
n=20
m*n=200
In this the class (P' Inherited form both M and 'N' So all the public and protected data are available
to 'P'.
3) Multilevel Inheritance
The mechanism of deriving a class from already derived class is known as Multilevel inherence.
Multilevel inheritance is just like inheriting the previously inherited object. That is we Inherited a
derived class 'D' from a base class 'B'. Further we inherited a class 'D1' from 'D' is called
Multilevel inheritance.
162
In this the Inherited class 'D' will become a base class for 'D1'. In real life example it is similar to
the son inheriting his father's wealth which is inherited from his father(grand father to the son).
This concept allows as to build a chain of class as shown in the following figure
#include<iostream.h>
//multilevel Inheritance
class student
protected:
int roll_number;
public:
void get_number(int);
void put_number();
void' student::get_number(int a)
roll_number=a;
void student::put_number()
cout""rollnumber=""roll_number"endl;
protected:
float sub1;
float sub2;
163
public:
void get_marks(float,float);
void put_marks();
};
void::get_marks(float x, floaty)
sub1=x;
sub2=y;
cout""Mark1=""sub1"""\n"; cout""Mark2=""sub2"""\n";
float total;
public:
void display(void);
void result::display(void)
total-sub1+sub2;
put_number();
put_marks();
cout""total="<<total""\n";
164
main()
result student1;
student1.get_number(111);
student1.get_marks (75.0,59.5);
student1.display();
output
Roll No 1294
SUB1 75
SUB2 89
Total 164
4) Hierarchical Inheritance
In hierarchical inheritance only one base can inherited by two or more derived classes. So each
do have their own icteristics in addition with the base class. In real life example the sons and
daughter their fathers wealth, characters, etc.,
5) Hyrbrid Inheritance
In some situations we need to apply two or inheritance sign a program. For example processing
with students results. Assume that we weightage for sports before finalizing
the results. Result for sport is stored in a separate class called sport inheritance relationship
between the various classes of the following figure.
In this example we combined the both multilevel and multiple inheritances together to form a
derived class result.
Example
#include<iostream.h>
class student
165
protected:
int roll_number;
public:
void get_number(int);
void put_number();
};
void student::get_number(int a)
roll_number=a;
void student::put_number()
cout""roll number=""roll_number"endl;
protected:
float subl;
float sub2;
public:
void get_marks(float,float);
void put_marks();
};
sub1=x;
sub2=y;
void test::put_marks()
cout""Mark1="<<sub1""\n";
cout""Mark2=""sub2""\n";
class sports
protected:
float score;
public:
void get_score(float s)
score=s;
void put_score(void)
cout<<"sports wt::"<<score<<"\n\n\n";
};
float total;
public:
void display(void);
void result::display(void)
total sub1+sub2+score;
put_number();
put_marks()";
put_score();
cout"total="<<total":<"\n";
void main()
result student1;
student1.get_number(111);
student1.get_marks(75.0,59.5);
student1.get_score(6.0);
student1.get_display();
9.5 Summary
In this lesson we have covered Visibility Modes and Inheritance. And also we have covered
types inheritance.
168
2. Single Inheritance
3. Multiple Inheritance
2 What are the different forms of inheritance? Give one example for
8. Design a base class called shape. Use this class to store two double type values the
could be used to compute the area of figures. Derive tow specific classes called triangle
and rectangle from the base shape. Add to the base class, a member function get dataQ
to initialise base class data members and another member function display area() to
compute and display the area of figures.
169
LESSON - 10
POLYMORPHISM AND VIRTUAL FUNCTIONS
Structure
10.1 Introduction
10.3 Polymorphism
10.5 Summary
10.1 Introduction
Polymorphism is one of the crucial features of OOP. It simply means 'one name, multiple forms'.
The concept of polymorphism is implemented using the overloaded functions and operators.
The overloaded member functions are 'selected' for invoking by matching arguments, both type
and number. This information is known to the compiler at the compile time and therefore, compiler
is able to select the appropriate function for a particular call at the compile time itself. This is
called early binding or static binding or static linking. Also known as compile time polymorphism,
early binding simply means that an object is bound to its function call at compile time.
10.3 Polymorphism
Now let us consider a situation where the function name and prototype is the same in both the
base and derived classes. For example, consider the following class definitions:
170
Class A
int x;
public:
class B:public A
inty;
public:
How do we use the member function show() to print the values of objects of both the clases A
and B? since the prototype of show() is the same in both the places, th function is not overloaded
and therefore static binding does not apply. In fact, the compiler does not know what to do and
defers the decision.
It should be nice if the appropriate member function could be selectwhile the program is running.
This is known as run time polymorphism. How could it happen? C++ supports a mechanism
known as virtual function to achieve run-time polymorphism at run time, when it is known wha
class objects are under consideration, the appropriate version of the function is called, since the
function is linked with a particular class much later after the compilation, this process is termed
as late binding. It is also known as dynamic binding because the selection of the appropriate
function is done dynamically at run time.
Dynamic binding is one of the powerful features of c++. This requires the use pointers to objects.
1. Pointers to Objects
We have already seen how to use pointers to access the class members. A pointer can point to
an object created by a class.
171
Where item is a class and x is an object defined to be of type item. similarly, we can define a
pointer it_ptr of type item as follows:
item *it_ptr;
Object pointers are useful in creating objects at run time. warla blow
We can also use an object pointer to access the public member of an object. Consider a class
item defined as follows:
class item
int code;
float price;
public:
void getdata(inta,floatb)
code=a;
price-b;
void show(void)
cout""Code:""code""\n";
"""Price""pric""\n\n";
item x;
item *ptr=&x;
We can refer to the member functions of item in two ways, one by using the dot perator and the
object, and another by using the arrow operator and the object pointer. "he statements
x.getdata(100,78,75)
x.show();
are equivalent to
ptr>getdata(100,78,75);
ptr->show();
method.
(*ptr).show();
The parenthesis are necessary because the dot operator has higher precedence than the
indirection operator *.
We can also create the objects using pointers and new operator as follows:
this statement allocates enough memory for the data members in the object structure and
assigns the address of the memory space to ptr. Then ptr can be used to refer to the members
as shown below:
ptr->showO;
If a class has a constructor with arguments and does not include an empty constructor, then we
must supply the arguments when the object is created.
173
We can also create an array of objects using pointers, For example, the statement
item *ptr=new item[10]; //array of 10 objects creates memory space for an array of 10 object of
items.
Remember, in such cases, if the class contains constructors, it must also contain an empty
constructor.
#include<iostream.h>
class item
int code;
float price;
public:
void getdata(inta,float b)
code=a;
price=b;
void show()
cout" "code""code""\n";
cout"<"Price:""price""\n\n";
};
174
main()
item "p=newitem[size];
item "d=p;
int x,i;
float y;
for(i=0;i<size;i++)
cin"x"y;
p->getdata(x,y); onter
P++;
for(i=0;i<size;i++)
cout""Item:""i+1<<"\n";
d->show();
d++;
}
175
In this example we created space dynamically for two objets of equal size. But this may not be
the case always. For example, the object of a class that contain character strings would not be
of the same size. In such cases, we can define an array of pointers to objects that can be used
to access the individual objects. This is illustrated in the following program.
#include<iostream.h>
#include<string.h>
class city
protected:
char *name;
int len;
public:
city()
len=0;
name=new char[len+1];
void getname(void)
char *s;
cin"s;
176
len=strlen(s);
name=new char[len+1];
strcpy(name,s);
void printname(void)
cout"name<,"\n";
};
main()
intn-1;
int option;
do
cptr[n]=new city;
cptr[n]->getnae();
n++;
cin"option;
177
while(option)
cout""\n\n";
for(int i=1;i<=n;i++)
cptr[i]-> printname();
2. 'this' Pointer
C++ uses a unique keyword called 'this' to represent an object that invokes a member function,
this' is a pointer that points to the object for which this function was called. For example, the
function call A.max() will set the pointer this to the address of the object A.
Thus unique pointer is automatically passed to a member function when it is called. The pointer
this acts as an implicit argument to all the member functions. Consider the following
simple example:
class ABC
int a;
...
...
...
};
The private variable 'a' can be used directly inside a member function, like
a=123;
We can also use the following statement to do the same job: meg trivan
this->a=123;
178
Since C++ permits the use of shorthand form a=123, WE have not been using the pointer this
explicitly so far. However, we have been implicitly using this pointer when overloading the operators
using member function.
Recall that, when a binary operator is overloaded using a member function, we pass only one
argument to the function. The order argument is implicitly passed using the pointer this. One
important applications of the pointer this is to return the object it points. For example, the statement
return "this; inside a member function will return the object that invoked the function. This statement
assumes importance when we want to compare two or more objects inside a, member function
and return the invoking object as a result.
Example
if x.age>age
else
max=A.greater(B):
The function will return the object B{argument object) if the age of the person B is greater than
that of A, otherwise, it will return the object A (invoking object) using the pointer this.
Remember, the dereference operator * produces the contents at the address contained in the
pointer. A complete program to illustrate the use of this is given in the following program.
#include<iostream.h>
#include<string.h>
179
class person
char name[20];
float age;
public:
person(char *s,float a)
strcpy(name,s);
age=a;
if(x.age>=age)
return x;
else
return *this;
void display(void)
cout""Name:""name"""\n";
""Age:""age""\n";
180
};
};
main()
person p1("Ahraf",37.20),
p2("Kareem",49.0),
p3("Manokar", 40.25);
person p('\0',0);
p=p1.greater(p3);
p.display();
p=p1.greater(p2);
p.display();
A pointer declared as a pointer to a base class can also be used to point to any class derived
from that based. For example, assume two classes called base and derived, where derived
inherits base. Given this situation, the following statements are
Correct.
base *p;
base base_ob;
181
derived derived_ob;
p=&base_ob;
p=&base_ob;
p=&derived_ob;
As the comments suggest, a base pointer can point to an object of any class derived from that
base without generating a type mismatch error. befassad w rolunu naitw
Although you can use a base pointer to point in a derived object, you can access only those
members of the derived object that were inherited from the base. This is because the base
pointer has knowledge only of the base class. It knows nothing about the members added by the
derived class.
Although you can use a base pointer to point to a derived object, you can access only those
members of the derived object that were inherited from the base. This is because the base
pointer has Typos vielir's feil estun sized emoz
knowledge only of the base class. It knows nothing about the members added by the derived
class. While it is permissible for a base pointer to point to a derived object, the reverse is not
true. A pointer of the derived type cannot be used to access an object of the base class.
A virtual function is a member function that is declared within a base class and redefined by a
derived class. To create a virtual function, precede the function's declaration with the keyword
virtual. When a class containing a virtual function relative to the derived class. In essence,
virtual functions implement the "one interface, multiple methods".
Philosophy that underlies polymorphism: The virtual function within the base class defines the
form of the interface to that function. Each redefinition of the virtual function by a derived class
implements its operation as it relates specifically to the derived class. that is the redefinition
creates a specific method.
182
When a virtual function is redefined by a derived class, the keyword virtual is not needed.
minine A virtual function can be called just like any other member function. However, what makes
a virtual function interest in and capable of supporting run time polymorphism is - what happens
when a virtual function is called through a pointer. When a base pointer points to a derived object
that contains a virtual function and that virtual function is called
through that pointer. C++ determines which version of that function will be executed based upon
the type of object being pointed to by the pointer.
And, this is determined at run time. It is the type of the object pointed to at the time when function
will be executed, Therefore, if two or more different classes are derived from a base class that
contains a virtual function then when different objects are by a base pointer, different versions of
the virtual functions are executed. This process is. the way that run-time polymorphism is
achieved. In fact, a class that contains a virtual function is referred to as a polymorphic class.
Beup When virtual functions are created for implementing late binding, we should observe some
basic rules that satisfy compiler requirements:
4. A virtual function in a base class must be defined, even though it may not be used.
5. The prototypes of the base class version of a virtual function and all the derived class
versions must be identical. If the functions with the same name have different prototype,
C++ considers them as overloaded functions, and the virtual function mechanism is
ignored.
7. While a base pointer can point to any type of the derived object, the reverse is not true.
That is, we cannot use a pointer of derived class to access an object of the base type.
183
8. When a base pointer points to a derived class, incrementing or decrementing it will not
make it to point to the next object of the derived class. It is incremented or decremented
only relative to its base type. Therefore, we should not use this method move pointer to
the next object.
9. If a virtual function is defined in the base class, it need not necessarily redefined in the
derived class. In such cases, calls will invoke the base function.
Virtual functions defined inside the base class normally serve as a framework for future design
of the class hierarchy; these function can be overridden by the methods in the derived classes.
In most of the cases, these virtual functions are defined with a null- body; it has no definition.
such functions in the base class are similar to do-nothing or dummy functions and in C++, they
are called pure virtual functions. The syntax of defining pure virtual function is shown below:
Pure virtual function is declared as a virtual function with its declaration followed by - 0.
class Myclass
public
......
......
......
......
};
A pure virtual function declared in a base class has no implementation as far as the base class
is concerned, the classes derived from a base class having a pure virtual function have to
define such a function or redeclare it as a pure virtual function.
184
It must be noted, that a class containing pure virtual function. It must be noted, that a class
containing pure virtual functions cannot be used to define any objects of its own and hence such
classes are called pure abstract classes or simply abstract classes.
Whereas all other classes without pure virtual functions and which are instantiated are called as
concrete classes.
A pure virtual function is an unfinished place holder that the derived class is expected to complete.
The following are the properties of pure virtual functions:
A virtual function has no implementation in the base class hence, a class with pure virtual function
cannot be instantiated.
It acts as an empty bucket (virtual function is a partially filled bucket) that the derived class is
supposed to fill. on se bod
10.5 Summary
The concept of abstract class (a class with pure virtual function) is necessary in order to
understand pure virtual functions. Note that a class with one or more pure virtual functions
cannot be instantiated.
2) This pointer
185
5. What are pure virtual functions? How do they differ from normal virtual functions?
6. What are the rules that need to be kept in mind in deciding virtual functions?
7. What are abstract classes? Write a program having student as an abstract class and
create many derived class such as engineering, science etc. from the student class.
Create their object and process them.
LESSON - 11
WORKING WITH FILES
Structure
11.1 Introduction
11.5 Summary
11.1 Introduction
Many real-life problems handle large volumes of data and, in such situations, we need to use
some devices such as floppy disk or hard disk to store the data. The data is stored in these
devices using the concept of files. A file is a collection of related data stored in a particular area
on the disk. Programs can be designed to perform the read and write operations on these files.,
This is illustrated in Fig 11.1. We have already discussed the technique of handling data
communication between the console unit and the program. In this chapter, we will discuss
various methods available for storing and retrieving the data from files. wall ombe 680 of
The I/O system of C++ handles file operations which are very much similar to the console input
and output operations. It uses file streams as an interface between the programs and the files.
The stream that supplies data to the program is known as input stream and the one that receives
data from the program is known as output stream. In other words, the input stream extracts (or
reads) data from the file and the output stream inserts (or writes) data to the file. This
188
illustrated in Fig 11.2. The input operation involves the creation of an input stream and linking it
with the program and the input file. Similarly, the output operation involves establishing an output
stream with the necessary links with the program and the output file.
The I/O system of C++ contains a set of classes that define the file handling methods. These
include ifstream, ofstream and fstream. These classes are derived from fstreambase and from
the corresponding iostream.h class as shown in Figure 11.3. These classes, designed to manage
the disk files, are declared in fstream.h and therefore we must include this file in any program
that uses files. Table 11.1 shows the details of file operation classes. Note that these classes
contain many more features. For more details, refer to the manual.
189
Fig 11.3 Stream classes for file operation (contained in fstream.h file)
Class Contents
filebuf Its purpose is to set the file buffers to read and write. Contains openport constant
used in the open() of the file stream classes. Also contains close() and open() as
members.
base Serves as a base for fstream. Ifstream and ofstream classes. Contains istab
ehomeopen() and close() functions.
Ifstream Provides input operations. Contains open() with default input mode. Inherits the
functions get(), getline(), read(), seekg() and tellg() functions from istream.
ofstream Provides output operations. Contains open() with default output mode. Inherits
put(), seekp(), tellp(), and write() functions from ostream.
fstream Provides support for simultaneous input and output operations. Contains open()
with default input mode. Inherits all the functions from istream and ostream classes
through iostream.
190
3. Purpose.
4. Opening method.
The filename is a string of characters that make up a valid filenames for the operating system.
It may contain two parts, a primary name and an optional period with extension
Examples
Input.data
Test.doc
INVENTORY
student
salary
OUTPUT
As stated earlier, for opening a file, we must first create a file stream and then link it to the
filename. A file stream can be defined using the classes ifstream, ofstream, and fstream that
are contained in the header file fstream.h. The class to be used depends upon the purpose,
whether we want to read data from the file or write data to it. A file can be opened in two ways:
The first method is useful when we use only one file in the stream. The second method is used
when we want to manage multiple files using one stream.
We know that a constructor is used to initialize an object while it is being created. Here, a
filename is used to initialize the file stream object. This involves the following steps:
191
1. Create a file stream object to manage the stream; using the appropriate class. That is,
the class ofstream is used to create the output stream and the class ifstream to create
the input stream.
For example, the following statement opens a file named "results" for output:
This creates outfile as an ofstream object that manages the output stream. This object can be
any valid C++ name such as o_1, myfile or fout This statement also opens the file results and
attaches it to the output stream outfile. This is illustrated in Fig 11.4
Similarly, the following statement declares infile as an ifstream object and attaches it to the file
data for reading (input).
outfile"TOTAL";
outfile"sum;
infile"number;
infile"string;
We can also use the same file for both reading and writing data as shown in Fig 11.5. The
programs would contain the following statements:
program 1
.....
.....
.....
.....
Program2
.....
.....
The connection with a file is closed automatically when the stream object expires (when the
program terminates). That is, when the program"! is terminated, the salary file is disconnected
from the outfile stream. Similar action takes place when the program2 terminates.
Instead of using two programs, one for writing data(output) and another for reading data (input)
we can use a single program to do both the operations on a file.
Example
.....
.....
.....
.....
Although we have used a single program, we created two file stream objects, outfile(to put data
to the file) and infile(to get data from the file). Note that the use of a statement like
outfile.close();
disconnects the file salary from the output stream outfile. Remember, the object outfile still
exists and the salary file may again be connected to outfile later or to any other stream. In this
example, we are connecting the salary file to infile stream to read data.
Program 11.1 use a single file for both writing and reading the data. First, it takes data from the
keyboard and writes it to the file. After the writing is completed, the file is closed. The program
again opens the same file, reads the information already written to it and displays the same on
the screen.
ofstream outf("ITEM");
cin" name;
outf"name" "\n";
float cost;
cin"cost;
outf.close();
ifstream inf("ITEM");
inf'name;
inf"cost;
cout" "\n";
inf.close();
Item cost: 45
As stated earlier, the function open() can be used to open multiple files that use the same
stream object. For example, we may want to process a set of files sequentially. In such cases,
we may create a single stream object and use it to open each file in turn. This is done as follows:
195
Example
ofstream outfile;
.....
.....
outfile.closeO;
.....
.....
outfile.closeO
.....
.....
The above program segment opens two files in sequence for writing the data. Note that the first
file is closed before opening the second one. This is necessary because a stream can be
connected to only one file at a time.
#include <fstream.h>
main()
ofstream fout;
196
//connect "country" to it
fout.close();
fout.open("capital");
//connect "capital"
fout" "Washigton\n";
fout" "London\n";
fout" "Seoul\n";
fout.close();
//disconnect "capital"
//size of line
char line[N];
ifstream fin;
fin.open("country");
//connect "country" to it
while(fin)
fin.getline(line, N);
cout" line;
//display it
fin.close();
fin.open("capital");
//connect "capital"
while (fin)
fin.getline(line,N);
cout" line;
fin.close();
///////////////////////////////<PROGRAM 11.2>/////////////////////////////
198
United Kingdom
South Korea
Washington
London
Seoul
At times we may require to use two or more files simultaneously. For example, we may require
to merge two sorted files into a third sorted file. This means, both the sorted files have to be kept
open for reading and the third one kept open for writing. In such cases, we need to create two
separate input streams for handling the two input files and one output stream for handling the
output file.
10.2
#include <fstream.h>
#include<stdlib.h>
main()
char line[SIZE];
199
fin1.open("country");
fin2.open("capital");
if(fin1.eof() !=0)
exit(1);
fin1.getline(line, SIZE);
if (fin2.eof() !=0)
exit(1);
fin2.getline(line, SIZE);
200
cout"line" "\n";
Washington
London
Seoul
2. Detecting end-of-file
Detection of the end-of-file condition is necessary for preventing any further attempt to read data
from the file. This was illustrated in Program 11.2 by using the statement
while(fin)
An ifstream object, such as fin, returns a value of 0 if any error occurs in the file operation
including the end-of-file condition. Thus, the while loop terminates when fin returns a value of
zero on reaching the end-of-file condition. Remember, this loop may terminate due to other
failures as well. (We will discuss other error conditions later.)
There is another approach to detect the end-of-file condition. Note that we have used the following
statement in Program 11.3:
if (fin1.eof()!=0) {exit(1);}
eof() is a member function of ios class. It returns a non-zero value if the end-of- file(EOF)
condition is encountered, and a zero, otherwise. Therefore, the above statement terminates the
program on reaching the end of the file.
201
We have used ifstream and ofstream constructors and the function open() to create new files
as well as to open the existing files. Remember, in both these methods, we used only one
argument that was the filename. However, these functions can take two arguments, the second
one for specifying the file mode. The general form of the function open() with two argument is
The second argument mode (called file mode parameter) specifies the purpose for which the
file is opened. How did we then open the files without providing the second argument in the
previous examples?
The prototype of these class member functions contain default values for the second argument
and therefore they use the default values in the absence of the actual values. The default values
are as follows:
The file mode parameter can take one (or more) of such constants defined in the class ios.
Table 11.2 lists the file mode parameters and their meaning.
Parameter Meaning
Each file has two associated pointers known as the file pointers. One of them is called the input
pointer(or get pointer) and the other is called the output pointer(or put pointer). We can use
these pointers to move through the files while reading or writing. The input pointer is used for
reading the contents of a given file location and the output pointer is used for writing to a given
file location. Each time an input or output operation takes place, the appropriate pointer is
automatically advanced.
Default Actions
When we open a file in read-only mode, the input pointer is automatically set at the beginning so
that we can read the file from the start. Similarly, when we open a file write- only mode, the
existing contents are deleted and the output pointer is set at the beginning.
"hello" file
input pointer
This enables us to write to the file from the start. In case, we want to open an existing file
output pointer
output pointer
to add more data, the file is opened in 'append' mode. This moves the output pointer to the end
of the file. (i.e. the end of the existing contents). See Fig. 11.7
All the actions on the file pointers as shown in Fig. 11.7 take place automatically by default. How
do we then move a file pointer to any other desired inside the file? This is possible only if we can
203
take control of the movement of the file pointers ourselves. The file stream classes support the
following functions to manage such situations:
infile.seekg(10);
moves the file pointer to the byte number 10. Remember, the bytes in a file are numbered
beginning from zero. Therefore, the pointer will be pointing to the 11th byte in the file. Consider
the following statements:
ofstream fileout;
fileout.open("hello", ios::app;
int p=fileout.tellpO;
On execution of these statements, the output pointer is moved to the end of the file "hello" and
the value of p will represent the number of bytes in the file.
We have just now seen how to move a file pointer to a desired location using the "seek" functions.
The argument to these functions represent the absolute position in the file.
'seek' function seekg() and seekp() can also be used with two arguments as follows:
seekg(offset, refposition);
seekp(offset,refposition);
The parameter offset represents the number of bytes the file pointer is to be moved from the
location specified by the parameter ref position. The refposition takes one of the following three
constants defined in the ios class:
204
The seekg() function moves the associated file's 'get' pointer while the seekp() function moves
the associated file's 'put' pointer. Table 11.3 lists some sample pointer offset calls and their
actions, fout is an ofstream object
3. The stream that receives data from the program is known as________________
11.5 Summary
The data is stored in flob by disk of hard disk using the concept of files program can be desingned
to perform the read and write operations on these files.
205
2) Input stream
3) Output Stream
2. What is a file mode? Describe the various file mode options available.
3. What is the difference between opening a file with a constructor function and opening a
file with open() function? Which is preferred?
LESSON - 12
12.1 Introduction
12.8 Summary
12.1 Introduction
The file stream classes support a number of member function for perfoprming the input and
output operation on files. In this lesson we shall discuss about various sequential 1/0 operations
in detail.
• Updating afile
The function put() writes a single character to the associated stream. Similarly, the function
get() reads.a single character from the associated stream. Program 12.1 illustrates how these
writes it, character by character, to the file using the put() function in a for loop. Note that the
length of the string is used to terminate the for loop.
The program then displays the contents of the file on the screen. It uses the function get() to
fetch a character from the file and continues to do so until the end-of-file condition is reached.
The character read from the file is displayed on the screen using the operator <<.
#include <fstream.h>
#include <string.h>
main()
char string[80];
cin>>string;
fstream file;
file.seekg(0);
char ch;
while(file)
file.get(ch);
cout"ch;
//display it on screen.
Enter a string
Cobol_programming output
Note that we have used an fstream object to open the file. Since an fstream object can handle
both the input and output simultaneously, we have opened the file in ios::in | ios::out mode. After
writing the file, we want to read the entire file and display its contents. Since the file pointer has
already moved to the end of the file, we must bring it back to the start of the file. This is done by
the statement
file.seekg(0);
209
The functions write() and read(), unlike the functions put() and get(), handle the data in binary
form. This means that the values are stored in the disk file in the same format in which they are
stored in the internal memory. Figure 12.1 shows how an int value 2094 is stored in the binary
and character formats. An int takes two bytes to store its value in the binary form, irrespective of
its size. But a 4-digit int will take four bytes to store it in the character form.
The binary format is more accurate for storing the numbers as they are stored in the exact
internal representation. There are no conversions while saving the data and therefore saving is
much faster.
The binary input and output functions takes the following form:
infile.read((char*) &v,sizeof(v));
outfile.write((char *) &v,sizeof(v));
These functions take two arguments. The first is the address of the variable v, and the second
is the length of that variable in bytes. The address of the variable must be cast to type char* (i.e
pointer to character type). Program 12.2 illustrates how these two functions are used to save an
array of float number and then recover them for display on the screen.
#include <fstream.h>
210
#include <iomanip.h>
main()
ofstream outfile(filename);
outfile.close();
for(int i=0;i<4;i++)
cout.setfios::showpoint);
cout<<setw(10)<<setprecision(2) <<height[i];
infile.close();
We mentioned earlier that one of the shortcomings of the I/O system of C is that it cannot
handle user defined data types such as class objects. Since the class objects are the central
211
elements of C++ programming, it is quite natural that the language supports features for writing
to and reading from the disk files objects directly. The binary input and output functions read()
and write() are designed to do exactly this job. These functions handle the entire structure of an
object as a single unit, using the computer's internal representation of data. For instance, the
function write() copies a class object from memory byte by byte with no conversion. One important
point to remember is that only data members are written to the disk file and the member functions
are not.
Program 12.3 illustrates how class objects can be written to and read from the disk files. The
length of the object is obtained using the sizeof operator. This length represents the sum total of
lengths of all data members of the object.
#include<fstream.h>
#include<iomanip.h>
class INVENTORY
//item name
char name[10];
//item code
int code;
float cost;
public:
void readdata(void);
void writedata(void);
};
212
endl;
main()
fstream file;
item[i].writedata();
213
file.close();
///////////////<<PROGRAM 12.3>///////////////
Enter code: 99
Enter cost: 84
Enter name: C
Enter cost:125
OUTPUT
BASIC 99 84
FORTRAN 100 98
C 120 125
The program uses for loop for reading and writing objects. This is possible because we known
the exact number of objects in the file. In case, the length of the file is not known we can determine
the file-size in terms of objects with the help of the file pointer functions and use it in the for loop
or we may use while(file) test approach to decide the end of the file. These techniques are
discussed in the next section.
214
These actions require the file pointers to move to a particular location that correspond to the
item/object under consideration. This can be easily implemented if the file contains a collection
of items/objects of equal lengths. In such cases, the size of each object can be obtained using
the statement
Then, the location of a desired object, say the mth object, may be obtained as follows:
The location gives the byte number of the first byte of the mth object. Now, we can set the file
pointer to reach this byte with the help of seekg() or seekp().
We can also find out the total number of objects in a file using the object_length as follows:
int n=file_size/object_length,
The file_size can be obtained using the function tellg() or tellp() when the file pointer is located at
the end of the file.
215
Program 12.4 illustrates how some of the tasks described above are carried out. The program
uses the "STOCK.DAT" file created using Program 10.3 for 5 items and performs the following
operations on the file:
#include<fstream.h>
#include <iomanip.h>
class INVENTORY
char name[10];
int code;
float cost;
public:
void getdata(void)
void putdata(void)
{
216
“setw(10)" code
“endl;
main()
INVENTORY item;
ios::out | ios::binary);
item.putdata();
item.getdata();
char ch;
217
in.get(ch);
item.putdata();
int last-inoutfile.tellg();
int n = last/sizeof(item);
ITEM............."/
int object;
cin" object;
cin.get(ch);
if(inoutfile.eof()) inoutfile.clear();
inoutfile.seekp(location);
218
item.getdata();
cin.get(ch);
inoutfile.seekg(0);
item.putdata();
inoutfile.close();
} //End of main
AA 11 100
BB 22 200
CC 33 300
DD 44 400
XX 99 900
219
ADD ANITEM
Enter name: YY
Enter Code: 10
AA 11 100
BB 22 200
CC 33 300
DD 44 400
XX 99 900
YY 10 101
Number of objects =6
Enter name: zz
Enter code:20
AA 11 100
BB 22 200
CC 33 300
DD 44 400
XX 99 900
YY 20 201
We are using the fstream class to declare the file streams. The fstream class inherits two
buffers, one for input and another for output, and synchronizes the movement of the file pointers
on these buffers. That is, whenever we read from or write to the file, both the pointers move in
tandem. Therefore, at any point of time, both the pointers point to the same byte.
Since we have to add new objects to the file as well as modify some of the existing objects, we
open the file using ios::ate option for input and output operations Remember, the option ios::app
allows us to add data to end of the file only. The ios::ate mode sets file pointers at the end of the
file when opening it. We must therefore move the get pointer to the beginning of the file using the
function seekg() to read the existing contents of the file.
At the end of reading the current contents of the file, the program sets the EOF flags on. This
prevents any further reading from or writing to the file. The EOF flag is turned off by using the
function clear(), which allows access to the file once again.
After appending a new item, the program displays the contents of the appended file and also the
total number of objects in the file and the memory space occupied by them.
To modify an objects, we should reach to the first byte of that object. This is achieved using the
statements
inoutfile.seekp(location);
221
The program accepts the number and the new values of the object to be modified and updates
it. Finally, the contents of the appended and modified file are displayed.
Remember we are opening an existing file for reading and updating the values. It is therefore,
essential that the data members are of the same type and declared in the same order as in the
existing file. Since, the member functions are not stored, they can be different.
1. A file which we are attempting to open for reading does not exist.
2. The file name used for a new file may already exist.
4. There may not be any space in the disk for storing more data.
6. We may attempt to perform an operation when the file is not opened for that purpose.
The C++ file streams inherits a 'stream-state' member from the class ios. This member records
information on the status of a file that is being currently used. The stream state member uses bit
fields to store the status of the error conditions stated above,
The class ios supports several member functions that can be used to read the status recorded
in a file stream. These functions along with their meanings are listed in Table 12.1
good() Returns true if no error has occurred. This means, all the above functions
are false. For instance, if file.good() is true, all is well with the stream file
and we can proceed to perform I/O operations. When it returns false, no
further operations can be carried out.
These functions may used in the appropriate places in a program to locate the status of a file
stream and thereby to take the necessary corrective measures. Example
...............
...............
ifstream infile;
infile.open("ABC")
while(iinfile.fail())
.......
.......
if(infile.eof())
else
223
if(infile.bad())
else
.......
.......
.......
.......
The function clear() (which we used in the previous section as well) resets the error state so
that further operations can be attempted
while(infile)
and
while(infile.read(....))
.......
.......
224
Here, infile becomes false (zero) when end of the file is reached (and eof() becomes true)
1) The C++ file streams inherits a stream - State member from the class_____________
Here, exam is the name of the file containing the program to be executed, and data and results
are the filenames passed to the program as command-line arguments.
The main() functions which we have been using up to now without any arguments can take two
arguments can take two arguments as shown below:
The first argument argc (known as argument counter) represents the number of argument in
the command line. The second argument argv (known as argument vector) is an array of char
type pointers that point to the command line arguments. The size of this array will be equal to
the value of argo. For instance, for the command line.
the value of argc would be 3 and the argv would be an array of three pointers to strings as shown
below:
argv[0] d exam
argv[1] a data
argv[2] a results
225
Note that argv[0] always represents the command name that invokes the program. The character
pointers argv[1] and argv[2] can be used as file names in the file opening statements as shown
below:
.......
.......
.......
.......
.......
.......
'Program 12.5 illustrates the use of the command-line arguments for supplying the file names.
The command line is
The program creates two files called ODD and EVEN using the command-line arguments and
a set of numbers stored in an array are written to these files. Note that the odd numbers are
written to the file ODD and the even numbers are written to the file EVEN. The program then
displays the contents of the files.
/////////////COMMAND-LINE ARGUMENTS/////////////////
#include <fstream.h>
#include <stdlib.h>
if (argc!=3)
226
cout<<"argc ="<<argc<<"\n";
exit(1);
fout1.open(argv[1]);
if (fout1.fail())
exit(1);
fout2.open(argv[2]);
if (fout2.fail())
"argv[2]" "\n";
exit(1);
if (number[i]%2==0)
else
fout1.close();
fout2.close();
ifstream fin;
char ch;
for(i=1;i<argc;i++)
fin.open(argv[i]);
cout<<"Contents of "<<argv[i]<<"\n";
do
fin.get(ch);
//read a value
cout<<ch; //display it
while (fin);
cout<<"\n\n";
fin.close();
Contents of ODD
228
11 33 55 77 99
Contents of EVENT
22 44 66 88
12.7 Summary
We have been opening and closing filesfor reading an writing on the assumption tha everhthing
is fine with the files. This may not be true always. Same times the error will be occured.
(a) ifstream.infile("DATA");
(d) close(f1);
(e) infile.open(argc);
(f) fmout.open(file:ios::inlios::out|ios::ate);
2. Write a program that read a text file and creates another file that is identical except tha
every sequence of consecutive blank spaces is replaced by a single space.
1. What is OOP?
3. Define: Constructor
5. Define: Polymorphism
9. What is a stream?
PART B - (5 x 5 = 25 marks)
Answer any FIVE questions
All questions carry equal marks
19. Explain to manipulate the position of file pointers in a random access file.
PART C - (3 x 10 = 30 marks)
Answer any THREE questions
All questions carry equal marks
I. Terminated()
II. Unexpected()
III. Uncaught()
IV. Exception()
23. Explain the syntax for passing arguments to base class constructors with an example in
multiple inheritance.
24. Write C++ program to create student information file using inheritance concepts.