C++ Final
C++ Final
Chapter - 1
OOPS INTRODUCTION
C++ PROGRAMMING
Object Oriented Programming:
The object-oriented programming paradigm expresses computer programs in ways
that show how people perceive the world. Because programmers are people, it is
only natural that our approach to the work of the world reflects pit view of the world
itself.
The object-oriented paradigm is built on the foundation laid by the structured
programming concepts and data abstraction. Data abstraction does for data what
functional abstraction does for operations. With data abstraction, data structures
can be used without having to be concerned about exact details of implementation.
For example, floating-point numbers are abstracted in programming languages. You
are not required to know how a floating-point number is represented in binary while
assigning a value to it. Likewise, you are not bothered how binary multiplication
takes place while multiplying floating-point values. Abstraction for floating-point
numbers has existed in programming languages since long. However, it is only
recently that languages have been developed to define your own abstract data types.
The fundamental change in OOP is that a program is designed around the data being
operated upon rather than upon the operations themselves. This is to be expected
once we appreciate that the very purpose of the program is to manipulate data. The
basic idea behind object-oriented language is to combine into a single unit, both, the
data and the functions that operate on the data. Such a unit is called an object.
An objects functions, called member functions in C++, typically provide the only way
to access its data. If you want to create a data item in an object, you call a member
function in the object. It will read the item and return the value to you. You cant
access the data directly. The data is hidden, so it is safe from accidental alteration.
Data and its functions are encapsulated into a single entity.
The Evolution of OOPS
Concept :
As a property of each language, there comes a point when programmers begin to
have difficulty managing programs of a certain size and sophistication. Programming
in
an
object-oriented language means creating new types of data (called classes) and
1
C++
"teaching" those data types how to handle messages. You teach a class what to do
with a "message" by creating a "method". The user creates variable of a data
type(objects) or instances and sends messages to those objects. You could think of
this as "Send a message to an object, and let the object figure out what to do with it".
Structured Development :
In traditional procedural languages large programs can be difficult to modify and
maintain. The reaction to this problem was to force structure into the programs from
outside through a methodology called structured development. However, they
require a great deal of forethought and planning, so the project will assemble quickly
and correctly, and be bug-free and easy to maintain. In traditional programming
languages, normally the data is openly available for all different types of operations
by the programmer, who does not have any restrictions on the data access or usage.
For him the data is globally available in all corners of the program. By fault of logic he
may misuse the data producing an erroneous result.
Characteristics of Object-Oriented Languages:
Object-oriented programming uses a vocabulary that is unfamiliar to the procedural
programmer. Let us now briefly examine this vocabulary with regards to the major
elements of object-oriented languages.
Inheritance:
OOPS permits you to create your own data types (classes) just like the types built into
the language. However, unlike the built-in data types, the user-defined classes can
use other classes as building blocks, using a concept called inheritance new classes
can be built from the old once. The new class referred to as derived class, can inherit
the data structures and functions of the original, or the base class. The new class can
add data elements and functions of those it inherits from its base class. Figure below
shows inheritance in C++.
C++
Feature A
Feature B
Feature A
Feature B
Feature C
Feature A
Feature B
Feature C
Fig. 1.1
Inheritance
Reusability :
Object-oriented programs are built from reusable software components. Once a class
is completed and tested, it can be distributed to other programmers for use in their
own programs. This is called reusability. If those programmers want to add new
features or change the existing ones they can do it. The tried and tested capabilities of
base classes do not need to be redeveloped. Programmers can devote time in writing
new code instead of wasting time in rewriting existing code. This way software
becomes easier to test since programming errors can be isolated within the new code
of derived classes.
Polymorphism :
Polymorphism is nothing but the ability to access different implementations of the
functions using the same name. There are two levels at which the Polymorphism
operates: Run-time and Compile-time polymorphism.
C++
Data Abstraction :
Data abstraction means you can combine the data structure and the operations on
the data structure together into a new abstract data type. An abstract data type
behaves just like data types that are built into language, except that they aren't part of
the language definition; they are something the programmer has created. When you
create a data structure in a traditional procedural language, you usually create
functions to manipulate the structure. Those functions can only be used on that
structure. Other functions won't know how to manipulate the structure since the
structure isn't a built-in type. It makes sense then, to bind into one unit the data
structure and the functions that will manipulate it. In C++ this unit is called a CLASS
(also called a user-defined type). Variable or instances, of that class are called
OBJECTS.
Objects:
In structures dividing it into functions approaches a programming problem. Unlike
this, in object-oriented programming the problem is divided into objects. Thinking
in terms of objects rather than functions makes the designing of program easier.
Following are few candidates that can be treated as objects in different programming
situations:
Classes:
Most languages offer primitive data types like int, long and float. Their data
representation and response to arithmetic, assignment and relational operators are
designed as part of the language. However, the language does not know user-defined
data types. The programmer defines its format and behavior by defining a class. For
example, there can be user-defined data types to represent datas. The compiler and
the computer do not know about dates. Programmers have to define the behavior of
dates by designing a date class. This class expresses the format of date and the
operations that can be performed on it . The way we can declare many variables of
the primitive type int, we can define many objects of the date class. A class serves as
a blueprint or a plan or a template. It specifies what data and what functions will be
included in objects of that class. Defining the class doesnt create any variables.
4
C++
Data
data 1
data 2
data 3
Functions
Func 1 ( )
Func 2 ( )
Func 3 ( )
Fig. 1.2 Class contain Data and Functions
Class
Methods
d1
m1
d2
m2
m3
m4
d3
Data
C++
Overloading functions
Overloading operators
Conversion or automatic type conversion
Inline functions
Prototypes
Default parameters
Exercise
C++
Chapter - 2
GETTING STARTED WITH C++
Data Types :
C++ recognizes the data types shown in the table below.
Type Name
Bytes
int
unsigned int
char
unsigned char
short
unsigned short
long
*
*
1
1
2
2
4
unsigned long
enum
float
double
long double
4
2
4
8
10
Other Names
Range of Values
System dependent
System dependent
-128 to 127
0 to 255
-32,768 to 32,767
0 to 65,535
-2,147,483,648 to
2,147,483,647
0 to 4,294,967,295
-32,768 to 32,767
3.4E +/-38 (7 digits)
1.7E +/-308 (15 digits
1.2E+/-4932 (19 digits
C++ has four basic built-in data types. They are: char, int, float and double. Char is
for storing a single character and is usually one byte in size, int stores an integral
value usually two bytes long float and double stores floating point numbers. Float is
for single precision numbers and double is for double precision floating point. Signed
and unsigned are modifiers that can be used with any integral type. The char type is
signed by default.
The following are some examples of built-in data types and initialization:
main()
{
char c;
int p,q,r;
float f = 156.278;
double d;
C++
char a='a';
Specifiers :
Specifiers modify the meaning of the basic built- in types. They effectively provide a
larger set of built in types. The four specifiers or qualifiers are short, long, signed, and
unsigned. The long and short specifiers set the range that the data type will hold
short int, int, and long int are in ascending order of range size. The actual values vary
from machine to machine. Similarly, float, double, and long double are in order of
increasing capacity. There is no long float and no short float or double. The signed
and unsigned specifiers indicate whether the first bit of the data type is to be used as
a sign indicator or no. Except for char the default is signed. Char may or may not be
signed by default. The following program shows the bytes used by the different data
types along with the specifiers:
#include <iostream.h>
void main()
{
int I;
unsigned int ui;
short si;
long li;
unsigned short usi;
unsigned long uli;
char c;
unsigned char uc;
float f;
double d;
long double ld;
//ini is understood
//ditto
//ditto
//ditto
C++
}
Constants :
The const keyword specifies that a variable's value is constant and tells the complier
to prevent the programmer from modifying it.
C++ Environment :
The following are keywords in Microsoft C and C++.
C Language Keywords :
asm
auto
for
short
cdecl
if
struct
default
load
unsigned
enum
register
fastcall
float
segname
caas
huge
static
continue
interrupt
union
else
pascal
while
self
segment
break
goto
sizeof
const
int
typedef
double
near
volatile
return
extern
based
fortran
signed
char
inline
switch
do
long
void
export
far saverefs
operator
friend
public
this
try
protected
private
delete
multiple inheritance
single inheritance
virtual inheritance
The following are not keywords, but they have special meaning in C++.
argc
argv
emit
envp
main
setargv
setenvp
set_new_handler
set_new_handler
C++
which lend a very powerful application development environment. Some features are
specifically useful for Object Oriented Programming Eg.: Construction, Constructors,
Destructors, Inheritance etc. Whereas some features are not OOPS specific but are
very useful.
Eg. : Default parameters, function Overloading etc.
C++ has inherited all the properties from C, plus it has its own properties which are
more enhanced. Thus there are several topics which are a part of C, but also available
with C++ but not commonly used in C++.
The C++ language
Features to implement
Object Oriented
Programming
Useful
features
The C Language
Features common
to C and C++
Features not
used in C++
Commonly
10
C++
Sequence
Name
Sequence
\a
Alert (bell)
\f
Formfeed
\r
Carriage return
\v
Vertical tab
?
quotation mark
?
quotation mark
?
quotation mark
Backslash \ddd
ASCII character in octal
\xdd ASCII character in hex
Format Specifiers :
\b
\n
\t
\?
Name
Backspace
Newline
Horizontal tab
Literal
Single
Double
\'
\"
\\
(signed decimal)
x, X
f
g, G
(fixed-point integer)
(%e or %f; whichever
shorter
e, E
c
s
p
n
(unsigned decimal
integer)
(unsigned hex
integer)
(scientific notation)
(single character)
(string)
(pointer)
(character count)
Preprocessor Directives :
The table below lists the directives to the preprocessor. Their usage and the meaning
in C++ are the same as in C.
#define
#else
#error
#ifdef
#include
#pragma
#elif
#endif
Header Files :
11
#if
#ifndef
#line
#undef
C++
All the header files available in C are used in C++, alongwith other header files of
C++. A few of them are listed below in the table.
File Name
Major Contents
ASSERT.H
BIOS.H
CDERR.H
COLORDLG.H
COMMDLG.H
CONIO.H
CPL.H
CTYPE.H
CUSTCNTIL.H
DDE.H
DDEML.H
DIRECT.H
DLGS.H
DOS.H
DRIVINIT.H
ERRONO.H
FCNTL.H
FLOAT.H
FSTREAM.H
GRAPH.H
IO.H
IOMANIP.H
IOS.H
IOSTREM.H
ISTREAM.H
LIMITS.H
LOCALE.H
LZDOS.H
LZEXPAND.H
MALLOC.H
MATH.H
classes
C++
MEMORY.H
MMSYSTEM.H
NEW.H
OLE.H
OSTREAM.H
PENWIN.H
PENWOEM.H
PGCHART.H
PRINT.H
PROCESS.H
SCRNSAVE.H
SSEARCH.H
SETJMP.H
SHARE.H
SHELLAPI.H
SINGNAL.H
STDARG.H
STDDEF.H
STDIO.H
STDIOSTR.H
STDLIB.H
STREMB.H
STRESS.H
STRING.H
STRESTREA.H
TIME.H
TOOLHELP.H
TOOLHELP.DLL
VARARGS.H
VER.H
VMEMORY.H
WFEXT.H
WINDOWS.H
WINDOWSX.H
WINMEM32.H
WINMEM32.DLL
Buffer-manipulation routines
Include file for Multimedia APIs
Declarations definitions for C++ memory
allocation functions.
OLE functions, types, and definitions
Functions used by the ostream class
Pen Windows functions, types, and definitions
Pen Windows APIs into recognizer layer
Presentation graphics
Printing helper functions, types, and
definitions
Process-control routines
Win3.1 screensaver definitions.
Searching and sorting functions
Setjmp and longjmp functions
Flags used in_sopen
SHELL.DLL functions, types, and definitions
Constants used by signal function
Macros for variable-length argument-list
functions
Commonly used data types and values
Standard I/O header file
Functions used by the stdiostream and
stdiobuf classes
Commonly used library functions
Functions used by the streambuf class
Stress functions definitions
String-manipulation functions
Functions used by strstream classes
General time functions
functions, types, and definitions
Variable-length argument-list functions
Version mnht. functions, types, and
definitions
Virtual memory functions
Windows File Manager Extensions definitions
Windows functions, types, and definitions
Macro APIs, window message creackes,
control
APIs
Function prototypes and general definition for
Win32 bit Memory management
13
C++
SYS\LOCKING.H
SYS\STAT.H
SYS\TIMEB.H
SYS\TYPES.H
SYS\UTIME.H
Extensions :
In C++, all the programs carry ".CPP" extensions as compared to ".C" extensions in C.
Any way, even if one is working in C++ compiler and gives ".C" extension, C compiler
takes over to compile that program.
C++ Comments :
Depending upon the requirement, they can be mentioned in either of the
following ways :
1. /*begins a comment and */ ends it.
2. double-slash (//) sequence.(unless it is inside a string),everything to the end
of the current line is a comment.
Program:
#include <iostream.h>
void main( )
{
char name[20];
//This is a C++ comment
cout << "Enter a name... \n";
/* This is a C comment */
cin>> name;
// This is a C++ comment
cout << "The name you entered was " <<name;
}
Operators :
Relational
Addition
Subtraction
Multiplication
<
<=
>
14
Less than
Less than or equal to
Greater than
C++
to
Division
>=
%
!=
Modulus
Not equal
==
Equal
Assignment
=
Assignment
+=
Addition
-=
Subtraction
/=
Division
<<= Left shift assignment
&=
Bitwise AND
|=
Bitwise OR
Bitwise
Logical
&
^
|
<<
~
&
*
()
[]
.
->
(type)
Bitwise AND
Bitwise-exclusive- OR
Bitwise
OR
Left shift
One's complement Pointer
Address of
Indirection
Function call
Array element
Structure or union member
Pointer to structure member
Type cast
||
!
&&
Logical AND
Logical OR
Logical NOT
>>
Right shift
Conditional
?:
Ternary
Miscellaneous : C++ only
::
Scope resolution
&
Reference
.*
Pointer to member
->
Pointer to member
Sizeof() Size in bytes
C++
Output:
post-increment i = 10
pre-increment i = 12
post-decrement i = 12
pre-decrement i = 10
Console I/O
cout :
printf is very rigid function. We have to specify each datatype with the appropriate
symbol and then specify the data. The 'cout' statement instead does not take any such
prototyping. An example of a cout statement is:
cout<<"p"="<<p<<"National "<<str<<"\n";
Output :
p=100 National Computers
cin :
cin is the object used for standard input .>> is used with cin. This operator waits for
input that is of the same datatype that is supplied to it as argument. This is shown in
the previous example.
Excersice
16
C++
17
C++
Chapter - 3
C++ BASICS
Functions
Definition :
Functions is a set of instructions that can be used at multiple instances, but defined
only once. The main() itself is a function in C and C++. The simple C program, if
written in the manner below will result in an error:
main()
{
}
printf("Hello Princeton\n");
Hence in the above program, we have to include the standard header file, STDIO.H
which contains the prototype of the function printf().
#include <stdio.h>
main()
{
printf("Hell Princeton\n");
}
Function Prototyping :
A function prototype is declaration that defines a function and its return type, so that
each time the function is called, it is checked against the prototype. It is necessary in
C++. When a function prototype is declared, this template is used by the compiler
when the function is called, to ensure that the proper arguments are passed to it and
the return value is correct.
Here is an example of a function prototype:
int func_name (float arg1, double arg2, char arg3);
This function will have three arguments:
The first float, second a double, and third a char. It returns an integer value. It could
also have been written in short as:
int func_name (float, double, char);
18
C++
Let us explore a new facility in C++ which is not available in C. i.e. Default
parameters. This reduces a lot of redundant coding in C++.
Default Parameters :
If a function is defined as accepting two integer parameters, and it is called with only
one integer, it will result in an error. This can be arranged to be syntactically correct
if we define initial values for the parameters. This is illustrated in the following
program:
Program:
#include<iostream.h>
void func (int a=0, int b=10)
{
cout <<" a=" <<a
<<" b=" <<b
<<"\n";
}
main()
{
int c=100, d=300;
func(c,d);
func(c);
func( );
}
Output:
a=100 b=300
a=100 b=10
a=0 b=10
While the above program will not work in C, it is error free in C++. The function
func() can be called with two, one or no parameters because the missing parameter
can always be used as it is initialized with some value. The program output would
look like this:
Thus we see that C++ behaves on three different levels with the programmer.
1) On one extreme it demands a rigid prototyping habit.
19
C++
2) On the moderate level it allows the programmer to specify default values, but
when the programmer fails to define his own parameters, the default
parameters help him out.
If the prototype of the above function is to be specified, it is written in the following
way.
void func (int, int);
It would result in an error. Since the compiler first looks at the prototype default
values must also be specified in the prototype declaration too. Hence the prototype
must be specified thus:
void func (int=0, int=10);
Storage Classes
There are two categories of storage classes - the declarable and the non-declarable.
As in C, automatic, static and extern are the declarable storage classes. Dynamically
allocated objects form a non-declarable storage class.
Declarations and Definitions.
Automatic :
An instance(object) of a class is similar variable. Hence local variables in functions
are created on the stack. The constructor is called at the point of declaration and the
destructor is called when the scope (closing brace) ends.
Extern :
The extern keyword tells the compiler to defer allocation. An initializer is not allowed
in a declaration. For example:
extern int y;
extern const start
struct person;
// Names a variable.
//Names a constant. Defers storage allocation.
//Names a structure type. The members
// are not defined and the size of the struct is not known.
For a variable, a definition provides both a name, type, memory and allows
initialization.
20
C++
The extern keyword defines EXTERNAL variables. These are defined in one file and
to use it in another file it should be declared thus: extern int file1_variable;
Static Data Members :The static member variable has certain special characteristics :
1) It is initialized to zero when the first object of its class is created.
2) 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
3) It is visible only within the class but its lifetime is the entire program.
Static variables are normally used to maintain values common to the entire class.
#include<iostream.h>
#include<conio.h>
class test
{
static int ctr; //static variable ctr
int no;
//normal variable no
public : void getdata(int a)
{
no=a;
ctr++;
}
void getctr(void)
{
cout<<ctr=<<ctr<<endl;
}
void getno(void)
{
cout<<number=<<no<<endl;
}
};
int test::ctr;
void main()
{
test t1,t2,t3; //static variable ctr is initialized to zero
t1.getctr();
t2.getctr();
t3.getctr();
21
C++
t1.getdata(10);
t2.getdata(20);
t3.getdata(30);
t1.getctr();
t2.getctr();
t3.getctr();
t1.getno();
t2.getno();
t3.getno();
}
OUTPUT :
ctr
no
0
0
0
1
2
3
10
20
30
function()
t1.getctr()
t2.getctr()
t3.getctr()
t1.getdata()
t2.getdata()
t3.getdata()
output
ctr=0
ctr=0
ctr=0
-
t1.getctr()
t2.getctr()
t3.getctr()
ctr=3
ctr=3
ctr=3
t1.getno()
t2.getno()
t3.getno()
number=10
number=20
number=30
Static Member Functions :Features of static member functions :1) A static function can have access to only other static member(function or
variables)declared in the same class
2) A static member function can be called using the class name(instead of its
objects) as follows :
class-name :: functionname
#include <iostream.h>
class test
22
C++
int no;
//normal variable
static int ctr;
//static variable
public : void setno(void)
{
no=++ctr;
}
void showno(void)
{
cout<<object number=<<no<<endl;
}
static void showctr(void)
{
cout<<count=<<ctr<<endl;
}
};
int test :: ctr ;
void main()
{
test t1,t2;
t1.setno();
t2.setno();
test :: showctr();
test t3;
t3.setno();
test :: showctr();
t1.showno();
t2.showno();
t3.showno();
}
Explanation :
ctr
no
function
output
1
2
1
2
t1.setno()
t2.setno()
23
C++
test::showctr()
t3.setno()
test::showctr()
t1.showno()
t2.showno()
t3.showno()
count=2
count=3
object number=1
object number=2
object number=3
Global :
A global (extern or static) variable is alive for the entire program. It is declared above
the main () in the program.
Scoping :
'Scoping' rules define the blocks or file where a variable is accessible, and when it gets
created or destroyed.
Scope Rules
Local or Block Scope :
Same as in C. In C++, an object declared in a block is said to be in block scope. It is
visible within the block from the point of declaration, and to all the blocks that are
embedded within this block.
File Scope :
An object declared outside any function body, is visible from the point of declaration
to the end of the file.
Function scope :
Variables defined in a function are seen within that function.
main()
{
int variable1 ;
//only variable1 accessible
{
int variable2;
//variable variable2 accessible
}
//here variable2 is destroyed
//only variable 1 accessible
24
C++
}
//variable 1 is destroyed here
//neither variable1 nor variable2 accessible here
An aspect of C++ that differs from C, and is very useful, the data can be declared on
the fly. This means the declarations need not be restricted only to the start of a block.
They can exist among the executable statements and sometimes also within them.
Program:
#include <iostream.h>
int a=20;
main()
{
{
}
++a;
int b=10;
}
int b=210;
}
Global :
Global Variables are defined outside all of the functions blocks, and are available
throughout the file and also to other files. Suppose that the following is contained in
one file:
The following code shows were the variables variable1, variable2, and variable3 are
available and where unavailable.
int globalvariable;
main()
{
globalvariable=20;
}
25
C++
In C when a local variable has the same name as a global variable in the block, the
global variable is inaccessible. This handicap is overcome in C++. Using the symbol ::
before the variable name indicates that the global variable is to be used, and not the
local synonym. An example follows.
Program:
#include <stdio.h>
int p = 100; //global variable
main()
{
int p;
p =50;
printf("%d\n", p,::p);
{
int p = 25;
printf("%d%\n" ,p, ::p);
}
Local :
Variables are defined within a block, i.e. within a function. They are 'automatic' by
default. This means that they are automatically created when the function is entered,
and destroyed when the function is exited. To declare a variable as automatic the
word 'auto' has to precede the declaration.
e.g.auto int i:
Register int i :
Local variables can also be declared of type 'register'. This causes the compiler to
access i as fast as possible.
Control Structures
The statement for controlling program flow are:
if-else,
for,
while,
break,
do-while,
continue,
switch statement.
C++
Global Variables
Accessible by any function
Accessible only by function A
Local
Variables
Local variables
Function A
Function B
27
C++
Conditional Statements
1) if-else
2) switch statement
1)
if-else :
The if statement will execute a body of itself when the condition is true otherwise it
will execute the body of else.
Forms of if-else
a)
if(conditional expression)
{
statement(s) to be performed if expression is true.
}
b)
if(conditional expression)
{
statement(s) to be performed if expression is true;
}
else
{
statement(s) to be performed if expression is false
}
28
C++
Nested if-else
c)
if(conditional expression)
d)
false
if(conditional expression)
false
true
true
statement(s);
if(conditional expression)
false
else
false
{
if(conditional
true
expression)
{
false
false
false
statement(s);
true
else
false
statement(s)
}
statement(s);
else
statement(s);
else
}
statement(s);
}
Example :
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
void main()
{
int s1,s2,s3,avg;
cout<<"Enter the marks of three subjects:";
cin>>s1>>s2>>s3;
if(s1<35 || s2<35 || s3<35)
{
cout<<"The student is fail";
getch();
exit(0);
29
C++
}
avg=(s1+s2+s3)/3;
if(avg>=35 && avg<45)
cout<<"The student is in third division";
if(avg>=45 && avg<50)
cout<<"The student is in second division";
if(avg>=60 && avg<75)
cout<<"The student is in first division";
if(avg>=75)
cout<<"The student has got distinction";
getch();
}
Switch - Case :
The switch and case keywords evaluate expression and execute any statement
associated with constant-expression whose value matches the initial expression. If
there is no match with a constant expression, the statements associated with the
default keyword are executed. If the default keyword is not used, control passes to the
statement following the switch block.
switch (expression)
{case value1 : statement; break;
case value2 : statement; break;
case value3 : statement; break;
()
default
: statement;
}
The following is a menu program the uses the switch statement:
Program:
#include <iostream.h>
main()
{
int esc = 0;
char inkey;
while (esc == 0)
{
cout<<"selct a,b,c, or q to quit";
cin>>inkey;
switch(inkey)
30
C++
{
case 'a':cout<<"a has been selected\n";
break;
case 'b':cout<<"b has been selected \n";
break;
case 'c':cout<<"c has been selected \n";
break;
case 'q':cout<<"I quit \n";
esc = 1;
default :cout<<"please choose only a,ba,c,q\n";
}
}
}
C++
}
cout<<sum=<<sum;
}
INPUT :
enter one number=2
enter one number=3
enter one number=7
enter one number=4
enter one number=9
OUTPUT :
Sum=25
Explanation :
ctr
ctr<=5c
ondition(true/false)
sum+no=sum
1
1<=5
true
2
2<=5
true
3
3<=5
true
4
4<=5
true
5
5<=5
true
6
6<=5
false
no
2
3
7
4
9
-
0+2
2+3
5+7
12+4
16+9
=2
=5
=12
=16
=25
-
Do While :do
{
do this;
}
while(condition);
true
false
C++
int no,sum=0;
char ch;
do
{
cout<<"enter one number="<<endl;
cin>>no;
sum=sum+no;
cout<<"do you want to enter number again(y/n)=";
fflush(stdin);
cin>>ch;
}
while(ch=='y');
cout<<"sum="<<sum;
}
Input :
ch
y
y
n
condition(true/false)
true
true
false
For
The for statement first initializes the loop, then tests the condition, then goes through
the loop and at the end does some form of stepping.
for ( initialization;expression;step ) //no semicolons
{ statement A}
for(initialisations ;condition ;increment/decrement )
33
C++
false
{
false
true
do this;
}
The expression is evaluated before each iteration and executes the statement only if
true. At the end of the loop the step is executed. Any of the above expressions initialization, expression, step or statement may be empty.
for (;i<10;)
The for loop is usually used for counting purpose.
Inside a loop, the flow can be controlled using break and continue. To quit the loop at
any point use the break keyword. Continue skips over the rest of the statements in
the loop, and goes on to the next iteration. For example look at two loops:
for(i=0;;++i)
{
statements..
if ( i==100 ) break;
statements
}
Here the loop will execute infinitely if it were not for the break statement which
causes exit from the loop at he 101 st iteration
Nested For Loop :
for(initialize;condition;increment/decrement)
false
true
{
for(initialize;condition;increment/decrement)
false
{
true
do this ;
34
C++
false
}
}
Example :
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void main()
{
int row,col;
for(row=1;row<=3;row++)
{
for(col=row;col<=3;col++)
{
printf(*);
}
printf(\n);
}
getch();
}
Output :
***
**
*
Explanation :
row
1
true
2
3
4
3<=3
true
2<=3
3<=3
4<=3
true
true
false
3<=3
true
35
*
*
No Output(\n)
*
C++
4<=3
4<=3
false
false
-
No Output(\n)
-
Exercise
Chapter -4
CLASSES AND OBJECTS
Structures :
A structure is a collection of data of similar or different data types. It can represent a
record.
Creating structure :
On creating a structure a new datatype is defined. This definition creates a new
datatype for future use. Variables of this data type can be then declared and used like
the basic data types. For example, if the details of a student is to be stored, the
following structure is used.
struct StudentDetail
{
int
RollNum;
char Name [40];
int
Marks [6];
36
C++
float
char
Percent;
Grade;
};
Example:
struct StudentDetail
{
int
RollNum;
char Name [40];
int
Marks [6];
float Percent;
char Grade;
}s
[50];
struct Object1;
The keyword struct is used to define the structure Object1. The user-defined name
StudentDetail is a tag, which is used at the time of declaring a structure variable. the
above examples give the declaration and initialization of structures, structure
pointers and structure arrays. The first example declares only one structure to store
details of an individual student, whereas the second declares an array of structure to
store detail of 50 students of the entire class.
Data Encapsulation :
Consider the structure,
struct number
{
public: int p;
};
The keyword public makes p available to all those who knowingly or unknowingly use
it. It is not guarded from outside interference. Any statement can now use it as
though it were just another structure member.
Similarly
struct number
{
private: int p;
}
37
C++
The 'private' protects the variable p, restricting its use to its private zone, and thus
ensuring that even accidentally the data cannot be touched or tampered with. This is
the concept of Data Encapsulation.
Class and Objects :
Definition :
A Class is an abstract datatype which contains data and the functions that access that
data. An Object is an instance of a class.
Here we are not concerned about how the addition of two complex numbers is taking
place. We are only concerned about the fact that adding two complex numbers adds
their real parts and their imaginary parts respectively. The actual operations on the
data is hidden. These operations are done by Methods. These methods are the
member functions of the class that operate on the data. The picture of the Class and
the Objects is shown in the fig.
Class
Data
Member Function
Member Function
Object
Object
Data
Data
Member Function
Member Function
Member Function
Member Function
38
C++
39
C++
Public :
Every attribute and member function declared between the public keyword and the
end of the class is available to the user as well as member functions of the class itself.
In the example class number above, member function display is public and hence can
be accessed by users of this class.
Program:
#include <stdio.h>
#include <iostream.h>
class integer
{
private :
int i;
public:
void print(void)
{
i=10;
printf("PUBLIC
MEMBER i=%d" ,i);
}
};
void main(void)
{
integer num;
num.print();
}
FUNCTION
ACCESSING
PRIVATE
Output:
PUBLIC FUNCTION ACCESSING PRIVATE MEMBER I=10
Data Hiding :
The private and public sections of a class are given by the keywords "private" and
"public" respectively. All the variables and the functions declared in a class, whether
in the private section, are the member if the class. The keywords - private and public
- in a class determine the accesibility of class members. However, a program can
access the private members of a class only by using the public member functions of
the class as shown in the figure below. This insulation of data members from direct
access in a program is called as INFORMATION HIDING or DATA HIDING.
40
C++
PROGRAM:
#include <iostream.h>
#include <stdio.h>
class A
{
private: int x;
public :
void set(int b)
{
x= b ;
}
void print()
{
cout <<x<<"\n";
}
//iostream.h used
};
main()
{
A object1,object2;
object1.set(105);
object1.print();
object2.set(60);
object2.print();
getchar();
}
Output :
//stdio.h used
105
60
Private
Data or Functions
Not accessible
from outside class
41
C++
Public
Accessible
outside class
Data Abstraction :
It helps in separating the computer's view of data from that of a human. In other
words, data abstraction represents information in terms of its interface with the user.
Once the data structure has been designed, functions can be defined to operate on it.
These functions can be stand alone functions like the traditional C language functions
or functions declared in that structure. This bundling together of data and the
functions that operate on that data is called as DATA ENCAPSULATION.
First level Abstraction :
In the diagram we see that the programmer cannot see the real data, but can only
access the data in a very specific manner using the Methods. In the figure the four
data items can be accessed in only six different ways using six Methods.
Second level Abstraction :
We can have more than one layer between the programmer and the data as shown in
the fig. This is called Second layer of Abstraction. Data is private and can be accessed
by three private methods which in turn are accessed by other three public methods by
the programmer. Here it is called two layered Data Abstraction.
Methods
private
public
m1
m2
d1
d2
m3
42
m4
C++
Data
Encapsulated
d3
m5
d4
m6
Methods
data
m1
data
m2
data
m3
private
private
layer 1
layer 2
Methods
Programmer
MA
MB
MC
public
43
C++
// Distance class
// Hidden Data
// set distance
44
C++
void getdist()
// get Length from user
{
cout <<"\nenter feet: ";
cin >> feet;
cout <<"\nEnter inches: "; cin >> inches;
}
void showdist()
// display distance
{
cout << feet <<"--"<< inches <<"\n" ;
}
};
void main()
{
Distance dist1, dist2;
dist1.initdist(11,6.25);
dist2.getdist();
}
Here:
Distance is a class.
dist 1,dist 2 are objects of class Distance.
initdist (), getdist() and showdist() are methods that acesses.
feet and indhes which is the private data.
"this" pointer :
When a method is invoked a pointer is passed to it which identifies the one object
(among the many objects that may belong to the same class) that we want to use. This
pointer is called 'this'. The built in pointer, 'this', points to the object being processed.
#include <iostream.h>
class number
{
private:
int p;
public:
void assign(int q)
45
C++
this->p=q;
}
void display (void)
{
cout <<this->p<<"\n";
}
};
void main()
{
number n,m;
n.assign(100);
m.assign(200);
n.display();
m.display();
}
Output:
100
200
data
this
data
Pointer
method
method
C++
int age;
char name[15];
public : void getdata(void);
void putdata(void);
};
void employee :: getdata(void)
{
cout<<"Enter name="<<endl;
cin>>name;
cout<<"Enter age="<<endl;
cin>>age;
}
void employee :: putdata(void)
{
cout<<"Name="<<name<<endl;
cout<<"Age="<<age<<endl;
}
void main()
{
employee manager[3]; //Array of object
for(int i=0;i<3;i++)
{
cout<<"\n Details of manager :"<<i+1<<"\n";
manager[i].getdata();
}
for(i=0;i<3;i++)
{
cout<<"\n Manager :"<<i+1<<"\n";
manager[i].putdata();
}
}
Interactive Input :
Program Output :
Details of manager :1
Enter name=kashyap
Enter age=23
Manager :1
Name=kashyap
Age=23
Details of manager :2
Enter name=Bhushan
Enter age=25
Manager :2
Name=Bhushan
Age=25
47
C++
Details of manager :3
Enter name=Mitesh
Enter age=22
Manager :3
Name=Mitesh
Age=22
C++
time t1,t2,t3;
t1.gettime(2,45);
t2.gettime(3,30);
t3.sum(t1,t2);
t1.puttime();
t2.puttime();
t3.puttime();
//t3=t1+t2
//display t1
//display t2
//display t3
OUTPUT :
2 hours and 45 minutes
3 hours and 30 minutes
6 hours and 15 minutes
hr
min
6
15
t1.hr
t1.min
2
45
t2.hr
t2.min
30
(t1+t2)
t3.sum(t1 , t2)
Friend Functions :
Friend function possesses certain special characteristics :
a) It is not in the scope of the class to which it has been declared as friend.
b) Since it is not in the scope of the class, it cannot be called using the object of
that class. It can not be invoked like a normal function without the help of
any object.
c) Unlike member function, 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).
d) Usally, it has object as arguments.
Example :#include<iostream.h>
49
C++
#include<conio.h>
class B;
//Forward declaration
class A
{
int a;
public : void seta()
{
cout<<"enter first number="<<endl;
cin>>a;
}
void friend max(A,B);
};
class B
{
int b;
public : void setb()
{
cout<<"enter second number="<<endl;
cin>>b;
}
void friend max(A,B);
};
void max(A a1 , B b1)
//Definition of friend function
{
if(a1.a>b1.b)
cout<<"first number is greater";
if(a1.a<b1.b)
cout<<"second number is greater";
if(a1.a==b1.b)
cout<<"both numbers are equal";
}
void main()
{
A a2;
a2.seta();
B b2;
b2.setb();
max(a2,b2);
}
Returning Objects :
A function can not only receive objects as arguments but also can return objects to
another function.
50
C++
Example :
#include<iostream.h>
#include<conio.h>
class complex
//x+iy form
{
float x;
// real part
float y;
//imaginary part
public : void input(float real , float imag)
{
x=real;
y=imag;
}
friend complex sum(complex , complex);
void show(complex);
};
complex sum(complex c1, complex c2)
{
complex c3;
//object c3 is created
c3.x=c1.x+c2.x;
c3.y=c1.y+c2.y;
return(c3);
}
void complex :: show(complex c)
{
cout<<c.x<<"+ j"<<c.y<<"\n";
}
void main()
{
complex A,B,C;
A.input(3.1 , 5.65);
B.input(2.75,1.2);
C=sum(A,B); //C=A+B;
cout<<"A=";A.show(A);
cout<<"B=";B.show(B);
cout<<"C=";C.show(C);
}
Output :
A=3.1+j5.65
B=2.75+j1.2
51
C++
C=5.85+j6.85
Exercise
Chapter - 5
POLYMORPHISM
Function Overloading :
Definition :
When several different function declarations are specified for a single name in the
same scope, that function is said to be overloaded. When that name is used, the
correct functions is selected by comparing the types of the actual arguments with the
types of the formal arguments.
52
C++
Explanation :
In C, if in the same scope we had two function definitions with the same name, it
would be an error. Thus if we wanted to display a char, a float and an int, we would
have to write three functions: one accepting a char argument, one a float and one an
int. Each function would have to be given a different name and we would have to
remember three names just to display some variable. If we had a lot of datatypes, the
list of names would grow so long. C++, however, allows the functions to be
differentiated, not only by their names, but also by the datatypes of their arguments.
Thus different functions can be called by the same name and different argument
datatypes.
Program :
#include <stdio.h>
void print(char *a)
{
printf("%s\n",a);
}
void print(int a)
{
printf("%d\n",a);
}
void print(float d)
{
printf("%f\n",d);
}
main()
{
char *s= "National Computers";
int i = 100;
float f = 123456.78;
print(f);
print(s);
print(i);
}
Output :
123456.78
National Computers
100
53
C++
This feature is called function overloading. Another point about function overloading
is that the compiler differentiates the functions according to their argument types
and Not according to their return types. Thus the following prototypes will not be
acceptable:
int sum (float, float);
float sum (float, float);
Overloading Rules :
In order to match the arguments and make a call, C++ follows rules:
1. Exact match.
2. int to double conversion.
3. Any user defined conversion i.e. provided as constructors for the user defined
class taking single parameter as a reference to another user defined or inbuilt
type or as conversion functions.
print (float)
___________
___________
___________
print (f);
___________
___________
___________
print (s)
___________
___________
___________
print (i);
___________
___________
___________
print (char)
print (int)
54
C++
}
Member functions of two different classes may have the same name as the default
parameter would differ. Strictly speaking, these functions are in different (class)
scopes.
Inline Functions :
C++ allows functions to be defined with a new keyword inline. Inline functions,
unlike conventional functions, do not result in a call to a single functions; rather, the
code for the inline function expands in place wherever the function is used. To inline
a function the programmer adds the keyword inline in front of the definition.
inline min(int n1, int n2)
{ return (n1<n2) ? n1 : n2;
The inline functions are faster as the compiler just picks the code and thus slower
stack operations are obviated. Unlike MACROS, they are part of the C++ language
and are not processed by the preprocessor.
55
C++
Strings :
The string manipulation routines allow you to compare strings, copy them, search for
strings and characters, and perform various other operations. All the functions of
strings that are valid in C are all valid in C++. To have an access to all the functions
listed below, one has to include "string.h" header file.
Routine
Description
Strcat,
strchr,
fstrcat
fstrchr
strcmComp
strcpy,
strcspm,
fstrcmp
fstrcpy
fstrcsn
strdup,
sterror
fstrdup
sterror
stricmp,
fstricmp
strlen,
strwr,
strncat,
strncmp,
strncpy,
fstrlen
fstrlwr
fstrncat
fstrncmp
fstrncpy
strnicmp,
fstrnicmp
strnset,
fstrnset
strpbek,
fstrpbrk
strchr,
fstrrchr
strrev,
strset,
strstr,
fstrrev
fstrset
fstrstr
strupr,
fstrupr
56
C++
Input / Output
In C++, there are facilities for performing input and output known as streams.
Cout :
The Standard Output Stream: cout
The name cout represents the standard output stream. You can use cout to display
information:
#include <iostream.h>
void main(0)
{ count << "Hello, world\n";}
The string Hello, word\n is sent to the standard output device, which is the screen.
The << operator is called the insertion operator. It points from what is being sent
(the string) to where is going (the screen). Suppose you want to print an integer
instead of a string. In C, you would use printf with a format string that describes the
parameters:
printf(%d", amount );
The program sends three different data types to cout; a string literal, the integer
amount variable, and a character constant '.' to add a period to the end of the
sentence. Notice how multiple values are displayed using a single statement. The <<
operator is repeated for each value.
Formatted Output :
So far, the examples haven't sent formatted output to cout. Suppose you want to
display an integer using hexadecimal instead of decimal notation. The prinf function
handles this well. How does cout do it? Let's face it.
Program:
#include <iostream.h>
main()
{
int amount = 123;
cout <<dec << amount <<' '
<< oct << amount <<' '
<< hex << amount;
57
C++
}
Output:
123 173 7b
The example inserts each of the manipulators (dec, oct, and hex) to convert the value
in amount into different representations. Each of the values shown is a different
representation of the decimal value 123 from the amount variable. Let us take one
example to see all different types of datatypes and the streams.
Program:
#include <iostream.h>
main()
{
int i = 65535U;
cout << "i =" << i << "\n";
long int l = 42294967295L;
cout <<"l =" << l << "\n";
cout << "i = " << unsigned(i) <<"\n";
cout << "l = " << ( unsigned long ) l << "\n";
}
Cin :
The standard Input Stream: cin
At times you may want to read data from the keyboard. C++ includes its own version
of standard input in the form of cin. The next example shows you how to use cin to
read an integer from the keyboard.
Program:
#include <iostream.h>
void main()
{
int amount;
cout << "Enter an amount... \n";
cin >> amount;
cout << "The amount you entered was " << amount;
}
58
C++
This example prompts you to enter an amount. Then cin sends the value that enter to
the variable amount. The next statement displays the amount using cout to
demonstrate that the cin to read other data types as well. The next example shows
how to read a string from the keyboard.
Program;
#include <iostream.h>
void main()
{
char name[20];
cout << "Enter a name... \n";
cin >> name;
cout <<"The name you entered was " << name;
}
The approach shown in this example has a serious flaw. The character array is only
20 characters long. If you type too many characters, the stack overflows and peculiar
things happen. The get function solves this problem. For now, the examples assume
that you will not type more characters than a string can accept.
Common Manipulators Stream Format Control Functions :
Manipulator
Member Function
Description
Dec
Hex
Oct
setfill( c)
setprecision(c)
setw(n)
flags(10)
flags(16)
flags(8)
fill(c)
precision (c)
width(n)
Set radix to 10
Set radix to 16
set radix to 8
Set the fill char'r to c
Set display precision to c
set field width
C++
Program:
#include <iomanip.h>
#include <iostream.h>
main()
{
cout.setf(ios::right|ios::showpoint|ios::fixed);
cout.precision(2);
cout.width(20);
cout<<500000.0 << "\n";
}
The following table shows the details of methods associated with cout. They all are
part of the basic class ios.
60
C++
Value Meaning
ios::skips
ios::left
ios::right
ios::internal
ios::dec
iosoct
ios::hex
61
C++
ios
istream
ostream
isstream
ofstream
istream_withassign
iostream
ifstream
stream_withas
sign
ostream
strstream
fstream
streambuf
stdiostream
iostream_init
filebuf
strstreambuf
stdiobuf
Manipulators :
There are two types of Manipulators: Input and Output Manipulators allow you to
add functions into the streams itself reducing the code. One has to include the
<iomanip.h> file to implement these manipulators.
Program :
62
C++
#include <iostream.h>
#include <iomanip.h>
ostream & setup(ostream &st)
{
st.setf(ios::left);
st << setw(10) << setfill ('$');
return st;
}
main()
{
cout <<10<< " " <<setup << 10;
}
Output:
10 10$$$$$$$$
Exercise
Chapter - 6
CONSTRUCTORS AND DESTRUCTORS
63
C++
Constructors
Definition :
A 'Constructor' is a method that has the same name as its class and is automatically
executed only at the time of declaration of an object of the class. A constructor cannot
be invoked by a user or explicitly called.
Consider the following program on a simple constructor.
Program :
#include <iostream.h>
class C1
{
private: int p,q;
public: C1 (int a =0, int b=0)
{
p=a; q=b;
}
int add (int a)
{
return (p+q+a);
}
int add (C1 a)
{
return (p+a.p+q+a.q);
}
void display (void)
{
cout <<p<<" "<<q<<"\n";
}
};
main()
{
C1 n,m(200);
n.display();
m.display();
int I=n.add(10);
cout<<I<<"\n";
int j=n.add(m);
cout<<j<<"\n";
64
C++
}
Output:
00
200 0
10
200
What a Constructor Does ?
A constructor performs various tasks that are not visible to you as the programmer,
even if you write no code for the constructor. These tasks are all associated with
building a complete and correct instance of class type. Constructors are called at the
point an object is created. Objects are created as:
1. Global (file-scoped or externally linked) objects.
2. Local objects, within a function or smaller enclosing block.
3. Dynamic objects, using new operator allocates an object on the program heap
or "free store".
4. Temporary objects created by explicitly calling a constructor.
5. Temporary objects created implicitly by the compiler.
6. Data members of another class. Creating objects of class type, where the class
type is composed of other class-type variables, causes each object in the class
to be created.
7. Base class sub-object of a class. Creating objects of derived class type causes
the base class components to be created.
Types of Constructors :
C++ defines two special kinds of constructors, default and copy constructors.
1.
Default Constructor :
It can be called with no arguments. It Construct a default object of the class
types. However, you can declare a default constructor with an argument list,
provided all arguments have default.
2. Copy Constructor :
It can accept a single argument of reference to same class type. Copy objects
of the class type. Copy constructors must be declared in such a way that they
can accept a single argument of reference to the same class type. More
arguments can be supplied, provided all subsequent arguments have default.
65
C++
C++
vector v21=v1;
// copy constructor called.
vector v3 (10);
v3 = v2
// overloaded assignment operator called.
Let us see program on copy constructor.
Program :
#include<iostream.h>
class code
{
int id;
public:
code(){}
code(int a){id=a;}
code(code &x)
{id=x.id;}
void display()
{
cout<<id;
}
};
void main()
{
code A(100);
code B(A);
code C=A;
code D;
D=A;
cout<<"\nid of A:"; A.display();
cout<<"\nid of B:"; B.display();
cout<<"\nid of C:"; C.display();
cout<<"\nid of D:"; D.display();
}
Output:
id of A:100
id of B:100
id of C:100
id of D:100
Destructor
67
C++
A 'Destructor' is a method that has the same name as the class, but preceded by a
tilde (-) mark. A destructor is executed at the time of destroying the object, and
cannot be invoked by us or explicitly called. "Destructor" functions are the inverse of
constructor functions. They are called when objects are destroyed (deallocated). The
destructor is commonly used to "clean up" when an object is no longer necessary.
Consider the following declaration of a String class. The destructor for class String is
declared as - String().
Class String
{
public:
String(char*ch); //Declare constructor
~String():
// and destructor.
private:
char*_text;
}
Let us see how a constructor and a destructor face each other in a same program and
how they are declared.
Program :
#include<iostream.h>
class C1
{
private:
int p;
public:
C1 (void)
{
p=100;
cout<<"\n Constructor.p="<<p;
}
C1 (int q)
{
p=100;
cout<<"\n Int Constructor.p="<<p;
}
void display (void)
{
p=300;
cout<<"\nDisplay.p=" << p << "\n";
}
68
C++
~C1(void)
{
cout<<"\nDestructor";
}
};
void main()
{
C1 n,m(200);
n.display();
m.display();
}
Output:
Constructor.p=100
Int Constructor.q=200
Display.p=300
Display.p=300
Destructor.
Destructor.
Rules for Constructors / Destructor :
1.
C++
function. One should not call the destructor until it is required - typically for
hardware addresses that are never deallocated, as they begin at a specific
predetermined address.
Exercise
70
C++
Chapter - 7
POINTERS
Definition :
Pointers are variables that carry addresses of memory locations that contain data of a
particular type. It should be noted that a pointer need not be initialized at the time of
definition as the following example might suggest. The program illustrates some
types of pointer to variables:
class Class { };
void main()
{
unsigned char uc;
unsinged char*ucp=&uc;
Void Pointer :
Different pointers may be of different sizes internally. Void pointers also exist. A void
pointer means a pointer to any data type. The use of the keyword void to describe a
pointer is different from its use to describe function argument lists and return values.
Thus function that is declared thus:
func 1 (void*ptr)
{}
can accept a pointer to any data type. Thus in this case the function calls:
func 1 (&c); and
func 1 (&d);
where c and d are of type char and double respectively, are valid. Since different
pointers may be of different sizes, the void pointer will be at lleast as large as the
largest typed pointer, so as to be able to accommodate any pointer, inside the
function however, we need to know what kind of pointer was C1. One method that
could be used is illustrated in the following program:
71
C++
Program:
#include<iostream.h>
enum dtype{
chartype,
inttype,
floattype};
void display (void* ptr, dtype whichtype )
{
switch (whichtype)
{
case inttype :
cout<<"int="<<*( (int*)ptr )<< "\n";
break;
case chartype :
cout<<"char="<<(*( ( char * )ptr ))<<"\n";
break;
case floattype :
cout<<"float ="<<*( (float *)ptr )<<"\n";
break;
}
void main()
{
int i =100;
char c ='C';
float f = 123.456;
display( &i, inttype);
display( &c, chartype);
display( &f, floattype);
}
Pointers have four main uses :
Arrays
Function arguments
Direct memory access,
Dynamic memory allocation.
72
C++
Output
array[0]=a
array[1]=b
array[2]=c
array[3]=d
array[4]=e
73
C++
array[5]=f
array[6]=g
i=0*(cp+i)=a
i=1*(cp+i)=b
i=2*(cp+i)=c
i=3*(cp+i)=d
i=4*(cp+i)=e
i=5*(cp+i)=f
i=6*(cp+i)=g
array[0]=h
array[1]=i
array[2]=j
array[3]=k
array[4]=l
array[5]=m
array[6]=n
This program shows that a pointer to the starting address of an array can be treated
like the array itself. Once the pointer cp is assigned to the starting address of array,
the pointer can be used instead of the array itself. char *cp is the same as cp[], if the
array isn't external. When cp[i] is assigned a new value, the array[i] is also assigned.
In the next program there is a demonstration of array indexing. It shows three
different ways of selecting the zeroth element, and prints the array using pointer
addition.
Program:
#include <iostream.h>
void main()
{
int arr[20];
for (int i=0; i<20; i++)
arr[i] = 200 - i*i;
cout<<"arr[0]="<<arr[0]<<"\n";
cout<<"*(arr+0) ="<<*(arr+0)<<"\n";
cout<<"*arr ="<<*arr<<"\n";
for(int i=0;i<20;i++)
cout<<"*(arr + " <<i <<") ="<<*(arr+i)<<"\n";
}
A definition of the type
C++
creates a global array and also initializes it to the values given. This is called
aggregate initialization. You can treat it as an array, for example;
void func()
{
char *str = "NATIONAL COMPUTERS.\n";
cout<<str[2];
}
Output:
An array of pointers is very useful construct. An example of this is the second
argument that the main function can take:
char*argv[]; or char**argv;
The following example takes command line arguments and concatenates them.
Program :
#include <iostream.h>
void main(int argc, char*argv[])
{
char buffer[100];
char*bufptr=buffer;
for( int i=0;i<argc; i++)
for (char *ptr=argv[i]; *ptr ;ptr++)
*bufptr++ = *ptr;
*bufptr = 0;
// this terminates the string
cout<<buffer<<"\n";
}
This program creates a character buffer to hold the finished string, defines a pointer,
assigns it to the starting address of the buffer, and uses it to stuff characters into the
buffer.
Pointers in Function arguments :
When you want a function to change the value of any of its arguments when it
returns, you should declare a pointer to the variable as argument instead of declaring
the variable itself. When a variable is declared as argument i is actually copied onto a
local variable inside the function and any changes made to that variable in that
75
C++
function are destroyed along with the local variable so the changes do not affect the
original variable. On the other hand if a pointer to a variable within the function
changes are made to the actual variable and so the modifications are preserved.
Thus in the following code i will be 10 at the first printf() statement and i will be 20 at
the next.
Program:
#include<iostream.h>
#include<conio.h>
void swap(int &a, int &b)
{
int t=a;
a=b;
b=t;
}
void main()
{
int x=10,y=20;
cout<<x:<<x<< y:<<y;
swap(x,y);
cout<<x:<<x<< y:<<y;
}
output:
x:10 y:20
x:20 y:10
Here the & operator is used to declare the address of the variable i to the function.
The & is a unary operator that returns the memory address of the variable it is
prefixed to.
Direct Memory access
Sometimes we would like to access memory directly. Examples of this is the video
memory in PC's and memory mapped I/O in some computers. Sometimes it is
possible to determine the size of some object or group of objects, only at run time. So
these objects cannot be defined beforehand. These objects can be created at run time
by using the 'new' keyword, which returns the address of the allocated memory that
can be assigned to a pointer and used. This process is called dynamic memory
allocation.
76
C++
C++
Once the pointer Another Array goes out of scope in the example above, the object
can no longer be deleted.
Initializing New Objects:
An optional new-initializer field is included in the syntax for the new operator. This
allows new objects to be initialized with user-defined constructors. The following
example illustrates how to use an initialization expression with the new operator:
Program:
#include<iostream.h>
class Acct
{
public:
// Define default constructor and a constructor that accepts
// an initial balance.
Acct()
{
balance = 70.5;
}
Acct(double init_balance) { balance = init_balance;}
private:
double balance;
};
int main()
{
Acct* CheckingAcct=new Acct();
Acct* savingsAcct=new Acct (34.98);
double* HowMuch= new double (43.0);
return 0;
}
Delete Operator
78
C++
The delete operator deallocates an object created with the new operator. The delete
operator has result of type void and therefore does not return a value. The operand to
delete must be a pointer returned by the new operator.
How delete Works :
The delete operator deallocates an object created with the new operator. The delete
operator has a result of type void and therefore does not return a value. The operand
to delete must be a pointer returned by the new operator.
int main()
{
// Allocate a user-defined object.
// of type double on the free store using the new operator.
ClassA*ptrObject = new ClassA;
double *dObject = new double;
return 0;
}
Let us see an example on new and delete with strings.
Program:
#include<iostream.h>
#include<string.h> // required by strlen, and strcpy
class String
{
private:
char *str;
// A traditional string
int size;
// Size of str buffer
public:
String(const char *s);
~String();
void print()
{
cout <<str;
}
79
C++
};
String::String(const char *s)
{
size = strlen(s);
str = new char[size + 1];
strcpy(str,s);
}
String::~String()
{
delete str;
}
void main()
{
String s("String should be easy to use.\n");
s.print();
}
Pointer arithmetic
Pointer arithmetic depends on the type of pointer being used. Suppose a pointer is
pointing to one integer in an array of integers, then the pointer incremented by 1 will
point to the next integer in the array and not the next memory location. The following
program demonstrates pointer arithmetic.
80
C++
Program:
#include<iostream.h>
void main()
{
double d = 123.456, *dp1 =&d, *dp2;
char c = 'A' ,*cp1 =&c, *cp2;
dp2 = dp1+1;
cp2 = cp1+1;
cout<<"cp2-cp1 ="<<cp2-cp1<<"n";
cout<<"dp2-dp1 = "<<dp2-dp1<<"\n";
cout<<"(int)cp2-(int)cp1 ="<<(int)cp2-(int)cp1<<"\n";
cout<<"(int)dp2-(int)dp1 ="<<(int)dp2-(int)dp1<<"\n\n";
cout<<"cp2=cp1,dp2=dp1,(cp2--)--,(dp2++)++.\n";
cp2=cp1; dp2=dp1;
(cp2--);
(cp2--);
(dp2++);
(dp2++);
cout<<"cp1-cp2 ="<<cp1-cp2<<"\n";
cout<<"dp1-dp2 ="<<dp1-dp2<<"\n";
cout<<"(int)cp1-(int)cp2 ="<<(int)cp1-(int)cp2<<"\n";
cout<<"(int)dp1-(int)dp2 ="<<(int)dp1-(int)dp2<<"\n";
}
Here you might expect that subtracting two adjacent doubles might result in 8, but it
would result in 1, signifying the number of double variable between two adjacent
double addresses.
Pointers Examples :
The size of a pointer depends on the size of the address. The Intel 80 x 86
microprocessors, on which he IBM PCs are based, use a segmented addressing
scheme in which the addresses consist of a segment and its offset. The size of a
pointer in this scheme depends on the memory model selected during compilation.
Some programs are small and don't need mush data space.
Pointers Examples :
We will go through some examples of pointer use. The first one reads the standard
input and counts all the various kinds of characters and displays the numbers of
occurrences of each kind of character at the end.
81
C++
Program :
#include <streams.h>
#include <limits.h>
void main()
{
int statistics[CHAR_MAX + 1];
char c;
for(int i=0; i<CHAR_MAX; i++)
statistics[i]=0;
//initialize array
while (cin.get(c)
//for each char input
statistics[c]++;
//use char as index; increment count
for(i=0;i<CHAR_MAX;i++)
if(staatistics[i])
cout<<"number of" <<i<<"."<<chr(i)<<":"<<statistics[i]<<"\n";
}
Check out the output for yourself on the computer. The next program is an example
of how to pass arguments of unknown size. Here a pointer has to be passed. The two
approaches possible are shown.
Program :
#include<iostream.h>
void dispa( const int a[ ], int arraysize)
{
for (int i=0;i<arraysize; i++)
cout <<"a["<<i<<"]="<<a[i]<<"\n";
}
void dispb( const int b[ ] )
{
for ( int i=0; b[i]!=1;i++) //let-1 terminate the array
cout<<"b["<<i<<"]="<<b[i]<<"\n";
}
int c[] = { 43,69,57,47,38,49,-1};
void main()
{
dispa( c, sizeof(c)/sizeof(c[0]));//no.of elements are
82
C++
dispb(c);
}
Since the arrays are declared as pointers, the function may be able to modify the
array. Hence the arguments are defined as const.
Pointers and structures :
The next example demonstrates the C ling of struct and object pointers. When you C1
a pointer to a structure or an object, you must dereference the pointer in a special
way, using the structure pointer operator (->). The operator * refers to the entire
structure, so you can't select individual members using *. The following example
demonstrates what happens when you dereference an entire structure using the *,
instead of individual elements using->.
Program:
#include <stdio.h>
#define PRINT(a) printf (#a"=%d\n",a)
struct st
{
float f;
int p,q,r;
};
void main()
{
st x,y;
st *ptx=&x,*pty=&y;
x.f=0.0;x.p=x.q =y.r=56;
ptx=pty;
//this dereferences the structure
PRINT(x.p);
PRINT(x.q);
PRINT(x.r);
printf("x.f=%f\n",x.f);
}
The program shows that the entire structure is copied from y to x.
Referencing :
A reference is like giving another name for a variable. The statement,
83
C++
int &a=b;
Says that a is a reference to b. The concept is similar to a pointer. If b is changed so
will a, and vice versa. Referencing eliminates the star sing we use while using
pointers. In pointers we 'de-reference' the pointer when we want to use its target
variable. With references we just use the reference as though it were the variable
itself. A program will introduce us to the concept of referencing.
Program:
#include<stdio.h>
void main()
{
int a=5;
int&b=a;
printf("a=%d, b=%d.\n",a,b);
a=100;
printf("a=%d, b=%d.\n" ,a,b);
printf("addr of a=%u, b=%u.\n",&a,&b);
}
Out put :
a=5
b=5
a=100 b=100
a=101, b=101.
addr of a=65500,65500.
Constants and References :
The keyword 'const' used in a data definition, makes the data invulnerable change.
The following statement gives the integer p, a value 50, and makes it value
unchangeable throughout the program:
const int p=50;
This is equivalent to the statement;
int const p=50;
Note that the integer has to be initialized at the time of definition and at that time
only. The following program illustrates the const keyword.
Program :
#include<stdio.h>
84
C++
void main()
{
const int p = 50;
const int& a = p;
printf("p=%d a=%d\n",p,a);
}
Output :
p=50 a=50
Here is an erratic program:
#include <stdio.h>
void main()
{
char *const p ="Sam is a fox";
printf('%s\n",p);
p="Jam in a box";
printf("%s\n",p);
}
Program:
#include <stdio.h>
class C1
{
int p,q,r;
public:
C1(int u=0, int v=0,int w=0)
{
p=u; q=v; r=w;
}
C1 byvalue(C1 A);
C1 bypointer (C1 *A);
C1 byreference(C1& A);
void display (char* msg =" ")
{
printf("%s:p=%d q=%d r=%d\n",msg,p,q,r);
}
};
85
C++
C1 C1::byvalue(C1 A)
{
A.p=A.q=A.r=468;
return (A);
}
C1 C1::bypointer( C1* A)
{
A->p= A->q= A->r=349;
return *A;
}
C1 C1::byreference(C1& A)
{
A.p= A.q= A.r= 198;
return A;
}
void main()
{
C1 A,B;
A.byvalue(B).display("by value");
A.bypointer(&B).display("by pointer");
A.byreference(B).display("by reference");
}
Exercise
Explain pointers in C++.
Explain passing by reference in C++.
Explain the operators which are used for dynamic allocation & deallocation of memory.
Explain pointers and structures in C++.
Fill in the blanks:
1. _____ operator is used allocate memory & ________ is
used to de-allocate the memory.
2. If an integer pointer is incremented then the value of the
pointer increases by ___ why ____________________.
3. ____ operator is used to get the value at address.
86
C++
Chapter - 8
OPERATOR OVERLOADING
Operator Overloading
In fact, C++ allows declaration of overloading operators as a function. In order to
understand what is meant by overloading operators, consider any operator as a
function. All rules that apply to function overloading apply to operators as well.
Differences : Overloading Operator And Overloading Function :The number of arguments for a given operator are predefined (1 for unary, 2 for
binary and 3 for tertiary).
An overloaded operator may appear in the operators natural form rather than the
function call form.
The following operators can be overloaded
new
+
delete
*
&
<
>
+=
-=
*=
/=
&=
^=
&=
|=
<<
>>
>>=
<<=
==
!=
<=
>=
&&
||
++
--
->*
->
()
[]
&
::
87
C++
Operators must either be class member functions or take an argument that is of class
or enumerated type or arguments that are references to class or enumerated types.
1.
2.
3.
4.
5.
Example :
#include<iostream.h>
class time
{
int hr,min;
public :
void gettime(int h,int m)
{
hr=h;
min=m;
}
void puttime(void)
{
cout<<hr<<"hours and";
cout<<min<<"minutes" <<"\n";
}
time operator+(time t1) //objects are arguments
{
time t;
//object t is created
t.hr=hr+t1.hr;
t.min=min+t1.min;
while(t.min>59)
{
t.hr=t.hr+1;
t.min=t.min-60;
}
88
C++
return(t);
t.min)
}
};
void main()
{
time t2,t3,t4;
t2.gettime(2,45);
t3.gettime(3,30);
t4=t2+t3;
//invokes operator+()
cout<<"t2=";t2.puttime();
//display t1
cout<<"t3=";t3.puttime();
//display t2
cout<<"t4=";t4.puttime();
//display t3
}
OUTPUT :
t2=2 hours and 45 minutes
t3=3 hours and 30 minutes
t4=6 hours and 15 minutes
time operator +(time t1)
{
time t;
t
6
6.20
t.hr =
t1.hr (3) +
hr (2) ;
t.min = t1.min (30) + min (45) ;
return (t);
return
t2
2
45
t3
hr
min
3
hr
30
min
Friendships
Definition :
The friend keyword allows programmers to designate either the specific functions or
the classes whose functions can access not only public members but also protected
and private members. In some circumstances, it is more convenient to grant member
89
C++
level access to functions that are not members of a class or to all functions ion a
separate lass.
Member Functions and Classes as Friends :
Class member functions can be declared as friends in other classes as shown.
class A
{
private:
int_a;
friend int B::Func1(a);
class B.
}
class B
{
public:
int Func 1(A a ) { return a._a; } // OK: this is a friend.
int Func 2(A a ) { return a._a } // Error: _a is private member.
};
In the preceding example, only the function B::Func1 (A) is granted friend access to
class A. Therefore, access to the private member_a is correct in function b of class B
but not in function c.
For example, if there were a class branch_manager, which should be allowed to see
into the details of the class account, then we should have the following declaration
within the class definition;
friend class
branch_manager;
Friend Functions
Friend functions are not considered class members; they are normal external
functions that are given special access privileges. Friends are not in the class's scope,
and they are not called using the member-selection operators (.and ->) unless they
are members of another class. The following example shows a Point class and an
overloaded operator, operator+. (This example primarily illustrates friends, not
overloaded operators.)
Program;
// Header file for point class
90
C++
#if !defined(_I_POINT_H_)
#define _I_POINT_H_
#include<conio.h>
class Point
{
int x,y;
public:
Point( int u, int v ) : x(u),y(v) { }
Point() { x=0; y=0;}
void print()
{
cprintf("x->%5d y->%5d\r\n",x,y);
}
Point operator +(Point p)
{
return Point(x+p.x, y+p.y);
}
Point operator -(Point p)
{ return Point(x+p.x,y+p.y);
}
void putch(char c)
{
gotoxy(x,y);
::putch(c);
}
int operator <=(Point p)
{
return x<=p.x && y<=p.y;
}
int operator >(Point p)
{
return (x>p.x && y>p.y);
}
int operator <(Point p)
{
return (x<p.x && y<p.y);
}
int operator ==(Point p)
{
91
C++
C++
Point p = origin;
//top
p.putch(TopLeft);
for ( p+= Point(1,0); p<corner; p+=Point(1,0))
p.putch(Top);
p.putch(TopRight);
//right
for (p+=Point(0,1); p<(corner+Point(1,0));p+=Point(0,1))
p.putch (Right);
// bottom
p.putch(BottomRight);
for (p+=Point(-1,0);p>origin;p+=Point(-1,0))
p.putch(Bottom);
p.putch(BottomLeft);
// left
for (p+=Point(0,-1);p>(origin-Point(1,0));p+=Point(0,1))
p.putch(Left);
}
class Window : public Rectangle
{
public:
Window(Point p, Point q) : Rectangle(p,q) { }
void select()
{
Window(Point(origin.getx()+1, origin.gety()+1),
Point(corner.getx()-1, corner.gety()-1));
}
void fullScreen()
{
Window(Point(1,1),Point(80,25));
}
void open ()
{
select();
clrscr();
fullScreen();
draw();
93
C++
select();
main()
{
clrscr();
Rectangle r1(Point(5,2), Point(40,12));
r1.draw();
gotoxy( 1,15);
r1.print();
Window w1 (Point(6,3), Point(41,13));
w1.open();
w1.fullScreen();
gotoxy(1,18);
w1.print();
w1.select();
for (int i=0; i<100;i++)
w1 <<"Here is"<<" the last line\n";
fullscreen();
gotoxy(1,24);
}
Try the above program and Discuss the Output.
Friends and Manipulators ;
94
C++
Manipulators can also be designed for strings in the similar fashion as we design for
other datatypes. The following example defines a class string with constructors,
destructors and friend manipulators. Note that the class contains only the prototypes
and the definitions are declared after the class declaration.
Program;
#include <iostream.h>
#include <string.h> // required by strlen, and strcpy
class String
{
private:
char*str;
// A traditional string
int size;
// Size of str buffer
public:
String(const char*s);
~String();
friend ostream &operator<<(ostream &os, const String &s);
};
String::String(const char*s)
{
size = strlen(s);
str=new char[size + 1];
strcpy(str,s);
}
String::~String()
{
delete str;
}
ostream & operator<<(ostream &os, const String & s)
{
return os<<s.str;
}
main()
{
String s("make efficient use of memory");
cout <<"strings should also\n"
<<s
<<"\n"
95
C++
<<"and be reuseable.\n";
Exercise
96
C++
Chapter - 9
INHERITANCE
Definition : The mechanism of deriving a new class from an old class is called
inheritance .The old class is referred to as the base class and the new one is called the
derived class
Reusability feature can be achieved with the help of inheritance.It means we can use
something that already exists rather than trying to create the same all over again.It
would not only save the time and money but also reduce frustration and increase
reliability.
Public and Private Inheritance :
With inheritance, there are three types of 'users' of a given class,
a) When an object of the given class type is created.
b) When an attribute of the given class type is used in another class.
c) When another class inherits from the given class.
The Protected keyword
Concept
B
Here Class B is inheriting from class B. Suppose there is private member int x in class
A, then as we know that private member is available only within the class. Therefore
int x will be visible only within the class A, but if we want int x to be available in class
B then we have only one alternative left i.e. we have to declare int x as public, but this
will break the concept of data encapsulation, which is the main feature of OOP
language. So for that we have the third and final access specifier protected. If a
member of a class is declared as protected then this member is not only available
inside the class but also in the class which is inheriting from it.
Protected Member Access :
97
C++
(Derived class)
Example :#include<iostream.h>
class A
{
int c; //private not inheritable
public :
int a,b; //public will be inherited
void getno()
{
a=10,b=20;
}
void sub()
{
c=b-a;
cout<<"substraction="<<c<<endl;
}
};
class B : public A
{
int p,q;
public :
void add()
{
p=a+b;
98
C++
}
void mult()
{
cout<<"addition="<<p<<endl;
q=a*b;
cout<<"multiplication="<<q<<endl;
}
};
void main()
{
B b1;
b1.getno();
b1.sub();
b1.add();
b1.mult();
b1.a=30;
b1.b=15;
int z=b1.a/b1.b;
cout<<"division="<<z;
}
OUTPUT :
subtraction=10
addition=30
multiplication=200
division=2
DESCRIPTION :
class A
private section
int c
public section
int a,b
getno()
sub()
Inherited
from A
class B : public A
private section
int p,q
public section
add()
mult()
int a,b
getno()
sub()
The class B ia a public derivation of the base class A.Therefore, B inherits all the
public members of A and retains their visibility. Thus public member of the base class
99
C++
A is also a public member of the derived class B.The private member of A cannot be
inherited by B.
2). In private derivation, the public members of the base class become
private members of the derived class
class A
private section
int p,q
class B : private B
private section
int c
public section
int p,q
getno()
sub()
int p,q
getno()
sub()
public section
add()
mult()
Grandfather
Father
Child
C++
class A
{
protected : int x;
public :void setx(void)
{
x=10;
cout<<"x="<<x<<endl;
}
};
class B : public A
{
int b,c;
public : void setb(void)
{
b=10;
cout<<"b="<<b<<endl;
}
void add(void)
{
c=b+x;
cout<<"c="<<c<<endl;
}
};
class C : public B
{
int y,z;
public :void sety(void)
{
y=20;
cout<<"y="<<y<<endl;
z=x*y;
cout<<"z="<<z<<endl;
}
};
int main()
{
C c1,c2;
c1.setx();
c1.setb();
c1.add();
c1.sety();
}
101
C++
OUTPUT :
x=10
b=10
c=20
y=20
z=200
DESCRIPTION :
Class A
Class B : public A
protected section
int x
public section
setx()
private section
int b,c;
public section
setb()
add()
setx()
Class C : public B
private section
int y,z
public section
sety()
setb()
add()
setx()
Class B is a public derivation of base class A, Hence B inherits all the public members
of A and retains their visibility but cannot inherit private members of A.
Class B inturns serves as base class for C. Hence C inherits all public members of B
and hence of A. Class B is known as intermediate base class. The chain A-B-C is
known as inheritance path.
MULTIPLE INHERITANCE :- A derived class with more than one base class is
called as multiple inheritance .
(base class1)
(base class2)
(base class n)
B-2
D
EXAMPLE :
#include<iostream.h>
class A
{
protected : int a;
public :
void seta()
102
B-n
(derived class)
C++
a=10;
cout<<"a="<<a<<endl;
}
};
class B
{
protected : int b;
public :
void setb()
{
b=10;
cout<<"b="<<b<<endl;
}
};
class C : public A , public B
{
int sum;
public :
void tot()
{
sum=a+b;
cout<<"sum="<<sum<<endl;
}
};
void main()
{
C c1;
c1.seta();
c1.setb();
c1.tot();
}
Description :
class A
protected section
int a
public section
seta()
class B
protected section
int b
public section
setb()
103
C++
Example :
#include<iostream.h>
#include<conio.h>
class A
{
protected : int rollno;
public : void getno(int a)
{
104
C++
rollno=a;
}
void putno(void)
{
cout<<"Roll No="<<rollno<<"\n";
}
};
class B : public A
{
protected : float part1,part2;
public : void getmarks(float x , float y)
{
part1=x;
part2=y;
}
void putmarks(void)
{
cout<<"Marks obtained="<<"\n"
<<"part1="<<part1<<"\n"
<<"part2="<<part2<<"\n";
}
};
class C
{
protected : float score;
public : void getscore(float s)
{
score=s;
}
void putscore(void)
{
cout<<"sports wt="<<score<<"\n";
}
};
class D : public B , public C
{
float total;
public : void display(void)
{
total=part1+part2+score;
putno();
putmarks();
105
C++
putscore();
cout<<"Total Score="<<total<<"\n";
}
};
void main()
{
D d1;
d1.getno(1480);
d1.getmarks(35.5 , 42.5);
d1.getscore(8.2);
d1.display();
}
OUTPUT :
Roll No=1480
Marks Obtained=
Part1=35.5
Part2=42.5
Sports wt=8.2
Total Score=86.2
106
C++
DESCRIPTION :
class A
f
protected
section
int rollno
public section
getno()
putno()
class B : public A
protected
section
float part1, part2
public section
getmarks()
putmarks()
class C
protected
section
float score
public section
getscore()
putscore()
getno()
putno()
class D : public B ,public C
private section
float total
public section
display()
getmarks()
putmarks()
getno()
putno()
getscore()
putscore()
Here, as in fig., Class A serves as base class for Class B, Hence B inherits all public
properties of A. Also class B serves as base class for class D which is a case of
multilevel inheritance. Also Class C is the base class for D, a case if Multiple
Inheritance. Hence Class D inherits all the public properties of class A, B and C.
This is hybrid Inheritance. Where two or more types of inheritance are used in a
single program.
Abstract Classes
A class is said to be abstract if it is used only for the purpose of inheritance i.e. if it is
only used for creating subclasses. One cannot create an object of an abstract class.
Note that it is just a programming concept, it helps a programmer in developing a
hierarchy of classes.
Constructors / Destructors and Inheritance :
107
C++
Constructors :
C++ assumes that the constructors of the base class to be called before the
constructor for the derived class is executed. If the parameters to the base class is not
specified, the default constructor (one without any parameters) if it exists would be
called. The constructor for a derived class can specify parameters of only its
immediate base class. When an object is defined in the derived class, first the
constructor of the base class is called, and then the constructor of the derived class.
The following program shows that the constructor goes from the base, down the
hierarchy.
Program;
#include<iostream.h>
class ClassA
{
public:
ClassA(void)
{
cout<<"constructor.ClassA\n";
}
};
class ClassB : ClassA
{
public:
ClassB(void)
{
cout<<"Constructor.ClassB\n";
}
};
class ClassC : ClassB
{
public:
ClassC(void)
{
cout<<"Constructor.ClassC\n";
}
};
108
C++
main()
{
ClassA a;
ClassB b;
ClassC c;
}
Output :
cout<<"\n";
cout<<"\n";
Constructor. ClassA
Constructor. ClassA
Constructor. ClassB
Constructor. ClassA
constructor .ClassB
Constructor. ClassC
Destructors and inheritance :
The destructor goes in reverse order, from the derived class up to the base class.
When an object of class savings_account goes out of scope, the destrucotr of class
saving_account is executed first, followed by that of its base class-class account. No
special syntax is requited for destructors as they cannot be overloaded and cannot
have parameters.
Program:
#include <iostream.h>
class ClassA
{
public:
ClassA (void)
{
cout<<"Constructor.ClasA\n";
}
~ClassA(void )
{
cout<<"Destructor. ClassA\n";
}
};
109
C++
};
~ClassB(void)
{
cout<<"Destrucot.classB\n";
}
cout<<"\n";
cout<<"\n";
Constructor. ClassA
Constructor. ClassA
Constructor. ClassB
110
C++
Constructor. ClassA
Constructor. ClassB
Constructor. ClassC
destructor. ClassC
destructor. ClassB
destructor. ClassA
destructor. ClassB
destructor. ClassA
destructor. ClassA
Local Classes :
Classes the are declared within a function are local to the scope of that function. In
the example given below the class 'loc' is local to the function func(), It behaves like
any other local variable. It is inexistant when the functions is exited. The destructor is
called a the end of the function scope.
Program:
#include <iostream.h>
void func(void)
{
class loc
{
int p;
public:
void print(void)
{
p=100;
cout<<p<<"\n";
}
}a1;
a1.print();
}
main()
{
func();
}
111
C++
display()
Pointers and Inheritance
Pointer to Objects :
Just like other datatypes, we can also have pointers to the objects. In the example,
put is a pointer pointing declared to point to an object of class.
Ex: class *ptr;
Lets study at a program to understand Pointers with Inheritance.
Program:
#include <iostream.h>
class room
{
int count;
public:
void students (void)
{
count=50;
cout<<count<<"\n";
}
};
main()
{
room *Tenth;
Tenth = new room();
Tenth -> students();
}
Here Tenth is a pointer to a class - room. Hence the symbol -> is used to call a
method of the class - students().
Pointers with Hierarchy :
Let us how a pointer behaves in an inheritance hierarchy
#include <iostream.h>
class ClassA
112
C++
{
public:
};
void display(void)
{
cout<<"clasA\n";
}
}
Output :
113
C++
ClassA
ClassA
ClassA
But this is not what we wanted. We recall that when methods that have the same
name in the base and derived classes are accessed directly through the derived class
objects, the methods of the derived class overrides the method of the base class. But
pointers behave differently. Even of the pointer is assigned a different address, it will
continue to aces the methods of the base class. The is vivid in the above output. The
problem can be solved by type casting the pointer. When the pointer is casted to
access a derived class. it need not even be passed the address of the derived class. At
the time of casting itself, it accesses the object of the derived class.
Casting pointers :
Let us now rewrite the program with casting pointers to get the desired results.
Program:
#include <iostream.h>
class ClassA
{
public:
void display(void)
{
cout<<"ClassA\n";
}
};
class ClassB : ClassA
{
public:
void display()
{cout<<"ClassB\n";}
};
class ClassC : ClassB
{
public:
void display(void)
{
cout<<"ClassC\n";
114
C++
};
main()
{
ClassA *p,a;
ClassB b;
ClassC c;
p=&a;
p->display();
((ClassB *)p)->display();
((ClassC* )p)->display();
}
Output:
ClassA
ClassB
ClassC
Virtual functions
Late / Dynamic Binding :
If the Inheritance relationship is defined as a logical "is-s" relationship, can we use a
derived class in place where a base class is expected ? A pointer to the derived class
can be used wherever a pointer to the base class is expected. It would not be sufficient
to allow just this equality of pointer, member function calls (for example
calcuate_interest ()) should also be made, so that depending on the actual instance
the correct version of the function is called. This would avoid the use of a switch
statement and also avoid storing the type of the object. C++ requires that the
designer of the base class identify all such functions and qualify them with the
keyword virtual. This is called as run-time binding., as at compile time, it may not be
clear which function would actually be called. Some other Oriented Programming
language make all functions run-time bound. C++ choose the center path to reduce
inefficiencies caused by run-time binding. This is also called Late Binding.
There is a discrepancy between treating an object as a member of the base class and
treating it as a member of a derived class. We would often like a common interface
provided by a base class, but different implementations of the methods created in
derived class. If suppose we have two derived class D1 and D2 of a base class B, and
all three of them had a method called display(). Further suppose an array of he base
class that contained members of both the derived classes was being used. Then a call
to display() must be resolved before the program executes. When the compiler
115
C++
generates a call to display(), for each element of the array of class B element, it
generates a call to B::Display(), because that is the only function it knows in that
context. Resolving the function call at compile time is called early or static binding.
Thus even though the object is being accessed from the base class, the display()
functions D1.display() or D2.display() should be called depending on which of the
derived classes that particular object belong to. Resolving a function at run time is
called late or Dynamic Binding.
Static Binding or Early Binding is normal in most programming language, in
particular procedural languages. With Static binding, the compiler and the linker
directly define the fixed address of the code to be executed on every function call.
With dynamic binding or late binding, the time to decide which of a list of addresses
is the actual one. Only during the execution of the program some value will be used
by run-time mechanism to determine the effective address among the several that are
possible (one for every derived class).
Properties of Virtual Functions :
The following properties about virtual function should be noted:
1.
Virtual functions called from within the member functions of base class
would call the correct function at run-time.
2. Virtual functions called from within constructors would not call the expected
function. as the object of the derived class is not created when the constructor
of the base class is being executed.
3. Virtual functions cannot be overloaded. This is very inconvenient.
The Overloading is not allowed for many reasons.
a) As overloading is defined over scopes, overloading of a virtual function would
not mean matching of parameters across classes.
b) Allowing a feature like this, would require type information to be stored for
the run time. Currently, even the linker does not have type information,
overloading being achieved by name mangling.
c) C++ is intended to be a strictly typed language - meaning that all type
mismatches would be pointed out by the compiler. Given that type resolution
is required at tun time, type mismatch errors could occur at run time. This is
undesirable for production quality software.
Polymorphism :
116
C++
};
main()
{
A *pa, a;
117
C++
B b;
C c;
pa=&a;
pa=&b;
pa=&c;
pa->display();
pa->display();
pa->display();
}
Here the class c does not have its own method display(). so who will it borrow it
from? A or B?
The answer lies in the output:
this is class A
this is class B
this is class C
Polymorphism functions through a process called Late binding. In the process of
compiling a program, what you get is an .obj file, with the references to the various
function. At the linking stage, these externals are resolved to get an exe file. This type
of linking is referred to as early binding. As against early binding is late binding. The
platform on which polymorphism rests. In this kind of binding process, the externals
are resolved not at link-time, buy at run-time. It is only at run time that the decision
about the function pointed to can be made. Without this facility polymorphism would
have remained only a theory.
Virtual Functions
"Virtual Functions' are functions that ensure that the correct function is called for an
object, regardless of the expression used to make the function call. Suppose a base
class contains a function declared as virtual and a derived class defines the same
function. The function from the derived class is invoked for objects of the derived
class, even if it is called using a pointer or reference to the base class. The following
example shows a base class that provides an implementation of the Print Balance
functions:
Program:
#include<iostream.h>
class Account
{
public:
Account( double d );
virtual double GetBalance();
virtual void PrintBalance();
// Constructor.
// Obtain balance.
// Default impleemntation.
118
C++
private:
double _balance;
};
// Implementation of constructor for Account.
Account::Account(double d)
{
_balance = d;
}
// Implementation of GetBalance for Account.
double Account::GetBalance()
{
return _balance;
}
// Default implementation of PrintBalance.
void Account::PrintBalance()
{
cerr<<"Error.Balance not available for base type." <<endl;
}
Exercise
Explain inheritance and its advantages.
Explain all the types of inheritance.
Explain abstract classes.
Explain virtual function.
Explain polymorphism.
Explain Constructors & Destructors with inheritance.
119
C++
Chapter - 10
FILES
THE STREAM CLASS HIERARCHY
A stream is a source or destination for a collection of characters or a flow of data.
There are two kinds of streams:
The input and output capabilities of C++ stem from the fact that each stream is
associated with a particular class. For example, the input streams are associated with
the istream class and the output streams are associated with the ostream class. Each
class contains its own member data, and functions and definitions for dealing with
the data in a particular kind of stream.
The following is a list of features of the C++ stream classes:
The figure below shows the hierarchy of the stream class library.
120
C++
ios
istream
ostream
iostream
ifstream
fstream
ofstream
121
C++
C++ provides specific classes, which deal with user-defined stream. User-defined
stream are in the form of files and are linked to a stream. A stream must be obtained
before a file is opened. These streams are more powerful than the predefined
iostreams. There arethree stream classes that provide file input/output capabilities.
They are:
The ifstream class, derived from the istream class, and used for file input
(reading).
The ofstream class, derived from the ostream class, and used for file output
(writing).
The fstream class, derived from the iostream class, and used for both file
input and output.
The definitions for these classes are in the header file, fstream. This file also includes
iostream, so there is no need for you to explicitly include it. The classes defined
fstream take care of all file input/output. File input and output is an extension of
stream extraction and insertion.
The open () Function
Each file stream class has an open () member function which is used to open files.
The following statements illustrate the same.
ifstream Ifil;
Ifil.open (DATA.DAT);
Ofil.close ();
Here the file, DATA.DAT, is closed. However, the object, Ofil, is still available in the
memory, though it is not associated with any particular data file. This technique of
closing files is useful when you want to use the same object to process any different
files in a single program.
OPEN MODE BITS
122
C++
Explanation
Starts reading or writing at the end of the file. Does not have
a meaning with input streams, it is used only for output
streams.
Open for reading
Open for writing
Seek to the end of the file
If the file exists, it is truncated, i.e. all data is erased before
writing/reading
C++
}
Note: To check whether the file is found or not there is a function called bad().
Better way to read from the file
#include<iostream.h>
#include<fstream.h>
int main()
{
ifstream in;
char str[30];
in.open("C:\\data.txt");
if(in.bad())
{
cout<<"\nError reading the file.";
return 0;
}
while(!in.eof())
{
in.getline(str,30,'/n');
cout<<str<<endl;
}
in.close();
}
File Input and Output using Objects
Here is an example of file output using an object of a user-defined class, Vehicle.
#include<fstream.h>
#include<string.h>
// for strcpy ()
class Vehicle
{
public:
int serialNo;
char model[8];
int price;
};
int main ()
{
ofstream out ("C:\\obj.txt");
Vehicle car;
car.serialNo = 55;
124
C++
C++
Syntax
read(char*addr, int size)
The address of the array into which the file is to be read is addr. The array
must be of the character type. Therefore, if any other type of address is
passed as the first parameter, it has to be type cast to a character pointer.
However, some C++ compilers support a void *. This means that any pointer
type can be used as an argument, without type casting.
The number of bytes to read is size.
The get pointer, which specifies the location in the file where the next read
operation will occur.
The put pointer, which specifies the location in the file where the next write
operation will occur.
However, you may have to manipulate file pointers to read from and write to only a
particular location in a file. The seekg () and tellg () functions help you to control the
get pointer. The seekp () and tellp () functions do similar operations on the put
pointer. In other words, these four functions allows you to access the file in a nonsequential or random mode.
The tellg () and tellp () functions can be used to find the current position of the get
and put file pointers respectively, in a file.
The seekg () member function takes two arguments:
126
C++
Example
ifstream iFil;
iFil.seekg (10, ios::beg);
means, position the get pointer 10 bytes from the beginning of the file
The first argument is an integer that specifies the number of byte positions (also
called offset). The second argument is the reference point. There are three reference
points defined in the ios class:
A negative value can also be specified for the first argument. For example, the
following statement moves the file pointer 20 bytes in the reverse direction from the
end of the file.
iFil.seekg (-20, ios::end);
If the seekg () function is used with only one argument, the ios::beg reference point is
assumed. For example in the statement:
iFil.seekg (16);
ios::beg will be the reference point and hence the get pointer will be positioned 16
bytes from the beginning of the file.
The tellg () member function does not take any arguments. It returns the current byte
position of the get pointer relative to the beginning of the file. For example the
statement:
int iPosition=iFil.tellg ();
will result in the variable, iPosition, having the value of the current position of the get
pointer.
The seekp () and tell0 () member functions are identical to the above two functions,
but they are identified with the put pointer.
The seekg () and tellg () member functions are defined in the istream class. The seekp
() and tellp () member functions are defined in the ostream class.
127
C++
C++
}
file.close();
file.open("customer.dat",ios::in);
file.read((char*)&object,sizeof(object));
while(!file.eof())
{
object.print();
file.read((char*)&object,sizeof(object));
}
file.close();
Exercise
Explain stream class hierarchy.
Explain file input/output using objects.
Explain reading and writing files in binary format.
Explain all the file manipulators.
129