Programming Using C++
Programming Using C++
USING
C++
BY
Avinash Kumar Singh
1 Avinash Kumar Singh
INDEX
The lessons of this tutorial will lead you from being a beginning student of C++ up to
being a intermediate level C++ programmer. To get good grasp on this tutorial, We will
suggest you all to first go through our "C Tutorial" to well understand the common
programming term.
Before you jump right in, here is the single most important piece of advice which is
offered. To learn C++ and to get the most out of these lessons, you need to have access
to a compiler. The complier turns the source code files, which are the text you will write,
into a form that can be read and executed by a computer. As you work through the
tutorials We encourage you to try to compile and run the examples which are provided in
the original C++ window.
Somewhere you will find out that the output of program is not given because, there we
have tried to show you structure and logical view of the program only. We make every
effort to create working code rather than code snippets that won't compile or run. The
best and most enjoyable way to learn to program is to actually write code.
This research removed the final obstacle to large, complex programs, the ability to
switch tasks quickly, and the logical certainly that a program above a certain complexity
level cannot be proven to be bug-free.
It can fairly be argued that a computer program is a product of pure intellect, has no
physical existence, and therefore cannot meaningfully be secured against theft.
The computer's higher purpose resides in its program. This is why, as time passes,
computers become less expensive and programs become more expensive.
It is why the richest man in the world is, not a builder of computers, but a builder of
programs.
1. Unstructured Programming
2. Procedural Programming
3. Modular Programming
4. Object-Oriented Programming (OOP)
Unstructured Programming
Usually, people start learning programming by writing small and simple programs
consisting only of one main program. Here "main program'' stands for a sequence of
commands or statements which modify data which is global throughout the whole
program.
For example, if the same statement sequence is needed at different locations within the
program, the sequence must be copied. This has lead to the idea to extract these
sequences, name them and offering a technique to call and return from these
procedures.
Procedural Programming
With procedural programming you are able to combine returning sequences of
statements into one single place. A procedure call is used to invoke the procedure. After
Execution of procedures. After processing flow of controls proceed where the call was
made.
For example, if a procedure is correct, every time it is used it produces correct results.
Consequently, in cases of errors you can narrow your search to those places which are
not proven to be correct.
Now a program can be viewed as a sequence of procedure calls. The main program is
responsible to pass data to the individual calls, the data is processed by the procedures
and, once the program has finished, the resulting data is presented.
Thus, the flow of data can be illustrated as a hierarchical graph, a tree, as shown below
for a program with no sub procedures:
In the Procedural programming technique main program coordinates calls to procedures
and hands over appropriate data as parameters.
Now we have a single program which is divided into small pieces called procedures. To
enable usage of general procedures or groups of procedures also in other programs,
they must be separately available. For that reason, modular programming allows
grouping of procedures into modules.
Each module can have its own data. This allows each module to manage an internal state
which is modified by calls to procedures of this module. However, there is only one state
per module and each module exists at most once in the whole program.
Object-Oriented Programming
Today's large scale software systems are typically designed and implemented using the
concepts of the object-oriented model. However, there is still a need for the existing OO
languages and architectures to continuously adapt in response to demands for new
features and paradigms. These new features include topics such as dynamic software
evolution, security, safety, distribution and expressiveness.
That is, an object is considered to be a partitioned area of computer memory that stores
data and set of operations that can access data. Since the memory partitions are
independent, the objects can be used in a variety of different program without
modifications.
C++ is an object-oriented language. To solve a problem with C++ the first step is to
design classes that are abstractions of physical objects.
These classes contain both the state of the object, its members, and the capabilities of
the object, its methods. After the classes are designed, a program is written that uses
these classes to solve the task at hand.
Therefore this features extends many other features of OOP. Those feature we will
discuss in the last of this section.
Object
Object is an identifiable run-time entity with some characteristic and behavior.
for example 'orange' is an object and its characters are shape, color etc.
Class
A class is a group of object that share common properties and relationship. for example
fruit has been defined as a class, then the statement
fruit mango;
will create an object mango belonging to the class fruit.
Message
At runtime instances of classes, the objects, achieve the goal of the program by
changing their states. Consequently, we can think of our running program as a collection
of objects.
The question arises of how these objects interact? We therefore introduce the concept of
a message.
A running program is a pool of objects where objects are created, destroyed and
interacting. This interacting is based on messages which are sent from one object to
another asking the recipient to apply a method on itself.
Data Abstraction
Abstraction refers to the act of representing essential features without including the
background details.
To understand abstraction, lets an example. you are driving a car you only know the
essential features to drive the car e.g. gear, steering etc. But while driving the car you get
into the internal details of the car such as wiring, battery etc.
What is happening inside is hidden from you. This is data abstraction where you know
only the essential things to drive the car without including the background details.
Data Encapsulation
Encapsulation is the most fundamental concept of OOP. It is the way of combining both
data and the functions that operate on data under a single unit.
The wrapping of the data and functions (that operate on the data) into a single unit
(called classes) is known as encapsulation.
The only way to access the data is provided by the functions (that are combined along
with the data). These function are called member functions in C++.
The data can not be accessed directly. If you want to read a data item in an object (an
instance of a class), you call a member function in the object it will read the items and
return the value to you. Encapsulation is just a way to implement data abstraction.
Inheritance
Understanding inheritance is critical to understanding the whole point behind object
oriented programming.
Super Class/Subclass
Definition: If class A inherits from class B, then B is called superclass of A. A is called
subclass of B. Objects of a subclass can be used where objects of the corresponding
superclass are expected. This is due to the fact that objects of the subclass share the
same behaviour as objects of the superclass.
In the literature you may also find other terms for "superclass'' and "subclass''.
Superclasses are also called parent classes. Subclasses may also be called child classes
or just derived classes.
Consequently, the arrowed line starts from the subclass towards the superclass as
illustrated in below figure:
A simple inheritance graph.
var i : integer;
For example, the following assignment will result in a type mismatch error when you try
to compile it:
var i : integer;
...
i := 'string';
We call this particular type of binding "static'' because it is fixed at compile time.
If the type T of a variable is explicitly associated with its name N by declaration, we say,
that N is statically bound to T. The association process is called static binding.
For example, some languages allow to introduce variables once they are needed:
... /* No appearance of i */
i := 123 /* Creation of i as an integer */
The type of i is known as soon as its value is set. In this case, i is of type integer since we
have assigned a whole number to it. Thus, because the content of i is a whole number,
the type of i is integer.
If the type T of a variable with name N is implicitly associated by its content, we say, that
N is dynamically bound to T. The association process is called dynamic binding.
Both bindings differ in the time when the type is bound to the variable.
Consider the following example which is only possible with dynamic binding:
Polymorphism
Polymorphism allows an entity (for example, variable, function or object) to take a variety
of representations. Polymorphism is key to the power of object oriented programming. It
is so important that languages don't support support polymorphism can not advertise
them self as OO languages.
Polymorphism is the ability for a message or data to be processed in more than one
form. Polymorphism is a concept that support the capability of an object of a class to
behave differently in response to a message or action.
Polymorphism is a property by which the same message can be sent to objects of
several different classes, and each object can be respond in a different way depending
on its class.
Template class
Definition: If a class A is parameterized with a data type B, A is called template class.
Once an object of A is created, B is replaced by an actual data type. This allows the
definition of an actual class based on the template specified for A and the actual data
type.
Benefit of OOP
Some of the benefit of using OOP given here:
1. Through inheritance, we can eliminate redundant code and extend the use of existing
classes.
2. Software complexity can be easily managed.
3. Object oriented system can be easily upgraded from small to large system.
4. It is easy to Partition the work in a project based on object.
5. We can build program from the standard working modules that communicate with one
another, rather than having to start writing the code from scratch.
6. Message passing techniques for communication between object makes the interface
description with external system much simpler etc.
Overview of OOP using C++
A Brief History Of C++
Bjarne Stroustrup at Bell Labs initially developed C++ during the early 1980's. It was
designed to support the features of C such as efficiency and low-level support for system
level coding. Initially it was called "C with classes" however in 1983 the name was
changed to C++ because is was an extends C by a special feature classes.
Added to this were features such as classes with inheritance and virtual functions,
derived from the Simula67 language, and operator overloading, derived from Algol68.
Don't worry about understanding all the terms just yet, they are explained in above
section. C++ is best described as a superset of C, with full support for object-oriented
programming. This language is in wide spread use.
Introduction of C++
C++ is an advanced, powerful language, yet it is relatively easy to introduce and learn. it
is most modern, high-performance computer programs are written using C++.
C++ knows about objects and therefore can teach sound programming techniques from
the very beginning.
C++ is a compiled computer language. This means the original source code is translated
into a specific machine's native tongue, all at once, before the program is run. The
program the computer runs is composed entirely of instructions known to it, requiring no
further interpretation.
Below a picture has been given to understand so how c++ source code translate into
machine code:
Source Code
#include <iostream.h>
int main()
{
cout << "Bonjour Monde!" << endl;
return 0;
}
Compiler
A compiler is a very specialized computer program that translates source code into
machine-specific code. Compiler writing is very difficult and esoteric, and is one of the
more advanced and complex parts of computer science.
Note This code only show how the program of c++ language converted into machine
language.
This is a nice environment in which to write programs, but if the program is simply used
and is no longer being developed, much time is wasted re-interpreting instructions that
could be translated just once and stored in translated form. Because a compiler
translates the entire program at once, compiled programs are faster than interpreted
programs, and are preferred for tasks that require high performance.
There are two principal reasons for high-level languages like C++.
The first is to make program development easier each instruction written in C++ might
represent dozens or hundreds of lower-level native instructions.
The second is to make programs portable if sufficient care is taken in development, a
program written for one computer can be re-compiled and run on another.
Therefore, a programmer need only learn one computer language, instead of one
language per computer architecture. If a single program can be run on any machine, the
unit price of software can go down. It would be nice if there were an interpreted version
of C++, for program development work only, so the developer would not have to re-
compile after each trivial change. But this hasn't happened yet, and in any case it would
probably be an expensive environment.
C++ is a third generation programming language. When computers were first invented,
they were programmed with very simple, low-level commands. A programmer would
design a program, then translate the program into a specific set of codes, known as
machine language.
These codes would be fed into a computer with switches, punch-cards, or primitive
keypads. These programs were cumbersome to write, and very hard to debug
16 Avinash Kumar Singh
(Debugging is the act of removing mistakes in a program). Machine code is considered
the first generation of programming languages.
Third generation languages are compiled languages. These languages are not processor-
specific. In theory, a program written in a third generation language will be able to run on
any other machine. This is not always the case, due to a number of factors. Third
generation languages are much more abstract than assembly languages. Third
generation languages are translated into assembly language by a complicated piece of
software called a compiler. A compiler can be thought of a a language translator.
C++ is a very useful language, because it gives the programmer a lot of control, but also
is abstract enough so development can be done fairly quickly. C++ is a very portable
language as well, because it is a third-generation language, and because it has a well
defined set of standards written for it. C++ is widely used for program development under
a variety of operating systems. Good C++ programmers are in high demand today.
Filename
A source file is the file that contains the C++ code that is compiled into an executable file,
using a C++ compiler. C++ source files usually have an extension name of cpp, or cxx,
depending on the compiler.
Library Files
Like C, C++ has a limited number of keywords, and depends on Library Files for its
functionality. This functionality is achieved by using library files. These library files are
referred to as Header files and have a .h extension name. The standard input/output
header file is called iostream.h.
The #include statement is used to insert the header code so your program may use the
functions defined in the header file. Angled brackets are used to instruct the
preprocessor to find the header files from the standard header file directory.
#include <iostream.h>
Comments
There are two types of comments in C++:
1. Block Comments: Block comments span several lines. The characters /* start a block
comment, and the characters */ end the block comment.
Preprocessor Directives
Before the program is compiled, the source code is scanned by a preprocessor to
perform text substitution, and header file inclusions. C++ supports inline functions, and
constants, so is consequently more often used just for header file inclusion and
conditional compilation statements.
Preprocessor directives are preceded with a #. The # should always be placed in the first
column of the line. The following is a directive that causes the contents of the header file
to be brought into the current file, effectively replacing the directive line with the
contents of that file.
#include <iostream.h>
#include <iostream.h>
int main()
{
// Statements belonging to the function are tabbed
return 0;
}
#include <iostream.h>
This is an include statement and tells the compiler to make the contents of the
<iostream> header available to the program. The input and output streams cin and cout,
used in our program to read keyboard input and output to the display screen, are defined
in <iostream.h>. If you try to compile the code without including this header it will fail to
compile.
19 Avinash Kumar Singh
The header <iostream.h> is a standard library header and in common with all of the
standard C++.
int main()
The above line is the start of the definition of function main(). All C++ programs must
have a main() function which is the entry point to the program. A typical C++ program in
the real world will have many functions. In our simple case, we can put all of our code
into the one function, main().
The opening brace, above, marks the start of a code block. In this case it marks the start
of function main(). For every opening brace in a program there will be a corresponding
closing brace marking the end of the code block.
This is where the real work is done in our simple program. Here the string "Hello, world"
is output via the output stream, cout. The endl manipulator outputs a newline and then
flushes the stream. Because cout is buffered, output may not be displayed when first
written. Flushing the stream forces the contents of the buffer to be output.
cin.get();
The line above causes the program to wait for input from the cin input stream. This may
not be required, however, there are some programming environments, for instance
running a console program in a Microsoft Windows environment, where the output may
disappear before you've had an opportunity to see it when the program completes.
Adding this line of code will enable you to see the output, and then press Enter to
continue. If not required for your environment you can safely remove the line from your
program.
return 0;
This is the return statement. Because main() is defined as returning an integer, the above
statement will return a status to the calling process indicating normal program
termination.
Simply choose "New File" and type out the program coding.
In the compiler program there will be an option called ‘Compile’ in the menu bar. Select
the compile option and the compiler will do its work. It will compile the program and in
case there are any errors, the compiler will point out the line where the error was
detected. Check whether the program has been typed exactly as given earlier. Even if a
semi-colon is missing, it will lead to errors. If the compiler says no errors (or if the
message "compiled successfully" appears), then you can go to the next stage: building
the *.exe file.
*.exe file extension stands for executable files. A *.cpp file cannot be run directly on the
computer. This has to be converted into a *.exe file and to do so select the "Make or Build
exe" option in the compiler. The file ‘first.exe’ will be created. Now the program can be
executed from the DOS prompt by typing ‘first’. But instead of running the program every
time from DOS, it will be convenient to run the program from the compiler itself and
check the output.
In the compiler there will be another option called "Run". Just click on this and the
program will run from the compiler itself (you needn’t switch back and forth between
DOS and the compiler screen).
What happens is that the program displays the character on the screen, immediately
terminates the program and returns to the compiler screen. This happens so fast that you
can’t see the output being displayed.
Only after a character is typed will the program move to the next instruction. In the above
program, there is no statement other than return 0; after getch ( ). Hence program flow is
as follows:
Output: The program asks the user to enter a letter. The user enters a letter. Then the
program displays the typed letter on the screen. The program will not quit at this point
since there is a statement getch ( ). It will wait till the user types another character. When
the user presses a character the program will quit.
Type the above program, save and run it from the compiler. Some compilers have named
the function getch( ) as _getch( ). This function also requires the <conio.h> header.
In other compilers if a similar problem is encountered while displaying the result try
using
getchar( ); instead of getch( );
getchar( ) function doesn’t require the conio.h header file. If the compiler does not
recognize getchar( ), then instead of adding any of the in-built functions, just add another
line as follows:
cin>>letter;
Tokens
The smallest unit in the program is called a token. C++ has the following tokens:
C++ Character Set
Character set is a set of valid characters that a language can recognize. A character
represents any letter any letter, digit or any sign. The C++ has the following character set
Letters: A-Z, a-z
Digit: 0-9
Special symbol: Space + - * / ^ \ ( ) [ ] { } = != < > . ' " , $ ; : % ! & ? _ # <= >= @
White Spaces: Blank space, Horizontal tab , New line
Other: C++ can process any of the 256 characters as data or as literals.
Identifiers
Identifiers are very important in C++ and are used in all programs. What is an identifier?
In the previous program ‘check’ was declared as a character variable. The identifier in
this case is ‘check’. Basically identifiers are names that are given to variables, constants
or functions. In the previous program there are two identifiers: ‘check’ and ‘i’.
C++ permits the use of a huge variety of names for identifiers like:
test
Test
int_test
var1
var123
c_b_f
_var
Almost any name you can think of can be used as an identifier but there are some
restrictions. An identifier should not start with a number. The first character of an
identifier should be an alphabet or an underscore ( _ ). After the first character, numbers
can be used in the identifier. Remember the following:
Variables
Variable represents named storage location, whose values can be manipulated during
program run. variables are called symbolic variables because they are named.
rvalue of A = 10 rvalue of C = 25
lvalue of A = 1052 lvalue of C = 1055
Declaration of a variable
To declare a variable this format is used
Syntax: data type name;
To declare a signed/unsigned variable place these modifiers before the data type.
Example:
signed int a;
unsigned short b;
here are three places where a variable can be declared: local, formal parameters and
local.
For example:
void test ( )
{ // Start of block
int q;
q = 2;
} // End of block
void test2 ( ) // Start of another block
{
int q;
q = 5;
}
The two q's that We have declared in the two functions (test and test2) have no
relationship with each other. Each q is known only within its own block (since it is a local
variable).
The main advantage is that a local variable cannot be accidentally altered from outside
the block.
Global Variables
These variables are known throughout the program. They can be used by any part of the
program and are not limited like local variables. They are declared outside the main
function.
#include <iostream.h>
int count; // count is a global variable
int main ( )
{
......
}
Global variables will take up more memory because the compiler has to always keep it in
memory.Avoid using too many global variables. Use it only if the variable is going to be
used by a number of functions.
Data Type
Data can be of many type e.g. character, integer, real, string etc. Any thing enclosed in
single quotes represent character data. Data type are means to identify the type of data
and associated operation of handling it.
26 Avinash Kumar Singh
C++ data types are of two types:
Fundamental Data type & Derived Data Type
0
10
345
6789
-23
-600
It includes positive and negative numbers but the numbers have to be whole numbers. It
does accept the decimal point. Hence the following numbers are not integer data types:
3.5
4.8
0.23
These numbers come under the second category (floating point type) and not under
integers.
How to declare a variable as belonging to the type integer? The syntax is:
int variable-name;
In C++ ‘qualifiers’ can be used to vary the range of fundamental data types. Qualifiers are
only supplements to the basic data types and they cannot be used separately on their
own. They work only with a basic (or fundamental) data type.
When an integer is specified as signed, then automatically the most significant bit of the
number is used as a sign bit (to denote the sign of the number). Hence it can be used if
the programmer needs positive and negative number values for the variable. By
declaring a variable as an integer, by default you can specify both positive and negative
values. By default an integer is a signed integer. In other words,
int variable-name;
An unsigned integer can hold a value up to 65,535 (a signed integer can hold only up to
32,767). Of course, in an unsigned integer you cannot assign a negative value. The range
is from 0 to 65,535. To go beyond 65,535 and make use of both positive and negative
values as well, the qualifier long should be used.
Long integers occupy 4 bytes of memory (32 bits). Remember, long int actually means
signed long int (you can give positive and negative values).
If you specify
you can only assign positive values to the variable. Thus, two qualifiers can be used
together with a basic data type.
int x;
short int x;
Compilers (depending on the operating system) will assume ‘int’ as a ‘long int’ or a ‘short
int’. Turbo C++ (which is a DOS based compiler) will default to ‘short int’ when you
specify a variable as type ‘int’.
Programmers sometimes prefer to explicitly state what type of integer they want to use
by making use of the ‘short’ and ‘long’ qualifiers. ‘short int’ always occupies only 2 bytes
(irrespective of whether the OS is Windows or DOS) while a ‘long int’ always occupies 4
bytes.
If you specify decimal numbers, floating point data type will store up to a precision of 6
digits after the decimal point. Suppose 0.1234567 is assigned to a floating-point variable,
the actual value stored would be 0.123457 (it will round up to the sixth digit after the
decimal place). Valid floating-point numbers are:
0.1276
1.23
1.0
10.2
2e5 (this will be typed in your code as 2e5)
float variable-name;
Character (char):
A character uses just one byte of memory. It can store any character present on the
keyboard (includes alphabets and numbers). It can take numbers from 0 to 9 only. The
following are valid characters:
A
B
3
a
:
‘
/
If the number 13 is entered as the value for a character, the program will only store 1 (i.e
it will store the first character that it encounters and will discard the rest). A character is
stored in one byte (as a binary number). Thus whatever the user enters is converted into
a binary number using some character set to perform this conversion. Mostly all
computers make use of the ASCII (American Standard Code for Information Interchange).
Double (double):
This is similar to the floating-point data type but it has an even greater range extending
up to 10308.
Remember: The size of data types given above is a general case. Data type sizes depend
on the operating system. So it may vary from system to system.
Name Bytes* Description Range*
char 1 character or integer 8 bits length. signed: -128 to 127
unsigned: 0 to 255
short 2 integer 16 bits length. signed: -32768 to 32767
unsigned: 0 to 65535
long 4 integer 32 bits length. signed:-2147483648 to 2147483647
unsigned: 0 to 4294967295
int * Integer. Its length traditionally depends on the length of the system's Word
type, thus in MSDOS it is 16 bits long, whereas in 32 bit systems (like Windows
9x/2000/NT and systems that work under protected mode in x86 systems) it is 32 bits
long (4 bytes). See short, long
float 4 floating point number. 3.4e + / - 38 (7 digits)
30 Avinash Kumar Singh
double 8 double precision floating point number. 1.7e + / - 308 (15 digits)
long double 10 long double precision floating point number. 1.2e + / - 4932 (19
digits)
bool 1 Boolean value. It can take one of two values: true or false Note: this is a type
recently added by the ANSI-C++ standard. Not all compilers support it. true or false
Arrays
Array refers to the named list of finite number n of similar data elements Each of the data
elements can be referenced respectively by a set of consecutive numbers, usually 0,1, 2,
.... n.
Function
A function is a named party of the program that can be invoked from other parts of the
program as often needed.
Program
Using a function to accept a number and return the cube of the number:
References
A reference is an alternative name for an object. A reference variable provides an alias
for a previously defined variable. C++ introduces a new data type called reference. You
can think of them as if they were "aliases'' to "real'' variables or objects. As an alias
cannot exist without its corresponding real part, you cannot define single references. The
ampersand (&) is used to define a reference.
For example:
ix = 1; /* also rx == 1 */
rx = 2; /* also ix == 2 */
References can be used as function arguments and return values. This allows to pass
parameters as reference or to return a "handle'' to a calculated variable or object.
Constant
The keyword const can be added to the declaration of an object to make that object a
constant rather than variable.
The general form of constant declaration is as follows:
Numeric Constants
Numeric constants consist of a series of digits. Integer constants can be written in
different
number systems: hexadecimal (base 16), octal (base 8) or in decimal (base 10).
A decimal integer constant is any normal whole number (can consist of digits from 0 to
9):
2,34, 100, 900, 1456 etc.
An octal integer constant can contain digits from 0 to 7 only and it should start with a
zero (so that the computer will know it is an octal number).
For example:
023, 0567, 0214 etc.
A hexadecimal integer constant should start with 0x or 0X and can consist of digits from
0 to 9 and A to F (uppercase and lowercase letters are allowed).
For example:
0x10, 0x1FF etc.
Floating point constants will have the decimal point in the number.
Structure
A structure is a collection of data of different data types under one name. e.g.
Struct employees
{
char Name[10];
33 Avinash Kumar Singh
int Age;
int Salary;
};
Union
It is a collection of data of different types sharing common memory space. e.g.
Union item
{
int m;
float x;
char c;
};
{
red, green, blue, cyan
};
colors foreground, background;
But remember we can't use values that aren't in the original declaration. Thus, the
following declaration cause error.
foreground=yellow;
Operator
Operators are tokens that trigger some computation when applied to variables and other
objects in an expression.
List of operators:
Assignment: =
Increment and decrement: ++ (pre or post fix) and -- (pre or post fix)
Arithmetic: +, -, *, / and % (integer remainder)
Compound assignation operators: +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=
and some other important we also discuss.
Assignation:
The assignation operator serves to assign a value to a variable.
a = 5;
assigns the integer value 5 to variable a. The part at the left of the = operator is known as
lvalue (left value) and the right one as rvalue (right value). lvalue must always be a
variable whereas the right side can be either a constant, a variable, the result of an
operation or any combination of them.
It is necessary to emphasize that the assignation operation always takes place from right
to left and never at the inverse.
a = b;
In Example 1, B is increased before its value is copied to A. While in Example 2, the value
of B is copied to A and B is later increased.
Arithmetic operators:
The five arithmetical operations supported by the language are:
+ addition
- subtraction
* multiplication
/ division
35 Avinash Kumar Singh
% module
Operations of addition, subtraction, multiplication and division should not suppose an
understanding challenge for you since they literally correspond with their respective
mathematical operators.
The only one that may not be known by you is the module, specified with the percentage
sign (%). Module is the operation that gives the remainder of a division of two integer
values.
For example: if we write a = 11 % 3;, the variable a will contain 2 as the result since 2 is
the remainder from dividing 11 between 3.
Logic operators
Operator ! is equivalent to Boolean operation NOT, it has only one operand, located at its
right, and the only thing that it does is to invert the value of it, producing false if its
operand is true and true if its operand is false. It is like saying that it returns the opposite
result of evaluating its operand.
For example:
!(5 == 5) returns false because the expression at its right (5 == 5) would be true.
!(6 <= 4) returns true because (6 <= 4) would be false.
!true returns false.
!false returns true.
Logic operators && and || are used when evaluating two expressions to obtain a single
result. They correspond with Boolean logic operations AND and OR respectively. The
result of them depends on the relation between its two operands:
First Operand a Second Operand b result a && b result a || b
true true true true
true false false true
36 Avinash Kumar Singh
false true false true
false false false false
For example:
( (5 == 5) && (3 > 6) ) returns false ( true && false ).
( (5 == 5) || (3 > 6)) returns true ( true || false ).
Bitwise Operators
Bitwise operators modify variables considering the bits that represent the values that
they store, that means, their binary representation.
op asm Description
& AND Logical AND
| OR Logical OR
^ XOR Logical exclusive OR
~ NOT Complement to one (bit inversion)
<< SHL Shift Left
>> SHR Shift Right
sizeof()
This operator accepts one parameter, that can be either a variable type or a variable itself
and returns the size in bytes of that type or object:
a = sizeof (char);
This will return 1 to a because char is a one byte long type.
The value returned by sizeof is a constant, so it is always determined before program
execution.
The example above has two variables named amount. The first is global and contains the
value 123. The second is local to the main function. The scope resolution operator tells
the compiler to use the global amount instead of the local one.
Note: The Function of I/O Library - iostream.h
Output operator
cout << "C++ is a object oriented language ";
The operator << is called the insertion or put to operator. It insert or sends the contents
of the variable on its right to the object. on its left.
In other words this operator is used to display the output on the screen.
Program to show use of output operator:
Input operator
cin>>"Ebiz is world's largest MLM company";
is an input statement or causes the program to wait for the user to type in a number.
The operator >> is known as a extraction to get from operator. It extracts or take the
value from the key word and assign it to the variable on its right.
In other words this operator is used to read a value from standard input.
Program to show use of input operator:
40 Avinash Kumar Singh
Output of the program:
For storing the values a variable is used. A variable refers to a storage area whose
contents can vary during processing.
Priority of operators
Priority of operators When making complex expressions with several operands, we may
have some doubts about which operand is evaluated first and which later.
For example:
in this expression:
a=5+7 %2
we may doubt if it really means:
a = 5 + (7 % 2) with result 6, or
a = (5 + 7) % 2 with result 0
The correct answer is the first of the two expressions, with a result of 6. There is an
established order with the priority of each operator, and not only the arithmetic ones
(those whose preference we may already know from mathematics) but for all the
operators which can appear in C++. From greatest to lowest priority
The priority order is as follows:
Operators Precedence and Associatively
Expression
An expression is composed of one or more operations. The objects of the operations are
referred to as operands. An expression in C++ is any valid combination of operators,
constants, and variables.
Type of expressions
Arithmetic Expression
Arithmetic expression can either be integer expression or real expression, some times a
mixed expression can also be formed with a mixture of real and integer expression.
Integer expression- int a=10, b=3, c=4, d=213;
. a+b, a*d etc
Real expression- float x=1.20, y=23.63, z=23.23;
. x+y, x*z etc.
Logical expression
The expression that result into 0 or 1 are called logical expression. The logical
expression are the combination of constants, variable and logical and relational operator.
The following are the examples of valid logical expression:
. x>y, (-y), (x-y) etc.
C++ Escape Sequences
Escape sequences are character constants that are usually used to format text.
Control Structure
Statements are the instructions given to the computer to perform any kind of action, be it
data movements, be it making decisions, or be in repeating action.
Selection statement
The selection statement allow you to choose the set of instructions for execution
depending upon an expression value.
a) if-else statement:
It shows that the condition is checked in if statement if it returns the value true then it
execute the statements inside the braces. If it returns false value the automatically the
statements in else condition are executed.
Syntax
if( expression )
{
statements;
}
else
{
statement;
}
Program.
b) Switch statements:
C++ provides a multiple branch selection statements known as switch. This selection
statement test the value of an expression against the value of the expression.
Syntax
switch( expression)
{
case 1:
case 2:
............
}
44 Avinash Kumar Singh
Iteration statement
The iteration statements allows a set of instructions to be performed repeatedly until a
certain condition to be fulfilled. The iteration statements are also called looping
statements. Some of the Iteration statement described here
Syntax
for( initialization, increment/decrement, termination condition)
{
.........
......
}
Syntax
while( expression)
{
loop body
}
Jump statement
The jump statement unconditionally transfer the program control within a function. C++
has four statements that perform an unconditional branch.
Syntax
goto label;
:
:
label:
c) Continue statement:
Continue is another statement like break but the difference is that it restart the loop again
when this statement is encountered skipping the statements after the statement.
Syntax
for(;;)
{
...
continue;
...
}
d) Exit statement:
Like break one can get out of the loop you can get out of the program by using a library
function exit().
This function causes the program to terminate as soon as it encountered.
The reason is simple. Suppose, in your program, you have to repeat a certain procedure
at different instances. Mean, a particular function has to be done in different parts of the
program.
You could keep typing the code in all the places (making the program larger in size) or
you could make use of functions concept. All you need to do is define the function once.
Wherever you need to perform the function you just need to call it (the call statement is
just one line).
The return data type specifies what sort of data the function will return to the calling
function. For example if return data type is int, then the function will return an integer
value to the main or calling function. If the return data type is void, this means that the
function does not return any value.
Actually the above syntax is the syntax for function declaration. You'll soon learn about
it. Just read on...
// Function declaration
// Funtion definition
Perhaps you feel a bit vague about the concepts of function. Don’t worry. It should
become clear with an example.
The above program is quite a simple example to illustrate the three components of a
function.
As you can see, we have first declared that a function of the return data type void, with
name add and no arguments.
Then comes, as usual, the main function.
Remember: The compiler will always execute what you type in the main function. You
can execute other functions by calling them within the main function. The compiler will
run the main function.
Since We just want to illustrate functions with a simple example, We haven’t written any
code in the main function other than the function call. When the compiler reads the
function call statement, it knows that you had already declared a function by the same
name and argument type. So it goes on reading your program and comes to the function
definition. In this you have written a set of statements to find the sum of two numbers.
The compiler will execute these statements. After displaying the result (due to the cout
keyword in the add function), the compiler will go back to the main function. It will then
see whether you have written anything after the function call. In this program We haven’t
mentioned anything, except the end of the program.
Example:
As you can see, in the above program there is only one small change. We haven’t
declared the function because We defined it before calling it. When the compiler reads
the above program, it will first read the function definition.
Argument
Argument is a piece of data passed from program to function. Argument allows a
function to operate with different values.
The variables used within the function to hold argument values are called parameters.
The data type in the function declaration and function call should be the same. Maybe it
all sounds a bit hard to understand. Just read on.
Example:
As you can see in the above program, We have used two parameters within the function
‘add’. The function definition comes before the function call and hence We have not
declared the function. Up till this point, everything is the same.
Now observe the Decelerator statement. The parameter specified is int var1, int var2
What this means is that in the function named add, var1 and var2 are integers that are
used in the body of the function. In the body We have declared a third integer, namely int
var3.
var1 and var2 are added and stored in var3 using the statement:
var3=var1 + var2;
The last statement of the function add, is just to display the value of var3.
Now the question might arise, what are the values of var1 and var2? A good question. To
get an answer to that just read on.
Next the compiler comes to the main function. So far the compiler has only read through
the code. When it comes to the main function it will start performing. Two integers have
been declared and defined as int num1 and int num2.
The values of num1 and num2 are obtained from the user. After obtaining the values, you
see the statement:
add(num1,num2);
As you know, add is the name of a function that has already been defined. So this
statement is the function call. In the brackets, We have mentioned the two arguments
namely num1 and num2. These two values have already been obtained from the user.
The compiler then goes to the function definition of add. Over there we have mentioned
51 Avinash Kumar Singh
the arguments as int var1 and int var2. But remember that the data type of the argument
is the same. Num1, num2 are integers and so also are var1 and var2.
What the compiler does next is to assign the value of num1 to var1 and num2 to var2.
Thus now,
var1=num1 and var2=num2.
If we had used the function declaration then it would have been as follows:
Return value, as the name suggests, is used to return some value. When a function
completes its execution it can return a single value to the calling program.
Return variable;
When a function returns a value, the data type of the value must be specified in the
function.
As you have already learnt, the right side of the equal sign is actually the function call.
This is being assigned to a variable called sum. Hence, it can clearly be seen that the
function add has to be executed and some value should be returned. This value is
assigned to sum.
As you can see, in the declarator instead of void we have mentioned int as return data
type. This means that the function add will return (or give back) an integer quantity to the
calling program (in this case the caller is main function).
The calling program is the one that calls a function. In this case the main function calls
the function add. When the compiler executes the add function, it knows that the add
function has to return a value to the main function (because the return data type of add is
int). Therefore, the sum of num1 and num2 will be returned to main.
This will be assigned to sum. Earlier when the return data type was void, nothing was
returned by the function.
int main ( )
{
................. //program code
return 0;
}
This isn't an actual benefit but We just want to show you the difference. For exact
reasons as to why we use int main ( ) check out the next section.
Simple since test is equal to 1, the compiler will go into the body of if. It will display You
typed 1 on the screen. Then the compiler will return a value of 1. Generally a return value
of a non-zero number is used when errors are encountered.
You can't use this return value anywhere else. In other functions (functions other than
main), you can make use of the return value. A return value of 0 indicates a normally
terminated program. After returning the value, the program exits. This is the point to be
noted.
Which means that the compiler will not even read the remaining few lines and hence
nothing else will display on the screen. The compiler will quit once an integer has been
returned to main.
On the other hand if you type anything other than 1 for test, the compiler will skip the if
body, display the last statement and then return 0. The program gets terminated. Learn
more in the next section.
We thought that since we have taken a discussion of void main and int main, we could
now go one step further into the topic.
Which one is better? Or which one should we use and why?
You might have had this question about where does main function return its value to?
Generally, a return value has to be returned to the calling process.
When you use int main ( ), the main function returns an integer to the operating system
(since the OS is what calls the program and in turn the main function).
So OS is the one that calls your main ( ) function. Returning a value from main ( ) is like
an exit function. The value is returned to the operating system and the program ends.
Actually, the OS never wants to know what you return. The program which started your
program might need to know. In any OS, a program when running is called a "process".
When booting up, the operating system starts the first process . Thereafter the first
process starts other processes such as a shell (shell is just a program which reads
commands from the user and converts it to system calls).
So when you write a program and execute it in the shell, the shell starts your program.
So now, the shell is the parent process of your program (and your program is the child of
the shell); Now, in the same way, suppose you want one of your programs to load
another program to do a particular job and you want to know just whether the job was
successful or not, then the OS get the exit code of the child process and gives it to the
parent process; just like returning from a function.
Hence it's always better to use int main ( ) along with a return value at the end of the main
( ) function. A return value of zero indicates a normally terminated program. A non-zero
value is used in case of errors. Of course this does not mean that a program written with
void main ( ) won’t work; but it is better to avoid writing such programs:
All the other programs that We have written so far have used void main ( ). They will all
work if you use int main ( ) with a return value as done in the above example.
We advise you to go on with int main ( ) rather than void main ( ) whenever you write C++
programs.
Types of Functions
There are two types of functions namely:
The declaration of library function is in the header file specified at the beginning of the
program.
The definition is in a library file that is automatically linked to the program.
Declaration and definition are not required. We will only call the function. Example: clrscr
( ).
Declaration and definition are part of the source file (*.cpp file).
Function definition and declaration have to be written by us.
Example of user defined function is the add function that we saw in the previous section.
Pass by Value and Pass by Reference
We have seen as to how to pass values to a function by making use of arguments. First
let me make one concept clear. What is a parameter and what is an argument? Parameter
is the variable that you declare within the function. Argument is the variable that you
pass to a function.
Pass By Value
Example:
void check ( int x )
{....................
}
int main ( )
{
...........................
int b = 10;
check (b);
......................
}
You can see that the value of a is unchanged. The function square works only on the
parameter (i.e. on x ).
Pass By Reference
In pass by reference method, the function will operate on the original variable itself. It
doesn't work on a copy of the argument but works on the argument itself.
Consider the same square function example We took in the previous section.
As you can see the result will be that the value of a is 100. The idea is simple: the
argument passed is the address of a. The parameter of square is a pointer pointing to
type integer. The address of a is assigned to this pointer. Within the function We've
written:
*x = (*x) * (*x);
*x is pointer variable we write '*' operator before any variable then it becomes a pointer
variable.* when used before a pointer, will give the value stored at that particular
address. Hence we find the product of a and store it in a itself. i.e. the value of 100 is
stored in the address of a instead of 10 which was originally stored.
In C++ we make use of the reference parameter. All you need to do is put & before your
function's parameter. Example: void square (& x)
Whatever operation is done on x will actually affect the original calling argument.
Basically x can be said to be an implicit pointer. The difference is that you needn't use *x
to operate on the parameter. We'll show you with an example (the same square function
example).
Function Overloading
Many functions can have the same name but they should have different number of
arguments or the types of the arguments should be different. This is known as function
overloading.
Inline Functions
There may be instances when you want to repeat a process more than once in a program.
Well, you may think of going for the concept of functions. It’s fine as long as your
function is a bit long. Suppose there are only one or two lines you want to repeat? Is it
worthwhile going for a function?
When our compiler friend sees a function call, the compiler has to save the present
memory address and then go to a new memory address to access the function. This
means it will take some time and also use some memory space.
If a function is very small, then there is no need to go for branching to sub routines (i.e.
there is no need for using another function).
Instead, we can make use of the inline functions. Inline functions will simply substitute
the lines into the main program where the function is called.
Example:
The advantage is that the compiler doesn’t need to save its present memory address, go
to the function’s memory address, execute the function and return back to the original
address. Instead the code is brought into the main program.
Recursion
This is another favorite topic in interviews and in question papers.
What is recursion? Recursion comes from the word ‘to recur’ which means happening
repeatedly over and over again.
In programming we have recursive functions and they are functions that keep repeating
themselves. How do they repeat themselves? Well, it’s like the function keeps calling
itself till an end occurs. It might seem really funny to think of a function calling itself but
this is what exactly happens.
The best example for recursion is to calculate factorials. In the last program We wrote a
function to find the factorial of a number using ‘for’ loop. We’ll now see how to do the
same using recursion. Remember to read the program just like the compiler would read
it; otherwise you’re bound to get confused.
First of all, the function fact ( ) is the recursive function here. Why? Check out the
function body and you’ll see that this function calls itself. So, let’s read through the
function just like the compiler would. For understanding purpose, let’s assume that we
want to find the factorial of 4.
The compiler enters into the recursive function and calculates value of ‘result’.
what does fact(3) mean? ‘Fact’ is a function and hence the function is being called with a
different argument value. The value returned by the function is ‘result’ (which is
4*fact(3)). But there is another function called in this returned value. So the program tries
to calculate fact(3). When calculating fact(3), it again calculates the value of ‘result’. Now,
result=3*fact(2);
63 Avinash Kumar Singh
This value is returned and your actual expression in the computer would be 4*3*fact(2).
What next? Calculate fact(2) and this leads to:
result=2*fact(1);
Hence the expression in the computer will be 4*3*2*fact(1). The program calculates
fact(1). When the value of ‘n’ is 1, we have specified an ‘if’ condition that says:
return 1;
Hence 1 is returned for fact (1) and the entire expression now is: 4*3*2*1 and the compiler
produces the result by multiplying all the terms.
If you don’t give the ‘if’ condition the recursive nature will never stop and it will lead to
problems.
Remember: When using recursive functions make sure that there is a way for the
function to stop itself from infinitely repeating itself.
Will it repeat infinitely? When using recursion there are chances for stack overflow. Stack
is a special portion of memory where the computer stores temporary values. For example
when a computer encounters a function call, it has to store the current location before
going to the function. When the function is executed, the program will return back to the
original position and continue the program execution. In recursive functions, there are
chances for the stack getting used up quickly. That’s what is stack overflow.
Anyway, there isn’t much advantage of using recursion but there may be some cases
where you feel that recursion might make the coding easier. But be very careful while
using recursion.
Remember: Any C++ function can be made recursive. What about main( )? It is also a C++
function. Well, main ( ) is the one function which CANNOT be made recursive.
Manipulators
Manipulators are keywords that are used for doing something to change the way the
output appears on the screen. They are only for presentation purpose; just to make your
program output look better.
One of the most commonly used manipulators is endl. This is used to end the line and
leave the next line blank. endl is used along with cout. You cannot use endl separately.
The iomanip.h header file is used to include the manipulators.
The above program will display the line Hi, this is a test program. After this line there is
an endl. Hence the compiler will end the current line and leave the next line blank. The
next cout statement is again endl. This means another line is left blank. The next
statement starts with an endl. Hence a third line is left blank before printing the last
sentence on the screen.
The output will be the same ,but We just wanted to illustrate that ways in which endl
could be use.
When a program is executed, the objects interact by sending messages to one another.
For example, if "customer" and "accountant" are two objects in a program, then the
customer object may send message to the account object requesting for the bank
balance. Each object contains data, and cod to manipulate the data.
Objects can interact without having to know details of each other's data or code. It is
sufficient to know the type of message accepted, and the type of response returned by
the objects.
Declaring an object:
Declaring Object:
Every object has its own memory and can store different data. Objects maintain a copy of
attributes of the class.
Classes
A class represents a group of similar objects. A class bears the same relationship to an
object that a type does to a variable. The Class forms the basic for object oriented
programming in C++. Any thing you want to encapsulate should be placed with in the
class. A class is a user defined data type. Once defined it is used to define objects of that
type. A class is template for an object and an object is an instance of a class. When
The body of the class is enclosed in the braces and terminated by semi-colon. The class
body contains the declaration of variables and functions. These functions and variables
are collectively called data members. Their are usually grouped under two sections,
namely, private and public to denote which of the members are private and which of them
are public. The keywords private and public are known as visibility levels. Note that these
keywords are followed by colons.
The class members that have been declared as private can be accessed only from within
the class. On the other hand, public members can be accessed from outside the class
also.
The variables declared inside the class are known as data members and the functions are
known as member functions.
Syntax of a class:
Keyword class name of class
{
private :
private data;
public :
public function;
}; // End of class- make a note of the
Next comes the public part. In public we define any function that we want to make use of.
The function definition is done in the usual way. Remember: only functions belonging to
the class can access the private members.
We have made three functions for a simple operation of adding two numbers. If you go
through the statements, you may feel that the same thing could have been put under one
function itself. The answer yes. If you want, you do the adding of two numbers and
displaying the result within one function itself.
The three functions are called member functions, i.e. any object belonging to the class
can make use of the member function.
The input function which comes under public part is changed as follows:
int main( )
{
add a1, a2; // Defining two objects a1 and a2 under the same class add
a1.input(x,y); // get the values for num1 and num2 for object a1
a1.sum( )
a1.display( ); // display sum of numbers entered for a1
a2.input(x,y); // get the values for num1 and num2 for object a2
a2.sum( )
a2.display( ); // display the sum of two numbers entered for a2
return 0;
}
Hence in the result of the above program, you will get two separate answers. One is the
result of adding num1 and num2 of a1 and the other is the result of adding num1 and
num2 of a2.
Class is just a template or a form of data. Template means that it doesn’t physically
occupy any memory space. But when an object is defined, memory is allocated. Template
can be compared to the plan of a building. When the plan is drawn, we have not yet
allocated the area on land for construction. We only know about how the building
structure will be. But when construction is started, the area has been allocated.
Similarly, the compiler allocates memory space only when an object of the class is
defined. A class on its own without any objects does not occupy any space.
Syntax of a class:
First of all, the name of the class is add. Under this class we have the three member data:
num1, num2, num3. Note that all three are made private. This means that any object that
is created under the class add, will have these three member data already in it.
Next comes the public part. In public we define any function that we want to make use of.
The function definition is done in the usual way.
Remember: only functions belonging to the class can access the private members.
We have made three functions for a simple operation of adding two numbers. If you go
through the statements, you may feel that the same thing could have been put under one
function itself. The answer yes. If you want, you do the adding of two numbers and
displaying the result within one function itself.
The three functions are called member functions, i.e. any object belonging to the class
can make use of the member function.
add a1 ; is the first statement in the main function. This statement creates an object
named a1 belonging to the class add. Then we get the value for two integers x and y. The
next statement is a1.input (x,y);
a1 is the name of the object, input is a member function with two arguments (two integer
arguments). If you remember we defined the input function in the public part of the class.
Then there is the dot operator. The dot operator comes in between the object name and
the member function. It is used to access or invoke the function. By invoke, We mean
executing the function.
When the compiler sees the line a1.input (x,y); it knows this is a function call. It goes to
the input function that has been defined. The value of x and y is passed on to the
integers var1 and var2. Then the input function is executed. The input function just
assigns the value of var1 (i.e. actually the value of x that the user entered) to the member
data num1. Similarly it assigns var2 to num2, which is also a member data. All the
member functions can make use of the member datas.
You might be wondering what’s the use of the object a1? Why do we need it?
Read on for answers: Just like a1 you can create another object called a2 under the same
class add. This object will also have the same member datas and also the member
functions. They can all be used in the same way as you used a1.
If you are doing so, it would be advisable to make the following change: Put the
statement to obtain the numbers from the user within the input function, rather than
keeping it in the main function.
The input function which comes under public part is changed as follows:
int main( )
{
add a1, a2; // Defining two objects a1 and a2 under the same class add
a1.input(x,y); // get the values for num1 and num2 for object a1
a1.sum( )
a1.display( ); // display sum of numbers entered for a1
a2.input(x,y); // get the values for num1 and num2 for object a2
a2.sum( )
a2.display( ); // display the sum of two numbers entered for a2
return 0;
}
Hence in the result of the above program, you will get two separate answers. One is the
result of adding num1 and num2 of a1 and the other is the result of adding num1 and
num2 of a2.
Example:
class add
{
private :
int num1, num2, num3; // The member data has been made private
public :
void input (int var1, int var2)
{
num1 = var1;
num2 = var2;
}
// ... you could have other member functions
};
int main ( )
{
add a1; // Creating an object a1
cout<<"Enter a value for num1";
cin>>a1.num1; // *** Error cannot run this program ***
return 0;
}
a1 is an object of the class add. num1 is a private member of class add. Private members
cannot be accessed directly by the object. Therefore, a1.num1 is an error. You can
access num1 only through one of you public functions.
Static Members
We’ve already seen about the use of static. Now we shall see the use of static in classes.
Before going into the topic We would like to restate that a class is just an empty area. No
area is allocated when you create a class. So, only when you create an object of that
class the compiler will allocate space to the object. Again, this means that:
private:
int x;
does not allocate space for an integer x. When you create objects belonging to this class,
required space is allocated for holding the integer. Each new object that you create
As you can see, the integer ‘count’ is declared to be static. But again outside the class
we say:
int bacteria::count=5;
This is done so that the compiler will allocate space for the integer ‘count’. If ‘count’ were
not static, when would the compiler allocate space to it? It would allocate space when an
object is created. But in the case of static variable members in a class, we will create it
only once and so we have to ensure that the compiler creates that one instance of the
variable. In this case we’ve initialized it to a starting value of 5. If you type:
int bacteria::count;
So far we’ve seen static member data but you can also make functions static in a class.
Just precede the function by the keyword static. Static functions will be useful to operate
on static member data
Friend Function
Remember We said that the private member datas of a class can be accessed only by the
class' member functions. Well, there is one exception. We have what is called a friend
function. As the name implies, a friend function will be friendly with a class even though
it is not a member of that class. Perhaps we are confusing you a little. Don't worry, just
check out the example below:
we'll give you a little explanation so that you can understand the concept. First of all
we've created a class named counter. It has one private data: count and one public
function setvalue. It also has a friend function called getvalue. Then we've terminated the
class.
In the main ( ) part, we've created an object called test whose count value is set to 6.
Then we've called the friend function using getvalue(test).........This means, the compiler
goes to the friend function getvalue, and uses the object test as the argument. So the
value returned will be the count value of test (in other words it is test.count) and the
result will be 6.
What is to be remembered is: Friend functions are not members of any class. They can
access private data of the class to which they are a friend. Since they are not members of
any class, you should not call them using the dot operator.
There are many uses, but the one We will deal with here is : being friendly to 2 or more
classes. The friend function does not belong to any class, so it can be used to access
private datas of two or more classes. we'll show you with an example:
Just one thing to explain: In the second line of the program we've written: class
counter2;
This is a forward declaration of the class counter2. This is done because when the
compiler reads through the lines in counter1 class, it encounters the word counter2 in
the friend function. Uptil this point it doesn't know what counter2 is because we will be
defining the counter2 class later on. So we tell the compiler in advance that counter2 is a
One more note: You should declare the friend function in both the classes where you
want it to be a friend.
First of all, let us suppose that we have a file by the name marks.cpp. From this file we
make an exe file called marks.exe. This is an executable file and you can run it from the
command prompt. The command prompt specifies what drive and directory you are
currently in. The command prompt can be seen in the ms-dos prompt.
C:\WINDOWS> This denotes that you are in C drive and in the directory of Windows.
Your marks.exe program is in this directory(let us assume this). To run the program you
will type:
You must be thinking that we will type only the name of the program? In this case the
C++ program that you wrote is assumed to have arguments for the main function as
follows:
Save the file as test.cpp. Compile it and then make the executable file (test.exe). If you
run test.exe from Windows (i.e. by just double clicking on the file), the output may just be
as follows:
Remember that the function has to work on the exact copy of the original object.
Constructors are usually used to initialize the member data. Thus, if the function invokes
the constructors (it will initialize the member data), it will not be able to act on exact
replicas of the original object. So, it does not invoke the constructor.
But whatever has come into existence has to be destroyed and thus the 2 extra
organisms are destroyed. There is a very important fact to be noted here. Usually we will
specify the ‘delete’ keyword in the destructor to free up any memory that was taken up
from the heap. When a function creates a copy of an object, it will copy the destructor
also exactly as it is in the original object.
Thus in the original object you will have a statement using ‘delete’, which will free up
some particular memory space. The copied object will also have the same destructor and
thus it will also ‘delete’ from the same memory area.
You should never use the delete twice (We mean if you have one ‘new’, you should have
only one ‘delete’). Double ‘delete’ can lead to serious errors. Thus the method of copying
objects can sometimes lead to problems and for this purpose we have copy constructors
(We’ll deal with them later).
int variable = 5;
This line declares variable to be an integer and assigns the value of 5 to variable.
Similarly, how about initializing an object?
Constructors are used for this purpose. A constructor is a special member function with
same name as the class. It is used for the automatic initialization of object and it is
carried out at the time of creation.
Syntax:
constructor name (arguments): member data (value)
{}
As usual let's take a look at a simple program to illustrate the use of constructors.
class counter
{
private:
int count;
public:
counter ( ) : count (0) // Constructor initializes member data count to zero.
{}
.................................... // As usual you can write the public functions
};
int main ( )
{
counter c1;
return 0;
}
class counter
{
private:
int count;
public:
counter (int x) : count (x)
{}
.................................................// Some other functions in the class
};
int main ( )
{
int y;
counter c1(2);
cout<< "What value of count do you want initialize it to?";
cin>>y;
counter c2(y);
......................................// We're not typing the rest. It could be anything to suit your
purpose.
return 0;
}
Program is simple. counter c1(2); means that the constructor with one argument is
invoked. The argument passed is 2. Its value is assigned to count. count (x) is equal to
count = x. Hence count of object c1 is two.
counter c2 (y); means that count of c2 will be initialized to the value of y (i.e. the value the
user types in).
It also possible to define constructors with default argument. For example, the
constructor count() can be declared as follows:
Copy Constructor
A copy constructors is used to declare and initialize an object from another object. A
copy constructor is invoked when you initialize a new object of a class using an existing
object. This will happen when:
You pass a copy of an object as argument to a function (i.e. when passing by value).
When you return an object from a function
Or initialize an object during declaration using another object.
If we don’t specify a copy constructor, the compiler already has a default copy
constructor. This default copy constructor will simply perform a bit-by-bit copy of the
original object to the new object (i.e. it will blindly copy everything to the new object). As
we saw earlier, this can lead to problems (especially when we use the ‘new’ and ‘delete’
operators in the constructor and destructor of the class).
Let us suppose that we are using the ‘new’ operator in the constructor of the class and
we have a function whose argument is an object of that class. While calling this function,
we will pass an existing object to the function. The function will create a temporary
object but it will not invoke the constructor for this new object. Hence the ‘new’ operator
(present in the constructor) is not invoked and an exact replica of the passed object is
made. During destruction, the temporary object will invoke the destructor (which has the
‘delete’ operator and it will delete the portion of memory allocated to the original object).
When the original object is destroyed, it will also invoke the destructor and this will again
try to free the same memory. This can lead to serious problems. To solve this problem
we have to define our own copy constructor.
Let ‘bacteria’ and ‘virus’ be two classes. Each one will have an array called ‘life’ created
dynamically using the ‘new’ operator. We shall also define a friend function to which we
will pass objects of both ‘bacteria’ and ‘virus’.
Beware: The copy constructor will not work when you use the assignment operator (=) to
assign one object to another. In such cases, you have to overload the = operator to avoid
the problem (overloading is discussed in the next chapter).
Dynamic Constructors
86 Avinash Kumar Singh
The constructors can also be used to allocate memory while creating objects. This will
enable the system to allocate the right amount of memory for each object when the
objects are not of the same size, thus resulting in the saving of memory. Allocation of
memory to objects at the time of their construction is known as dynamic construction of
objects. The memory is allocated with the help of the new operator.
Here we are going to introduce the destructor which is often not necessary. You can use
it to do some calculation whenever an instance is destroyed or output some text for
debugging. But if variables of the instance point towards some allocated memory then
the role of the destructor is essential: it must free that memory!
Destructors in Details
Just as a constructor is used to initialize an object when it is created, a destructor is
used to clean up the object just before it is destroyed. A destructor always has the same
name as the class itself, but is preceded with a ~ symbol. Unlike constructors, a class
may have at most one destructor. A destructor never takes any arguments and has no
explicit return type.
Destructors are generally useful for classes which have pointer data members which
point to memory blocks allocated by the class itself. In such cases it is important to
release member-allocated memory before the object is destroyed. A destructor can do
just that.
For example, our revised version of Set uses a dynamically-allocated array for the elems
member. This memory should be released by a destructor as follows:
class Set {
public:
Set (const int size);
~Set (void) {delete elems;} // destructor
//...
private:
int *elems; // set elements
int maxCard; // maximum cardinality
int card; // set cardinality
};
Now consider what happens when a Set is defined and used in a function:
Use of this in this particular example is redundant. There are, however, programming
cases where the use of the this pointer is essential. We will see examples of such cases
in Chapter 7, when discussing overloaded operators.
The this pointer can be used for referring to member functions in exactly the same way
as it is used for data members. It is important to bear in mind, however, that this is
defined for use within member functions of a class only. In particular, it is undefined for
global functions (including global friend functions).
Scope Operator
When calling a member function, we usually use an abbreviated syntax. For example:
class Point {
public:
Point (int x, int y) { Point::x = x; Point::y = y; }
//...
private:
int x, y;
}
Here x and y in the constructor (inner scope) hide x and y in the class (outer scope). The
latter are referred to explicitly as Point::x and Point::y.
class Image {
public:
Image (const int w, const int h);
private:
int width;
int height;
//...
};
The second approach uses a member initialization list in the definition of a constructor.
For example:
class Image {
public:
Image (const int w, const int h);
private:
int width;
The effect of this declaration is that width is initialized to w and height is initialized to h.
The only difference between this approach and the previous one is that here members
are initialized before the body of the constructor is executed.
A member initialization list may be used for initializing any data member of a class. It is
always placed between the constructor header and body. A colon is used to separate it
from the header. It should consist of a comma-separated list of data members whose
initial value appears within a pair of brackets.
Constant Members
A class data member may defined as constant. For example:
class Image {
const int width;
const int height;
//...
};
However, data member constants cannot be initialized using the same syntax as for other
constants:
class Image {
const int width = 256; // illegal initializer!
const int height = 168; // illegal initializer!
//...
};
The correct way to initialize a data member constant is through a member initialization
list:
class Image {
public:
Image (const int w, const int h);
private:
const int width;
const int height;
//...
};
class Set {
public:
Set (void) : maxCard(10) { card = 0; }
//...
private:
const maxCard;
int elems[maxCard]; // illegal!
int card;
};
The array elems will be rejected by the compiler for not having a constant dimension. The
reason for this being that maxCard is not bound to a value during compilation, but when
the program is run and the constructor is invoked.
Member functions may also be defined as constant. This is used to specify which
member functions of a class may be invoked for a constant object. For example,
class Set {
public:
Set (void) { card = 0; }
Bool Member (const int) const;
void AddElem (const int);
//...
};
defines Member as a constant member function. To do so, the keyword const is inserted
after the function header, both inside the class and in the function definition.
A constant object can only be modified by the constant member functions of the class:
const Set s;
s.AddElem(10); // illegal: AddElem not a const member
s.Member(10); // ok
92 Avinash Kumar Singh
Given that a constant member function is allowed to be invoked for constant objects, it
would be illegal for it to attempt to modify any of the class data members.
Constructors and destructors need never be defined as constant members, since they
have permission to operate on constant objects. They are also exempted from the above
rule and can assign to a data member of a constant object, unless the data member is
itself a constant.
Static Members
A data member of a class can be defined to be static. This ensures that there will be
exactly one copy of the member, shared by all objects of the class.
For example, consider a Window class which represents windows on a bitmap display:
class Window {
static Window *first; // linked-list of all windows
Window *next; // pointer to next window
//...
};
Here, no matter how many objects of type Window are defined, there will be only one
instance of first. Like other static variables, a static data member is by default initialized
to 0. It can be initialized to an arbitrary value in the same scope where the member
function definitions appear:
Window *Window::first = &myWindow;
The alternative is to make such variables global, but this is exactly what static members
are intended to avoid; by including the variable in a class, we can ensure that it will be
inaccessible to anything outside the class.
For example, the Window class might use a call-back function for repainting exposed
areas of the window:
class Window {
//...
static void PaintProc (Event *event); // call-back
};
Because static members are shared and do not rely on the this pointer, they are best
referred to using the class::member syntax. For example, first and PaintProc would be
defines a member function pointer type called Compare for a class called Table. This
type will match the address of any member function of Table which takes two constant
character pointers and returns an int. Compare may be used for passing a pointer to a
Search member of Table:
class Table {
public:
Table (const int slots);
int Search (char *item, Compare comp);
The definition of Table includes two sample comparison member functions which can be
passed to Search. Search has to use a slightly complicated syntax for invoking the
comparison function via comp:
Note that comp can only be invoked via a Table object (the this pointer is used in this
case).
None of the following attempts, though seemingly reasonable, will work:
Therefore the brackets around this->*comp are necessary. Using a Table object instead
of this will require the following syntax:
Table tab(10);
(tab.*comp)(item, entries[mid])
Search can be called and passed either of the two comparison member functions of
Table. For example:
tab.Search("Sydney", Table::NormalizedComp);
The address of a data member can be obtained using the same syntax as for a member
function.
For example:
The above class member pointer syntax applies to all members except for static. Static
members are essentially global entities whose scope has been limited to a class.
Pointers to static members use the conventional syntax of global entities.
In general, the same protection rules apply as before: to take the address of a class
member (data or function) one should have access to it. For example, a function which
does not have access to the private members of a class cannot take the address of any
of those members.
References Members
A class data member may defined as reference. For example:
As with data member constants, a data member reference cannot be initialized using the
same syntax as for other references:
class Image {
int width;
int height;
int &widthRef = width; // illegal!
//...
};
The correct way to initialize a data member reference is through a member initialization
list:
class Image {
public:
Image (const int w, const int h);
private:
int width;
int height;
int &widthRef;
//...
};
class Rectangle {
public:
96 Avinash Kumar Singh
Rectangle (int left, int top, int right, int bottom);
//...
private:
Point topLeft;
Point botRight;
};
The constructor for Rectangle should also initialize the two object members of the class.
Assuming that Point has a constructor, this is done by including topLeft and botRight in
the member initialization list of the constructor for Rectangle:
If the constructor for Point takes no parameters, or if it has default arguments for all of its
parameters, then the above member initialization list may be omitted. Of course, the
constructor is still implicitly called.
The order of initialization is always as follows. First, the constructor for topLeft is
invoked, followed by the constructor for botRight, and finally the constructor for
Rectangle itself. Object destruction always follows the opposite direction. First the
destructor for Rectangle (if any) is invoked, followed by the destructor for botRight, and
finally for topLeft. The reason that topLeft is initialized before botRight is not that it
appears first in the member initialization list, but because it appears before botRight in
the class itself. Therefore, defining the constructor as follows would not change the
initialization (or destruction) order:
//destructor codes
ragged::~ragged()
{
node *ptr;
You have to remember that objects are defined by you (We mean they are defined by the
programmer). The data that comes under an object is chosen by you. The data type that
you use will be in-built data type like integer or character but the object as a whole is
user defined. Hence it is not possible to add two objects (that belong to the same class)
using the + sign.
But using operator overloading you could use the same + sign to add two objects.
Syntax:
return data type keyword operator sign of operator to be overloaded (arguments)
{
body of the function;
}
Example:
void operator ++ ( )
{
body of function;
}
class counter
{
private:
int count;
public:
counter ( ) : count (0) // Constructor that initializes count to zero
{}
int display ( )
{
return count;
}
99 Avinash Kumar Singh
void operator ++ ( ) // ++ is overloaded operator. When compiler comes across ++
{ // anywhere in the program, then if the operand is user defined,
++ count; // the compiler will do whatever is written within the body of the
operator function
}
};
int main ( )
{
counter c1, c2; // c1 and c2 are two objects belonging to class counter
cout<<c1.display( ); // count of c1 is 0
cout<<c2.display( ); // count of c2 is 0
++c1; // ++ is an overloaded operator
++c2; // Compiler knows this because c1 and c2 are objects-they are
user defined
++c2;
cout<<c1.display( ); // count of c1 is 1
cout<<c2.display( ); // count of c2 is 2
return 0;
}
When compiler comes across ++c1 it does the following. It knows that c1 is an object
which a user defined data type.
But ++ can operate only on in-built data types. Now it thinks. It remembers that ++ was
already overloaded using the operator function within the class counter. So it goes back
to the operator function and reads through what is written in the body. No return data
type and no arguments. This makes it work a lot easier.
++count;
count is an integer data type. The compiler increases the value of count by one and goes
back to the original program. All this was done when it saw ++c1. Hence the count of c1
only is increased by one.
When the compiler comes to ++c2 it increases the count of c2 by one.
enum E {e = 37};
cout << e;
37 will indeed be output, by virtue of the enumerator value being promoted to an int and
then output using the operator<<(int) function found in iostream.h.
In the last output statement, we created an invalid enumerator value and then output it.
Operator overloading in C++ is very powerful but can be abused. It's quite possible to
create a system of operators such that it is difficult to know what is going on with a
particular piece of code.
Example:
The values of feet and inches for dist1 are got from the user while dist2 is initialised to 11
feet and 6.25 inches.
First of all, you know that dist2 is passed as an argument. Hence, d2 actually represents
dist2 in our case.
f and i are two variables declared as integer and float respectively.
In the expression : int f = feet + d2.feet; what does the feet stand for?
This feet is the value of dist1's feet. dist1 is on the left of the operator and it is not passed
as argument. Hence feet and inches refer to the values of dist1.
In technical terms: When an overloaded operator is invoked, the object on the left of the
operator is the object of which the operator is a member and the object on the right must
be provided as argument to the operator.
The program overloads the operator * two times , thus overloading the operator function
.operator*()itself.In both the cases, the function are explicitly passed two arguments and
they are invoked like any other overloaded function, based on the types of its arguments.
This enable us to both the forms of scalar multiplication such as
p=2*m; //equivalent to p=operator*(2,m);
q=n*2;//equivalent to q=operator*(n,2);
The prog. and its output are largely self-explanatory. The first constructor
vector();
constructs a vector whose elements are all zero. Thus vector m;
creates a vector m ands initialize all its element to 0.The second operator-vector(int*x);
Beware: There are some operator which can't be overloaded e.g.:- sizeof,.,.*,::,?: etc.
Type Conversions
Some types are automatically converted to other types as needed.
For example, an integer value can always be used where a double value is expected. In
the following:
a := 5
b := a * .2
b is assigned the double value 1.0 and a's type remains integer. Similarly, a double value
can be converted to a dcomplex value. Automatic conversions are limited to converting
between numeric types, and converting a reference type to the type it refers to.
Other types require explicit conversion. For example, the following expression is illegal:
5 * "1234foo"
but the string can be explicitly converted to an integer using the function as_integer. The
following yields an integer value of 6170:
5 * as_integer("1234foo")
as_boolean
as_byte
as_short
as_integer
as_float
as_double
as_complex
as_dcomplex
as_string
Type Conversion
The following functions convert their argument to the stated type:
as_boolean(x)
as_byte(x)
as_short(x)
as_integer(x)
as_float(x)
as_double(x)
as_complex(x)
as_dcomplex(x)
as_string(x)
Boolean Conversions
Conversion of a numeric values to Boolean yield T if the converted value is non-zero. A
string value yields T if its length is non-zero.
For example:
yields T, and
as_boolean(".0000001foo")
and
as_boolean("0.")
and
as_boolean(0+9i)
Note that an empty string here means a string with no text in it; this is different from a
string with no elements.
as_boolean('')
yields F, but
as_boolean("")
Integer Conversions
A boolean value converted to byte, short, or integer yields 1 if the value was T and 0 if F.
Conversions between byte, short, and integer types yields the same values as the host
machine's C++ compiler doing the same conversion via a cast.
A float or double value yields the same integer value as the host machine's C++ compiler
doing the same conversion via a cast. In particular, it is possible for a value like -3.14159
to be converted to -3 or -4 depending upon the particular compiler. If the direction of this
conversion is important, you can use floor and ceiling:
ceiling(x)
returns the smallest integer which is greater than or equal to the argument, x. This
function can be abbreviated as ceil. If x is a vector, ceiling is applied to each of the
elements of the vector.
floor(x)
returns the largest integer which is less than or equal to the argument, x. If x is a vector,
floor is applied to each of the elements of the vector.
A string value is converted as per the C (and C++) routine atoi(). If the value is not a valid
integer then it is converted to 0.
complex or dcomplex values lose their imaginary portion when converted to float or
double.
A string value is converted as per the C (and C++) routine atof(). If the value is not a valid
floating-point number then it is converted to 0.0.
107 Avinash Kumar Singh
Complex Conversions
A boolean value converted to complex or dcomplex yields 1.0+0.0i if T and 0.0+0.0i if F.
String Conversions
boolean
values when converted to a string yields "T" if true and "F" if false.
float
values are converted as per printf()'s "%.6g'' format.
double
values are converted as per printf()'s "%.12g'' format.
complex
values are converted as per printf()'s "%.6g+%.6gi'' format.
dcomplex
values are converted as per printf()'s "%.12g+%.12gi'' format.
The conversion of floating point values to strings are changed by setting the
system.print.precision value or the print.precision attribute for an individual value.
By the way, in many instances you may come across the term ‘method’. A method is just
another term used for a function.
Now let us assume that you have created a new library that you want to distribute to
other programmers. A library is a C++ code written for some specific purpose.
For example, working with images (bmp, gif or jpg) isn’t so easy in C++. You have to
write methods (functions) for reading an image, identifying what type it is, displaying etc.
There are many applications where image processing is applicable. The simplest
application is in Optical Character Recognition (OCR). In OCR we try to write a program
that will be able to recognize hand-written letters or numbers.
For instance, if you write 8, the computer should be able to recognize that an 8 has been
written (no matter how bad the handwriting is). Whatever you write on paper will be
scanned into the system and stored in the form of an image file. A programmer
developing an OCR application, could either start from scratch or he could focus on his
problem (i.e. OCR). By starting from scratch, We mean that he has to write a lot of coding
for reading an image etc. If he can get access to some good Image processing library he
could simply use the #include directive and concentrate on the OCR algorithm.
So, let’s say that you have created a library for the purpose of image processing. You will
make use of the concept of classes. You will create a class called ‘Image’ which will
contain member functions for reading an image, identifying the type of image etc. You
will also have some member data like the height and width of the image. When you
distribute your library to others, you give them the opportunity to create objects (or
instances) of your ‘Image’ class. You will also have provided a little help file describing
the various functions that are available for use. Note: You will only describe the use of
the various functions (ex: the function syntax and what it will do). You will not be
providing an insight into the implementation aspect of the function.
Now, the OCR person will start coding for his application. There is a chance that he might
use the same member data identifier ‘length’ and ‘width’ in his program. Imagine the
consequence if ‘length’ and ‘width’ are not made private within the class. If they are not
made private, there is a good chance that the user will fiddle around with the data
(knowingly or unknowingly) and their values will get altered by the user (which is what
you don’t want to happen). The result is that your functions, which operate on these
member data, will produce some ambiguous results. By hiding your data, you prevent
such problems from happening because the user will never be able to access or
modify the member data.
We restrict the user in such a way that the user can perform only limited operations on
the private data (and that is only through the member functions). Another advantage of
hiding the implementation is that you (the class designer) may decide to change the
algorithm used for reading an image. You might have discovered some better and
effective method for doing the same purpose. By hiding the implementation, all you need
to do is to change the function definition. The user will never have to change his code
(because you have only changed the implementation, which the user has nothing to do
with). The code written by the user will still run even though you have changed the
implementation.
Inheritance
Inheritance means getting something from the parent. In C++ also, inheritance means the
same. But who is the parent?
Remember that classes and objects are a key feature in C++. When we talk of inheritance
in C++, we talk of classes. We will have the parent class and the derived class. The
derived class inherits all properties of the parent class.
The parent class is known as the base class. All the classes that arise from the base
class are known as derived classes. These derived classes inherit all non-private parts of
the base class.When any data is made private in a class, it can be accessed ONLY by
member functions of that class.
A derived class CANNOT access the private area of its base class.
Let's take a look at the syntax for making a derived class.
Syntax
The syntax is easy. Just create the base class as you normally would. Then when you
want to create
class d1 : public b1
{
body of d1;
};
where d1 is the name of the derived class and b1 is the name of the base class.
We think you might have just one question. What's the meaning of protected? Well, as
We said earlier, private data of a base class cannot be inherited by it's derived class. So
the question arises as to how to make some data available to both the base and derived
class? The answer is to make use of protected keyword.
Protected data will be inherited by the derived classes.
The rest of the program is as normal.
Multiple Inheritance
One important object-oriented mechanism is multiple inheritance. Multiple inheritance
does not mean that multiple subclasses share the same superclass. It also does not
mean that a subclass can inherit from a class which itself is a subclass of another class.
For example, it might have a method to append other text. In our program we would like
to use this class to add text to the possible drawing objects. It would be nice to also use
already existing routines such as move() to move the text around. Consequently, it
makes sense to let a drawable text have a point which defines its location within the
drawing area.
Therefore we derive a new class DrawableString which inherits properties from Point and
String as illustrated in Figure below:
Definition (Multiple Inheritance) If class A inherits from more than one class, i.e.. A
inherits from
B1, B2, ..., Bn, we speak of multiple inheritance. This may introduce naming conflicts in A
if at least two of its superclasses define properties with the same name.
The above definition introduce naming conflicts which occur if more than one superclass
of a subclass use the same name for either attributes or methods.
For an example, let's assume, that class String defines a method setX() which sets the
string to a sequence of "X'' character. The question arises, what should be inherited by
DrawableString? The Point, String version or none of them?
The question arises what properties class D actually inherits from its superclasses B and
C. Some existing programming languages solve this special inheritance graph by
deriving D with the properties of A plus the properties of B and C without the properties
they have inherited from A.
Another possible solution is, that D inherits from both inheritance paths. In this solution,
D owns two copies of the properties of A: one is inherited by B and one by C.
There are some more types of inheritance is used in the nature of programming, some of
them is given and discussed below:
Hybrid Inheritance
There could be the situations where we need to apply two or more types of inheritance to
design a program. In this case we use Hybrid Inheritance.
Address of a variable
An introduction to pointers
Pointers are variables that store memory address. This address is the address of another
variable.
You know that variables are stored in memory spaces. Memory spaces are bytes.
For information, 8 bits make up one byte. Bits stands for Binary digits. A binary digit is a
one or a zero. You have only one's and zeroes. You may remember that a character
means it requires one byte, an integer two etc......
Every byte will have its own address. In computers the address is a hexadecimal number.
For example: 0X8566fff4 is a hexadecimal number representing an address. Hence when
we say that values of variables are stored in the computer, we actually mean that the
value has been stored in a particular address.
The 'address of ' operator is denoted by '&'. This can be applied to any variable as
illustrated below:
Pointer
Pointers are variables that store memory address. This address is the address of another
variable. Hence a pointer points to another variable.
115 Avinash Kumar Singh
Declaring a Pointer:
Syntax
data type * name of pointer ;
When * is used, it denotes a pointer. The data type denotes the data type to which the
pointer points.
{
int marks = 6; // marks is a variable value of integer type initialized to 6
int * pmarks; // pmarks is a pointer that points to an integer data type.
pmarks = &marks; // pmarks is assigned the address of marks which is a integer.
cout<< *pmarks; // Displays the value of 6. Explanation given below.
cout<< pmarks; // Displays a memory address.
}
We think the above program (you have to write the usual void main and # include
statements) is self explanatory. The only doubt you may have is what does cout<<
*pmarks; do?
In this context * is known as a dereferencing or indirect value operator. This operator will
give the value stored at a particular location. It is the complement of the & operator that
you saw in the previous section. Hence, *pmarks means value at pmarks (which holds an
address).
The difference between pointers and a general variable is that address is primary for
pointers. The value stored at the address is secondary. For other variables, the value is
primary while the address where the value is stored is secondary. The example below
illustrates primary and secondary:
{
int x = 5; // x is an integer
int * p; // p is a pointer
p = &x; // p points to x
cout<<p; // This displays the address. Hence address is primary for pointer
cout<<*p; // Only using * operator can we display the value. Hence value is
secondary. cout<<x; // For the integer, value is primary.
This displays 5
cout<<&x; // Need to use & to display address. Hence address secondary
Note: Make sure that your pointer variable points to the correct type of data. If you
declare a pointer of type int then make sure that the address it holds points to an integer.
Suppose you want to declare two pointers: p1 and p2 that point to an integer data type.
You might right the declaration as:
Seems right, doesn't it? Well the declaration is WRONG. What this does is, declares p1 as
a pointer pointing to integer type. The compiler will consider p2 as an integer and not a
pointer. Since * precedes p1, the compiler knows that p1 is a pointer. Hence be careful
while declaring pointers.
long * marks; // marks is a pointer that points to data type long. Statement correct.
* marks = 223000; // WRONG
Note the point that we have not yet stored any memory address in marks.
When a pointer is created the compiler will allot memory to hold an address. It will not
allocate memory to hold data to which address points. Perhaps it's a bit confusing. Just
read on...
The problem with our program is that we are supposed to store an address in marks.
After storing an address in marks you can then store some value at that address. What
we have done is : we haven't assigned any address to marks. Hence the value 223000
cannot be placed anywhere.
Pointers are not the same as integers. Pointers hold a memory address and hence they
cannot be multiplied or divided. Regarding addition We shall discuss that later. Consider
the following:
We said that you can't perform multiplication and division on pointers. But you can do
addition and subtraction on pointers. Suppose that p1 is a pointer that points to an
integer and the address is 100 (yes, addresses should be hexadecimal numbers but
assume 100 as a memory address for simplicity). Also assume that an integer occupies 2
bytes. Now we say:
p1++ ;
What would the above expression do? The value of p1 (i.e. the address of p1) gets
changed. The address becomes 102 not 101 because an integer occupies 2 bytes. If an
integer occupied 4 bytes then the result would be address 104. Similarly if you do:
p1--;
Hence, when a pointer is incremented it points to the memory location of the next
element of its data type.
p1 = p1 + 10;
This makes p1 point to the tenth element of p1's data type beyond the current position. If
p1 points to a character type then p1 + 10 would move the pointer 10 bytes. Suppose p1
were a integer then p1 would move 20 bytes (if int occupies 2 bytes).
When you say *(p + 1), the pointer adds one to itself (this means the pointer increments
itself by the number of bytes of its data type). Hence it will go to the next integer address
which is array[1]. The output will thus be 5.
Consider a modification of the above program. The code is the same till array[2] = 6; After
this line type in the following code:
this Pointer:
Every C++ class has an implicit pointer called the this pointer. The this pointer points to
the instantiation of the object. The this pointer can be de referenced to members of the
class like any other pointer. Inside of a class declaration the use of the this pointer is
implicit, so the code this->destroy(); is equivalent to destroy();
Basically, the word is the same word but it's interpretation varies depending on the use.
Similarly, in C++ we can make use of polymorphism.
For example: consider operator overloading. You may have created an overloaded +
operator to concatenate two strings. Now, the + sign can be used to add two strings
(because you overloaded it) and it can even be used to add two numbers (which was it's
actual use). Depending on the type of data being operated on, the compiler will decide on
which function to use. If the operands are numbers, then it will use the normal function.
This is a type of polymorphism.
Therefore we have to distinguish different types of polymorphism which will be outlined
here. The first type is similar to the concept of dynamic binding. Here, the type of a
variable depends on its content. Thus, its type depends on the content at a specific time:
v := 123 /* v is integer */
... /* use v as integer */
v := 'abc' /* v "switches" to string */
... /* use v as string */
The concept of dynamic binding allows a variable to take different types dependent on
the content at a particular time. This ability of a variable is called polymorphism.
boolean isNull(int i) {
if (i == 0) then
return TRUE
else
return FALSE
endif
}
However, if we want to check this for real numbers, we should use another comparison
due to the precision problem:
boolean isNull(real r) {
if (r < 0.01 and r > -0.99) then
return TRUE
else
return FALSE
endif
In both cases we want the function to have the name isNull. In programming languages
without polymorphism for functions we cannot declare these two functions because the
name isNull would be doubly defined.
Objects of superclasses can be filled with objects of their subclasses. Operators and
methods of subclasses can be defined to be evaluated in two contexts:
Based on object type, leading to an evaluation within the scope of the superclass.
Based on object content, leading to an evaluation within the scope of the contained
subclass.
The main advantage of virtual function is that they support run-time polymorphism.
Check out the example:
In the starting We've created three classes: base (which is our base class), der1 and der2
(these two are derived from base). The function made virtual is the display ( ) function.
Notice that We use the virtual keyword only in the base's virtual function. The derived
classes der1 and der2, redefine the display ( ) function.
Now come to the main ( ) function.
base *p; As you know this is how a pointer is created. Instead of creating a pointer to an
integer (or character as we usually do), we're creating a pointer to point to base (which is
a class). Hence you can say that p is pointing to an object of type base.
A pointer which points to an object of the base class, can point to an object of a derived
class. But the reverse is not possible.
Pointers can be used to invoke member functions. Invoking in this way is done by using
the following operator: -> (it's a minus followed by greater than sign). Since p is pointing
to an object of base, the display( ) function of base will be executed.
Next comes: p = &d1; A pointer to object of base can point to an object of a derived
class. d1 is an object of der1 (which is derived from base). Therefore, p can point to d1
and the address of d1 is now assigned to p. When the display ( ) function is now invoked
using the pointer p, the compiler will run the derived class der1's version of display ( ).
This decision of choosing which function to execute is made at run-time. Hence this is
known as run-time polymorphism.
In this simple example, Base is an abstract class, and Base::f() a pure virtual function
(denoted by "= 0"). A class is abstract if it contains at least one pure virtual function. No
instances of an abstract class may be created, nor may an abstract class be used as a
function argument or return type. Abstract class pointers and references are always
legal.
Typically an abstract class is used just as in the example above, to serve as a base and
allow for manipulation via pointers or references that actually refer to instances of
derived types.
Although streams produce or consume characters, insertion and extraction can be used
with other types of data.
For instance, in the following statements, the characters '1' , '2' , and '3' are inserted into
the stream cout, after which characters are extracted from cin, interpreted as an integer,
and the result is assigned to i:
int i = 123;
cout << i;
cin >> i;
Insertion and extraction can be overloaded for user-defined types as well. Consider the
following code:
class fraction
{
These statements define an insertion operator for a user-defined fraction class, which
can be used as conveniently and easily as insertion of characters or ints.
You can use member functions of the various stream classes to move the get or put
pointer without performing an extraction or insertion.
For example, the fstream::seekoff() member function moves the get and put pointers for
an fstream.
The exact behavior of the get and put pointers for a stream depends on the type of
stream.
For example, for fstream objects, the get and put pointers are tied together. That is, any
operation that moves one always moves the other. For strstream objects, the pointers are
independent. That is, either pointer can be moved without affecting the other.
The get and put pointers reference positions between the characters of the stream, not
the characters themselves.
For example, consider the following sequence of characters as a stream, with the
positions of the get and put pointers as marked in Illustration of Get and Put Pointers:
In this example, the next character extracted from the stream is 'c', and the next
character inserted into the stream replaces the 'r'.
strstream
where characters are read and written to areas in memory.
fstream
where characters are read and written to external files.
stdiostream
where characters are read and written to external files using the C standard I/O
library.
bsamstream
where a bsambuf object is used for performing formatted file I/O.
stdiostream objects should be used in programs that use the C standard I/O package as
well as C++, to avoid interference between the two forms of I/O; on some
implementations, fstreams provide better performance than stdiostreams when
interaction with C I/O is not an issue.
Other types of streams can be defined by derivation from the base classes iostream and
streambuf. See Stream class hierarchy for more information on the relationships between
these classes.
cin is a standard source of input. It reads input from the same place that stdin
would have.
cout is a stream to which program output can be written. It writes output to the same
place stdout would have.
cerr is a stream to which program error output can be written. It writes output to the
same place stderr would have.
clog is another error stream that can be more highly buffered than cerr. It also
writes output to the same place stderr would have.
To use these streams, you must include the header file iostream.h.
Four sets of stream classes are provided in the standard streams library: fstream,
strstream, stdiostream, and bsamstream. Corresponding to each of these stream classes
is a buffer class: filebuf, strstreambuf, stdiobuf, and bsambuf, implementing a form of
buffering appropriate to each stream. Note that the stream classes are not derived from
the buffering classes; rather, a stream object has an associated buffering object of the
appropriate kind (for instance, an fstream object has an associated filebuf ), which can be
accessed directly if necessary using the rdbuf() member function. Relationship between
Stream Classes shows the inheritance relationships between the various classes.
The get() and getline() functions behave similarly, except that getline() extracts the
final delimiter and get() does not.
read()
extracts a fixed number of characters from a stream. read() is intended for use with
binary data, whereas get() and getline() are usually more appropriate with text data.
putback()
allows a character extracted from a stream to be "pushed back," so that it will be
extracted again the next time a character is required from the stream.
write()
inserts a number of characters into a stream. The null character is treated as any
other character and therefore this function is suitable for inserting binary data.
flush()
immediately transmits any buffered characters. For a stream associated with a
terminal file, this causes any buffered characters to be transmitted to the terminal.
For a nonterminal file, calling flush() may not cause any characters to be
immediately written, depending on the characteristics of the file.
tie()
ties one stream to another stream, so that whenever the first file's buffer is full or
needs to be refilled, the tied file's buffer is flushed. The cin stream is automatically
tied to cout, which means that cout 's buffer is flushed before characters are
extracted from cin. If, as is usually the case, cin and cout are both terminal files,
this assures that you see any buffered output messages before having to enter a
response. Similarly, the cerr stream is tied to cout , so that if an error message is
generated to cerr, any buffered output characters are written first.
Creating streams
Streams are normally created by declaring them or by use of the new operator. Creating
an fstream or stdiostream entails opening the external file that is to be the source or sink
of characters. Creating a strstream entails specifying the area of storage that will serve
as the source or sink of characters. For fstream, a stream constructor can be used to
create a stream associated with a particular file, similar to the way the fopen function is
used in C.
For instance, the following declaration creates an output fstream object, dict, associated
with the CMS file named DICT DATA:
Opening files
When you create an fstream (or a stdiostream), you must usually provide a filename and
an open mode. The open mode specifies the way in which the file is to be accessed. For
an ifstream, the default open mode is ios::in, specifying input only; for an ofstream, the
default open mode is ios::out, specifying output only.
Defining a strstream
When you create a strstream, you must usually provide an area of memory and a length.
Insertions to the stream store into the area of memory; extractions return successive
characters from the area. When the array is full, no more characters can be inserted;
when all characters have been extracted, the ios::eof flag is set for the stream. For an
istrstream, the length argument to the constructor is optional; if you omit it, the end of
the storage area is determined by scanning for an end-of-string delimiter (' \0 ').
For a strstream that permits output, you can create a dynamic stream by using a
constructor with no arguments. In this case, memory is allocated dynamically to hold
inserted characters. When all characters have been inserted, you can use the member
function str() to "freeze" the stream. This prevents further insertions into the stream and
returns the address of the area where previously inserted characters have been stored.
Formatting
When a program inserts or extracts values other than single characters, such as integers
or floating-point data, a number of different formatting options are available.
130 Avinash Kumar Singh
For instance, some applications might want to have an inserted unsigned int transmitted
in decimal, while for other applications hexadecimal might be more appropriate. A similar
issue is whether white space should be skipped on input before storing or interpreting
characters from a stream. The member function setf() is provided to allow program
control of such options.
For instance, the following expression sets the default for the stream cout to
hexadecimal, so that integral values written to cout will ordinarily be transmitted in
hexadecimal:
cout.setf(ios:hex, ios:basefield)
width()
sets the number of characters to display.
fill()
defines the fill character when there are fewer characters to insert than the width.
precision()
sets the number of significant digits to write for floating-point values.
Manipulators Again
Use of the setf(), width(), and similar member functions is very convenient if the same
specifications are used for a large number of inserted items. If the formatting frequently
changes, it is more convenient to use a manipulator. A manipulator is an object that can
be an operand to the << or >> operator, but which modifies the state of the stream, rather
than actually inserting or extracting any data.
For instance, the manipulators hex and dec can be used to request hexadecimal or
decimal printing of integral values. Thus, the following sequence can be used to write out
the value of i in decimal and the value of x[i] in hexadecimal:
For convenience, the '!' operator and the conversion to void* operator allow concise
testing of a stream for any error. These operators allow you to use statements such as
the following, which writes the results of the function nextline to the standard output
stream until an error occurs:
while(cout)
cout << nextline();
Because an insertion or extraction always produces its stream argument as its result,
this can be further abbreviated to the following statement:
This form makes it more obvious that the loop might not terminate at all. Note that
attempting to extract from a stream from which no more characters can be taken is
considered a failure. Thus, you can use a loop such as the following to extract and
process items from a stream until the stream is exhausted:
C++ has one feature common to a data base that it can store the data permanently for
future use. Data can be stored in files and files can be edited and can be opened a
program for reading it.
The files specific functions are not provided in iostream.h they are provided in a separate
header file fstream.h stands for files stream.
Streams revisit
Using C++ you can access a device through an intermediate medium. The intermediate
medium is called as stream. The device that you access is known as file.
Don't mistake the term file as a normal computer file. A normal file (a text file or a word
document) is referred to as disk file. In this case file takes a broader meaning. It includes
disk files, tape drives, the terminal, printers and so on. C++ is designed to work with
these devices. To work with them you have streams. You can access devices using
streams.
The point is: Each device is different. Each one is unique. The C++ file system transforms
each device into a stream. All streams will behave similarly though they provide access
to different devices (or files). Hence streams are mostly device-independent. The function
used to write to a disk file can be used to write to a printer as well. Hence all streams are
similar but files are not.
Each stream is associated with a specific file by using the open operation. Once you
open a file (not just disk file-could be a printer) information can be exchanged between
the file and your c++ program. This exchange is done through streams.
Opening and Closing a File
We think you'll find this interesting. You'll learn how to access disk files in the following
sections. First of all you have to make use of another header file: fstream.h This header
file has a number of classes already defined within it. Some of them are ofstream,
ifstream, fstream etc...
To access a file you have to have a stream. Hence first we declare a stream. The stream
will be an object of one of the classes in fstream.
Once you've created a stream, you can use the open ( ) function to associate it to a disk
file. The open ( ) function is a member of all the three classes. It can be used as follows:
133 Avinash Kumar Singh
out.open("text.txt") ; // Opens a file called text.txt for output. The file is opened using
the stream out which was created earlier.
Note: When you say that a file is opened for output, it actually means that now you can
write data to the file. When a file is opened for input (using ifstream), the data in the file
can be displayed on the screen.
Suppose there was a file text.txt already. When using output stream (ofstream), the
stream will create a new file text.txt. Whatever content was there in the original text.txt
gets deleted and you can write new data to text.txt.
The 3 classes (ofstream, ifstream, fstream) have a constructor function that makes it
easier to open a file. Example:
ofstream out("text.txt"); // This creates an object out for output and opens the file
text.txt.
This statement makes use of the constructor in the ofstream class. Ifstream and fstream
also have the constructor.
Closing a File
The member function for closing is close ( ). Since you do all I/O through the stream, you
have to close the stream as follows:
Actually you can link this to the object and classes concept. Out is an object and close is
a member function of the ofstream class. Hence by saying out.close( ); you're actually
calling the member function.
When you open a file using ofstream (which means output), you can write data to the file.
You could say it's an input to the file. Hence open for output means actually for input.
When a file is opened for reading, you will make use of the ifstream as follows:
When you want to read a file, it means that the file is already present in your directory.
Hence if you try to open a file (that isn't present) for reading, what happens?
Hence you can check whether an error has resulted in the open operation as follows:
if ( ! instream )
{
cout<< "The file cannot be opened";
}
if ( ! instream ) stands for: if not instream (that means if instream not open) then do what
is said in the body of the if statement.
Writing to a Text File
Reading and Writing to a file is very easy. First we shall take a look at writing:
<< is known as the insertion operator. It is used for output along with the keyword cout
(console out). Hence cout<<"Hi"; would actually write the word Hi on your screen
(output). In the above program, instead of writing on the screen, we want to write to a
particular file. Perhaps now you understand why we create an output stream for actually
writing to a file. So we create a stream out for output and open the file test.txt.
out<<"First "<<1<<endl;
does the following things: it writes the word First and the number 1 to the stream out.
Remember that out has been linked to the file test.txt. Hence First and 1 are written to the
file. Similarly Second and 2 are written on the next line of the file because of the endl
keyword. Finally we close the stream.
Reading a Text File
Before learning this section We hope you know the Difference between void main ( ) and
int main ( ). If you haven't seen the section then please do so and come back here.
The program to read the text file that you created in the previous section is as follows:
First of all, the file has been opened. String is a character array. The compiler reads the
file (test.txt which has been opened). It reads the first 15 characters. The first word in the
file is First. After this it encounters a blank space. Hence the string is terminated (for
details on why it doesn't continue reading check the section: Beware of character
arrays). Hence the word First is stored in variable array string. Next comes a number.
This gets stored in the variable num that you have declared.
It just displays on the screen what it read from the file. After this remember that the
compiler has reached the end of the first line of the file. It automatically moves to the
second line of the file. Hence when we repeat the statement:
in>>string>>num ;
the compiler will read the next line of the file. The process just repeats and Second and 2
are now stored in string and num. Finally, the compiler prints the second line of the file
on the screen.
136 Avinash Kumar Singh
Modes of Opening Files
When you open a file (for writing or reading), there are 6 modes that you can use to
specify how you want the file to be opened. The modes are:
Modes of Opening Files Description
ios::app causes all the output (or whatever you write) to be appended to
the end of the file. This mode can be used only for files opened for output.
ios::ate Go to the end of the opened file.
ios::binary causes the file to be opened in binary mode (we'll deal with
binary later on).
ios::in specifies that the file is capable of input only.
ios::out specifies that the file is capable of output.
ios::trunc causes contents of pre-existing file by same name to be
destroyed.
ofstream out;
out.open("test"); // This means test is opened in normal mode.
By default this is the same as out.open("test", ios::out); // opened specifically for output
A template can also be considered as a kind of macro. When an object of a specific type
is defined for actual use, the template definition for that class is substituted with the
required data type. Since template is defined with a parameter that would be replaced by
a specified data type at the time of actual use of the class or function, the templates are
sometimes called parameterized classes or function.
Function templates
We can also define function templates that could be used to create a family of functions
with different arguments types. The general format template is:
Suppose you want to write a function that returns the minimum of two numbers.
Ordinarily this function would be written for a particular data types.
For example:
The following program shows how to write the min() functions a template, so that it will
work with any standard type. we have invoked this function from main() for different data
types.
template
T min( T a, T b)
{
return( a> b ) ? : b ;
138 Avinash Kumar Singh
}
void main()
{
int i = 10, j = 20 ;
cout << endl << min(i, j)
char ch = 'A' , dh = 'Z';
10
-6.28
A
1.1
Example:
Example:
Class Templates
The concept of templates can be extended even to classes. Class templates are usually
used for data storage (container) classes. Stacks and linked lists, which we encountered
in previous chapters, are examples of container classes. However, the examples of these
classes that we presented could store data of type float in a stack we would be required
to define a completely new class. It follows that for every new data type that we wish to
store , a new stack class would have to be created. Won't it be nice if we are able to write
a single class specification that would work for variables of all types, instead of a single
basic type. Enter class templates. Here is a program with class template in action.
It is simple process to create a class using a template with anonymous type. The general
format is:
Exception handling
Check out whether your C++ compiler supports this feature (the older C++ compilers will
not support exception handling).
This feature is used for dealing with certain specific situations (these situations are not
supposed to occur and if you don’t provide some way of dealing with them then your
program could simply freeze when the conditions really occur). To implement exception
handling, C++ provides us with three keywords:
Try
Catch
Throw
How does it work? First you try (execute) the coding and in case some special situation
is encountered, then the program will throw an exception. The exception that is thrown,
will be caught by catch.
int main( )
try
{
cout<<"\nEnter a number : ";
cin>>a;
cout<<"\nEnter the denominator : ";
cin>>b;
if (b= =0)
{
throw 0;
}
cout<<"\nResult of division : "<<a/b;
}
catch(int i)
{
cout<<"\nError - You entered : "<<i;
}
return 0;
}
Suppose the second number you enter is zero, the following will result:
Enter a number: 5
Enter the denominator: 0
Error- You entered: 0
The coding should be easy to comprehend. You should note that once the program
throws something, it will not execute what follows it within the try block. It will go directly
to the catch block and execute the underlying statements. The catch block that you write
should immediately follow after the try block. Even if you add one display statement
between the try and catch blocks it will lead to errors. Can We have more than one
catch??? Yes but each catch should catch a different exception (meaning that the
argument types for each one should be different). You can write one catch block to catch
integers, one to catch strings etc. Suppose you want to catch everything that is thrown,
there is a simple way to do it. Just use:
catch(…)
{
//body of the catch
}
144 Avinash Kumar Singh
The 3 consecutive dots imply that this catch block will catch anything that is thrown.
Uncaught Exceptions
This is an interesting topic. What will happen if We throw a string but We have
programmed for catching only integers? This is what is called as an uncaught exception
and if you try it out, your compiler will display the message:
set_terminate(your-function);
For using this, you would need to make use of the <exception> header file.
void myterminate( )
{
cout<<"\nMy Terminate Function";
abort( );
}
int main( )
float a,b;
try
{
set_terminate(myterminate);
cout<<"\nEnter a number : ";
cin>>a;
cout<<"\nEnter the denominator : ";
cin>>b;
if (b= =0)
{
throw "zero";
}
cout<<"\nResult of division : "<<a/b;
}
145 Avinash Kumar Singh
catch(int i)
{
cout<<"\nError - You entered : "<<i;
}
return 0;
}
The output would be (when you enter the second number as 0):
Enter a number: 5
Enter the denominator: 0
My Terminate Function
The <exception> also defines some standard exceptions that are thrown. For example:
bad_alloc- thrown if some problem is encountered using ‘new’
bad_exception- thrown when exception doesn't match any catch