232
Introduction to OOP UNIT I Object Oriented Programming Page 1 Object Oriented Programming thr C++

C++ infosystems 1

Embed Size (px)

Citation preview

Page 1: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 1

Object Oriented Programming thr C++

Page 2: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 2

Object Oriented Programming UNIT 1 Introduction to OOP 1

UNIT 2 Operator, Overloading and Inheritance 73 UNIT 3 Templates, Pointers and Graphics 135

UNIT 4 Files and Streams, Polymorphism and Virtual Function 193

Page 3: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 3

BLOCK INTRODUCTION

The chief problem with computer program is complexity. Large programs

are probably the most complicated entities created by humans. Because

of this complexity, programs are prone to error and software errors can be

expensive. Object-Oriented programming offers a new and powerful way

to cope with this complexity. Its goal is clearer, more reliable, more easily

maintained programs.

OOP involves concepts that are new to programmers of traditional language

such as Pascal, Basic and C. These ideas such as date hiding, encapsulation

and polymorphism, lie at the heart of OOP. This block explains OOP with the

C++ programming language.

This book has been split into 4 units.

After completing Unit I, you will under the basic concept of programming in OOP

style. You will also learn to use classes to combine data and function and to

create objects. In this unit, concept of constructors, distracters and overloaded

constructors are also explained.

Unit 2 explains the techniques for designing reusable and extendable classes

and objects. It also explains the basic techniques of redefining functions and

operators, called overloading.

Unit 3 explains how to create templates and use it in programs. You will know

what is a pointer and how to allocate memory dynamically using new operator.

You will learn to design graphics pictures using OOP technique.

Page 4: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 4

In Unit 4, you will understand the concepts of files and streams, and how to

create binary and ASCII files. You will also learn to define virtual function, friend

functions and Polymorphism.

Page 5: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 5

UNIT 1 INTRODUCTION TO OOP Structure

1.0 Introduction 1.1 Objectives 1.2 What is C++ ? 1.3 Characteristics of Object Oriented Languages

1.3.1 Objects 1.3.2 Classes 1.3.3 Inheritance 1.3.4 Reusability 1.3.5 Creating New Data Types 1.3.6 Polymorphism and Overloading 1.3.7 Overloading Functions

1.4 Starting, Compiling and Executing C++ Programs 1.4.1 Invoking C++ 1.4.2 Naming your Program 1.4.3 Compiling 1.4.4 Running the Program

1.5 Inline Functions 1.6 Storage types in C++ 1.7 C++ Programming Basic

1.7.1 First C++ Program 1.7.2 White Space 1.7.3 Escape Sequence 1.7.4 Input with cin 1.7.5 Output with cout 1.7.6 Example to develop an Employee class 1.7.7 Manipulators 1.7.8 Example 1.7.1 rewritten to illustrate setw

1.8 Programming Style 1.8.1 Character Set

Page 6: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 6

1.8.2 Keywords and Identifiers 1.8.3 Variables 1.8.4 Constants 1.8.5 Data Types 1.8.6 Declarations 1.8.7 Arrays 1.8.8 Enumerated Data Types 1.8.9 Structures

1.9 C++ Operators 1.9.1 Assignment Operators 1.9.2 Arithmetic operators 1.9.3 Type conversion 1.9.4 Casting 1.9.5 Relational Operators 1.9.6 Logical Operators 1.9.7 Increment/Decrement Operators 1.9.8 Conditional Operators 1.9.9 Precedence Of Operators

1.10 Decision Statements 1.10.1 One Way Branching 1.10.2 Two Way Branching 1.10.3 Nested if then else 1.10.4 Multi Way Branching 1.10.5 Switch Case

1.11 Programming Control Statements 1.11.1 Goto statement 1.11.2 For loop 1.11.3 Continue Statement 1.11.4 Break Statement 1.11.5 While loop 1.11.6 Do loop

1.12 Objects and Classes 1.12.1 Private and Public 1.12.2 Protected 1.12.3 Example to Illustrate Class Concept

Page 7: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 7

1.12.4 Class - Declaration and Usage

1.13 Constructors 1.13.1 Example to Illustrate Constructors

1.14 Destructors 1.15 Overloaded Constructors 1.16 Example to illustrate Overloading Constructors and Destructors 1.17 Formatting Decimal Number

1.17.1 To Illustrate Formatting Decimal Numbers 1.18 Static Class Data

1.18.1 To Illustrate Static Class Data and Static Functions 1.19 Exercise 1.20 Summary

1.0 INTRODUCTION

PROCEDURAL LANGUAGES AND ITS DIFFICULTIES

A program in a procedural language is a list of instructions. The programmer

creates the list of instructions, and the computer carries them out. When

programs become larger, a single list of instructions becomes difficult to

understand. Hence 'functions' were adopted for better understanding of the

programs. Functions are called as subroutines, subprograms or procedures in

different languages. Dividing a program into functions and modules is called

structured programming or 'Procedure Oriented Programs' (POP).

As programs grow larger and more complex, the schedule slips, more

programmers are added, complexity increases, costs sky-rocket, the schedule

slips further.

In POP, the emphasis is on doing things, and a subdivision of programs into

functions continues this emphasis. Data is the reason for the program, not the

function that acts on the data. Yet data is given a secondary status, while

Page 8: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 8

functions primary status. The global variables in such languages are accessible

to all functions. There are chances that it may accidentally be corrupted.

Another problem is that, since many functions access the same data, the way

the data is stored becomes critical. The arrangement of the data cannot be

changed without modifying all the functions that access it. In a large project, it

may also be difficult to find all the functions to modify it correctly.

There are other problems with traditional languages based on POP. One is the

difficulty of creating new data types (extensibility) as traditional languages are

not usually extensible.

THE OBJECT - ORIENTED APPROACH

The fundamental idea behind Object Oriented languages is to combine into a

single unit both data and the functions that operate on the data. Such a unit is

called an ‘object’.

Object Oriented Programming (OOP) is a software development technique that

has gained popularity because of potential gains in programmer productivity over

conventional software development methodologies.

An object is a self contained unit or module of data and code. All data and

procedures related to the object are defined within it. So, procedures (called

'methods' in OOP terminology and 'member functions' in C++) are tied to the

data. A 'message' identifying a method to execute is passed to the object.

The advantages of OOP fall into two broad categories increased programming

productivity and decreased maintenance costs. Well chosen classes and objects

may be re-used in other applications. Re-used code would have already been

tested, so it should need little testing when used in a new program. Objects help

partition complex problems into simpler ones that are easier to implement.

Page 9: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 9

Application testing is generally shorter because objects are small and contain

independent code and local data segments that are verified with less effort than

in conventional programs. When a bug does occur, a particular object is usually

implicated. This makes isolating and correcting the bug easier.

Data hiding, a feature with all OO languages makes it possible to change the

data structure of an object without affecting the operation of the program.

1.1 OBJECTIVES

At the end of this unit, you will be able to :

♦ Understand the characteristics of Object Oriented Language.

♦ How to start C++, write a simple program, compile and execute C++

programs.

♦ Different storage types in C++, escape sequence.

♦ Taking input using cin and displaying output using cout.

♦ The basic data types in C++.

♦ The different operators.

♦ The decision statements.

♦ The looping statements.

♦ How to write the constructors and destructors and invoke them.

1.2 WHAT IS C++ ?

C++ is a superset of C, that is, C with extensions to support OOP. It was

developed by Bjarne Stroustrup of AT&T Bell Labs in 1986 as a means of

making complex programs easier to write and maintain. The name C++ is a

combination of C and the increment operator '++' indicating an incremental

development of C.

Page 10: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 10

C++ Version 1.2 was the initial AT&T release. The next AT&T version was 2.1. It

is available both in translator form and compiler form. C++ version 2.1 adds

several features to C++. Some of the primary new features include :

♦ Multiple Inheritance

♦ Explicit support for abstract classes

♦ Pointers to class members

♦ Additional operator overloading

These are significant enhancements over previous C++ standards.

1.3 CHARACTERISTICS OF OBJECT ORIENTED LANGUAGES

The fundamental idea behind Object Oriented languages is to combine into a

single unit both data and the functions that operate on the data. Such a unit is

called an ‘object’.

1.3.1 Object

In an OO language problem you no longer divide the problem into functions, but

into objects. To understand object correctly, you need to understand Class first.

1.3.2 Class

Class describes the data and its behavior or functionality. Objects are said to be

'members' of classes.

This is the very much like what you see in nature, where Animal is a class and

Cat is an object of this class. The basic features of Animals, that is - 2 eyes, 2

ears, legs, etc. are common to all Animals. Thus Cat which is an object of class

Animal inherits these properties. The Cat can then be assigned individual

characteristics like color, their nature etc.

Just as int, a predefined data - type in C++ can have many variables declared of

its type, e.g. int a, count, total, amount, declares 4 variables, all of integer

type. Similarly, you can define many objects of the same class.

Page 11: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 11

A class is a data type defined by the user describing the data it represents and

the functions to be used to manipulate the data. It serves as a plan / template.

Defining the class does not create any objects. Thus the class Animal can have

objects - Cat, Dog, Lion, Tiger, Crocodile, Frog etc.

Classes and their objects can be defined according to the problem at hand.

Thus in the banking system, ACCOUNT is a class describing number, date

opened, name of customer etc. SB, AC, FD, RD are objects of this class, each

having additional properties - like RD would include number of installments and

installment amount.

WHAT CONSTITUTES AN OBJECT ?

♦ Physical Objects: e.g. Electrical components in a circuit design problem.

♦ Elements of the computer - user environment: Windows, Menus, Mouse,

Keyboard, Graphics - objects (line, circle, etc.)

♦ Programming Constructs: Stacks, Customized Arrays, Linked lists, Binary

trees.

♦ User - defined data types : Angles, Complex numbers, Points on the plane.

♦ Collections of data: Dictionary, an inventory.

♦ Components in Computer games: Positions in a board game (chess,

checkers), Opponents and friends in adventure games.

1.3.3 Inheritance

Classes are divided into subclasses. Like the Animal, described above, can be

divided into subclasses like Land animal, Water Animal etc. Animal in turn may

be a subclass of the Fauna class. Thus Land Animal inherits all or some

properties of the higher classes and can add properties of its own.

The principle here is that each subclass shares common characteristics with the

class from which it has been derived. In addition to the characteristics shared

Page 12: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 12

with other members of the class, each subclass has its own particular

characteristics.

In C++, the original class that is, the main class is called the 'Base class'. Other

classes can be defined that share the 'Base class' characteristics and add their

own as well. These are called 'Derived Classes'. The derived class can be a

base class of another class.

1.3.4 Reusability

The concept of inheritance provides an important extension to the idea of

reusability. Once a class has been written, created and debugged, it can be

distributed to other programmers for use in their own programs. This is called

reusability.

A programmer can take an existing class, and without modifying it, add

additional features and capabilities to it. This is done by deriving a new class

from the existing one. The new class will inherit the capabilities of the old one,

but is free to add new features of its own.

1.3.5 Creating New Data Types

New data types can be created by using the 'class' definition.

1.3.6 Polymorphism And Overloading

Polymorphism allows you to create multiple definitions for operators and

functions and at run-time depending on the context a particular definition will be

used.

An existing operator like + used with integer values (built-in data type)

constitutes addition. When a new data type is defined, the same + operator can

be made to operate in a particular manner on the new data type. This capability

of an operator to operate on many data types or in a new manner, constitutes

"operator overloading". Overloading is a kind of polymorphism. For e.g. '+' is

Page 13: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 13

normally used to add numbers. This operator can be overloaded to add strings

(concatenation) or sets (union) and so on. Similarly functions also can be

overloaded as shown in the next section. The terms 'Overloading' and

'Polymorphism' are used interchangeably.

1.3.7 Overloading Functions

An overloaded function appears to perform different activities depending on the

kind of data to be sent to it. A function can be overloaded depending on the

factors like the number of arguments, the kind of arguments etc. The compiler

can also distinguish between overloaded functions with the same number of

arguments, provided their data types are different.

1.4 STARTING, COMPILING AND EXECUTING C++ PROGRAMS

1.4.1 Invoking Turbo C++

To start Turbo C++, type TC at the DOS prompt.

F>TC

Page 14: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 14

Figure 1 ( C++ Editor screen)

You get the following screen. It will mostly be blank, with the menu bar at the top

and the status line on the bottom.

1.4.2 Naming Your Program

Select New from the FILE menu. An edit window will appear with the filename

NONAME00.CPP. You need to change this name. Select Save As from the FILE

menu to do this. In the text field in the resulting dialog box, enter the name of

your program, e.g., FIRST.CPP. The new name will appear at the top of the Edit

window. Notice that you have changed the filename from NONAME00.CPP to

FIRST.CPP.

1.4.3 Compiling And Executing The Program

Page 15: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 15

The program that you type into the Edit window constitutes the source file. It is

an ASCII file with .CPP extension. This source file is not an executable program.

First, you must compile the source file into an object file. The object file, has an

extension .OBJ contains machine-language instructions that can be executed by

the computer. However, these instructions are not complete. A second step,

called linking is required. The linking step is necessary because an executable

program almost always consists of more than one object file. Linking combines

the object files into a single executable program.

Compiling: To compile the source file, select Compile from Compile menu. A

window called compiling will appear. An entry called Line Compiled will change

as compiling progresses. When the process if finished, the window will display

Success: Press Any Key. The entries for Warnings and errors will be 0.

Compilation creates an object file which has the extension .OBJ. If there is an

error, go back to the program correct the errors and compile it again.

Linking: To link your object file, Select Link from the COMPILE menu. The OBJ

file will be combined with the one or more library files. The result is an

executable file with extension .EXE.

Page 16: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 16

1.4.4 Running the Program

To run the .EXE file, select Run from RUN menu (or press CTRL + F9). The

result will be displayed in the screen and control returns to the editing screen. To

see the result, select User Screen from WINDOW menu or ALT + F5.

1.5 INLINE FUNCTIONS

Functions, as you know is a module of code, which occurs repeatedly in the

program. Thus, it saves memory space, as the code is not repeatedly compiled.

When the compiler sees a function call, it normally generates a jump to the

function. At the end of the function, it generates another jump to the statement

after the call. But this takes time as the compiler has to save the variables and

return address on the stack, process the function, unstack all the variables etc.

But, when the function is very small say two or three lines and is not repeated

often or the time taken to transfer control to the function and back is more than

the time for execution of the function body, the functions become a bottleneck to

the program. In such cases, you use an 'inline’ function. This function is written

like a normal function in a source file but is compiled into inline code instead of

into a function.

When you use 'inline functions' there are some restrictions. The compiler must

have seen the function definition before it gets to the first function call so that it

can insert the statements. If there is only 'main function' in the program then the

'inline function' definition must be written before main function. In such cases the

function declaration is unnecessary and can be eliminated.

It is to be noted that 'inline' keyword is actually just a request to the compiler.

Sometimes the compiler will ignore the request and compile the function as a

normal function. These functions will be discussed in detail, later in this book.

Page 17: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 17

1.6 STORAGE TYPES

C++ provides all the storage types available in C as shown in the table given

below:

TABLE 1.1 : STORAGE TYPES IN C++ Storage Type Automatic

(Local) Static Automatic (Static)

External (Global)

Visibility Function Function Function Lifetime Function Program Program Initialized Value Not initialized 0 0 Storage Stack Segment Data Segment Data Segment Purpose Variables used by

a single function. Same as auto, but must retain value when the function terminates.

Variables used by several functions.

1.7 C++ PROGRAMMING BASICS

The execution of every program begins from 'main()'. This function may or may

not take parameters, it always returns void. It indicates the logical beginning of

the program. Other commands and constructs are enclosed in braces as the

body of main().

# include <iostream.h> is not a program statement. It is called a 'preprocessor

directive'. A preprocessor directive is a instruction to the compiler itself. A part of

the compiler called the 'preprocessor' deals with these directives before it begins

the real compilation process.

Just as in C, appropriate headers are included, using the # include command,

depending on the functions to be used in the program. This command is placed

at the beginning of the program, i.e. before any functions are executed.

'iostream.h' is the header file to be included to perform any input - output

operations in C++. Keyword 'cout' is used for output. The following program

displays a message on the screen.

Page 18: C++ infosystems 1

Introduction to OOP UNIT I

Object Oriented Programming Page 18

1.7.1 First C++ Program

Consider the following program - myclass1.cpp. This class contains one integer

num and describes the functionality of this data member. All functionality of this

data member is described through methods (member functions) within the class.

myclass allows the data to be entered (getdata()) and displayed (dispdata()).

Any other functionality required will have to be included within the class

declaration.

// myclass1.cpp # include <iostream.h> class myclass1 { private : int num; public : void getdata() // to enter the value { cout << endl << "Enter an integer:"; cin >> num; } void dispdata() //to display the value { cout <"Num=" << num<<endl; } }; void main () { myclass1 a1, b1; a1.getdata(); b1.getdata(); a1.dispdata(); b1.dispdata(); } // end of program.

NOTE

The class command starts the declaration of a new class private and public are two types of accesses. Data members are usually private while member functions are public. cout is the keyword used to display information. cin is the keyword to enter data. indicates the end of the class command a1 and b1 are objects of class myclass1.

Page 19: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 14

A class as you have defined earlier is a combination of data and its functionality,

that is the data is encapsulated in the class. In the class defined above, you

have one data member - num. It is defined as private. Private access implies

that the member can be accessed only by other members of the class. You see

the value of num being manipulated only within the class, that is, by the member

functions getdata() and dispdata() only.

Member functions - getdata() and dispdata() are declared as public. Public

access implies that the member can be accessed directly by other members of

the class (within the class) and by objects of the class (in main) using the dot (•)

operator e.g. - a1•getdata(); in the above program.

cout is the keyword used to display information on the standard output (the

VDU). It uses the overloaded left-shift operator (<<). Any number of items can

be concatenated using the << operator. endl is used to insert a newline

character in the output. In its place the escape sequence \n can be used as :

cout << '\n' << "Enter an integer :"; or cout << "\nEnter an integer :";

All other escape sequences available in C are available in C++ as shown in the

table given below.

cin is the keyword to enter data from standard input (the keyboard). It uses the

overloaded right-shift (>>) operator

1.7.2 White Space

White Space is defined as spaces, carriage returns, linefeeds, tabs, vertical tabs,

and formfeeds. These are ignored by the compiler. But there are some

exceptions :

♦ The string constant cannot be split.

♦ # include <header file> must be written on a single line.

Page 20: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 15

♦ // symbols are used in C++ to indicate comments. This is valid only till the

end of that line. No white space should be used between the slashes.

1.7.3 Escape Sequences

Escape sequences are denoted by a backslash (\) and a character. E.g. : \t is an

Escape sequence because the \ causes an 'escape' from the normal way the

characters are interpreted. In the example given above, it is interpreted as the

'tab' character and not as character 't'.

Escape Sequences can be used in both character and string constants.

TABLE 1.2 : COMMON ESCAPE SEQUENCES

Escape Sequence Character \a Bell(Beep) \b Backspace \f Formfeed \n New Line \r Return (Enter key) \t Tab \\ Backslash \’ Single Quotation Mark \” Double Quotation Mark

\xadd Hexadecimal Representation

1.7.4 Input With Cin

cin is used for input in C++. It is defined as an object in the header file

iostream.h. The >> is the 'extraction' or 'get from' operator.

1.7.5 Output using cout

cout is used for output in C++. It is defined as an object in the header file

iostream.h. The << is the 'insertion' or 'put to' operator.

1.7.6 Example To Develop An Employee Class .

Page 21: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 16

/* class employee stores employee information. You use calc() function to

return average salary. */

# include <iostream.h>

# include <string.h> // to use strings class employee { private : int emp_no; char name[20]; int basic; public : void getdata() // to enter the data { cout << "Enter employee no :"; cin >> emp_no; cin.get(); cout << "Enter name :"; cin.getline(name,'\n'); cout << "Enter Salary :"; cin >> basic; } void dispdata() // to display the value { cout << "Employee no :" << emp_no; cout << "Name :" << name; cout << "Salary :" << basic; } float calc(employee x) { float temp; temp = (float(basic) + x.basic)/2; // int basic is casted to float type return temp; } }; void main () { employee a1, b1; a1.getdata(); b1.getdata(); float average = a1.calc(b1); /* object a1, invokes function calc(), b1 is passed as the parameter */ cout << endl << "Average salary :"<< average;

parameter received

basic of object that calls calc() function -i.e. instance variable

Page 22: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 17

} // end of program. 1.7.7 Manipulators

The 'endl' manipulator has the same effect as the '\n' escape sequence.

The 'setw' manipulator (setw(n), causes the number (or string) that follows in the

stream to be printed within a field 'n' characters wide, where 'n' is the argument

to setw(n). The setw(n), is defined in iomanip.h.

The number or string variable or constant that follows the setw manipulator is

printed right justified within the width specified as argument. These manipulators

are normally used to format the output obtained from the program.

1.7.8 Example 1.7.1 Rewritten to illustrate manipulator - setw()

# include <iostream.h> # include <iomanip.h> class myclass1 { private : int num; public : void getdata() // to enter the value { cout << endl << "Enter an integer :"; cin >> num; } void dispdata() // to display the value { cout << setw(10) << "Number =" << setw(10) << num<<endl; } }; void main () { myclass1 a1; a1.getdata(); a1.dispdata();

Page 23: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 18

} // end of program. OUTPUT

with setw manipulator without setw manipulator

Enter an integer : 12 Enter an integer : 12

Number= 12 Number = 12

1.8 PROGRAMMING STYLE

1.8.1 Character Set

Obviously the set of legal characters of ‘C++’ can contribute a legal word in

‘C++’. The set of such characters is refered as Character set of ‘C++’. The

characters are grouped as follows:

♦ Letters

♦ Digits

♦ Special Characters

♦ White Spaces

Alphabets :A ... Z a ... z

Numerals : 0 ... 9

Special Characters

, comma & ampersand . period ^ caret ; semicolon * asterisk : colon - minus sign ? question mark + plus sign ‘ apostrophe < less than “ quotation mark > greater than ! exclamation ( left parenthesis | vertical slash = equal to / slash ) right parenthesis

Page 24: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 19

\ back slash [ left square bracket ~ tilde ] right square bracket _ under score { left bracket $ dollar sign } right bracket % percent sign # number sign

White Spaces

Blank spaces , Horizontal tab ,Carriage return , New line.

1.8.2 Keywords And Identifiers

The set of ‘C++’ words that can be formed from these characters can be

classified as keywords and identifiers. The keywords are a part of ‘C++’, which

have a predefined meaning and cannot be changed. All keywords must be

written in lower-case. From the character set you could observe that both upper

and lower cases are allowed in ‘C++’.

‘C++’ Keywords auto do for return typedef break double goto start union case else if sizeof unsigned char enum int static void continue extern long struct while default float register switch Identifiers are user defined names, that refer to variables and function names.

1.8.3 Variables

Variables enable the programmers to assign and manipulate data using symbolic

names. Strings and numeric values can be stored in the memory of the

computer for subsequent recall. Whenever the memory is used for this purpose

the programmer must assign a unique name to each area in memory. In brief, a

variable is a data name that may be used to store a data value, for easy retrieval.

For example, the legal identifier names in ‘C++’ are,

Page 25: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 20

totsalary

Counter1

Stdname

The naming conventions of variables has already been discussed. The

maximum length of the variable is machine dependent. Usually 32 is the

maximum number of characters permissible in a variable name.

Page 26: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 21

1.8.4 Constants

Constant is one that has a fixed value throughout the program. The constant

can be viewed as a read only memory variable. In a program, the constant

identifier should not be changed by any manifestation of the program

statements.

Constants are broadly classified into numeric constant and character constant.

Pictorially the taxonomy of the constants are given here.

Constant

* Numeric Constant

# Integer Constant

# Real Constant

* Character Constant

# Character Constant

# String Constant

An integer constant is a sequence of digits that may or may not be prefixed with

a minus sign. Some examples are,

14 -32 0 576321 Note that ‘C++’ does not support unary plus hence, +14 is not a valid integer.

A real constant can be represented in 2 forms,

1. Decimal form 2. Exponent form

Eg. 12.75 Eg. 1275E-2

-14E-2 A character constant is a single character enclosed within a pair of single quotes.

Examples are,

Page 27: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 22

’7’, ’K’, ’,’

Note that the character constant ‘7’ is not the same as the integer 7.

A string constant is a group of characters enclosed in double quotes. These

characters may be letters, numbers, or any special characters.

Examples are, ”welcome”

”2000”

1.8.5 Data Types

Data type is defining an attribute to the variable. It defines the set of legal that

the variable can store. ‘C++’ is rich data types. The basic data types are int,

char, and float.

Integer

The data type ‘int’ are whole numbers with a range of values supported by a

particular machine. For instance, in a 16 bit word length machine, the integer

values lie between –32768 to 32767.

‘C++’ facilitates some control over the integer data type by providing sub data

types namely short int, int, long int.

Short int represents fairly small integer values and requires half the amount of

storage as a normal int uses.

Similarly a long int represents fairly higher integer values and requires generally

twice the number of bits as a normal int uses. Nevertheless these are highly

machine dependent.

Another option in integer data type is declaring it as unsigned. This unsigned

integer uses all bits for the magnitude of the number and are always positive. For

instance, in a 16 bit machine the range of unsigned integer is 0 to 65,535. Thus

long and unsigned are intended for increasing the range of values.

Page 28: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 23

Floating point type

Floating point numbers are numbers that have a decimal point. This data type in

‘C++’, is an attribute for real numbers. The corresponding declaration is,

float a;

which instructs the compiler that the variable ‘a’ belongs to the data type real. If

you want to initialise the variable, then

float a;

a = 14.752;

This can also be achieved through a single statement.

float a = 14.752;

The keyword float defines the floating point number. When more accuracy is

required, another subdata type, double under the float data type can be used.

Obviously this double data type uses twice the storage as that of the float data

type. To display a double value the format specifier %f is used to obtain the

standard floating point notation and %e for scientific or exponential notation.

Character data type

The char keyword defines a character data type. Thus the declaration for this is

char x;

x = a;

The variable x is of type character and is initialised to the character ‘a’. The same

effect could be achieved as,

char x = ’a’;

Table 1.3

Integer type Floating point type Character type

Page 29: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 24

Int short int long int Unsigned int

Float Double Long double

Char

Page 30: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 25

Table 1.4 Type specifier

Description Format specifier

storage (machine dependent)

Int

Short int Long int unsigned int

float

double long double char

integer data type

floating point representation Scientific notation(exponent form) Otherwise (decimal form)

for better precision of floating point scientific notation otherwise character representation

%d or %i

%hd %ld %u

%e %f

%e %f %le or %lf %c

2 Bytes 4 Bytes

8Bytes 10 Bytes 1Byte

Format specifications of 'C++' data types

1.8.6 Declarations

The modern programming languages clearly separate the data and the control

statements. All the data is declared first. This makes the program more readable

and also provides the information to the compilers to allocate memory spaces.

The data and control are well separated by making the former to precede

textually, in the name of declarations. Such declarations follow the syntax,

type identifier v1,v2,...............vn;

Example: int n1, n2, n3;

Of course, initialisation of the data is also possible.

float x, y, z; int x =72;

Data declaration does two significant tasks for each variable. They are:

♦ tells the compiler what the variable name is.

♦ specifies what type of data the variable will hold.

Page 31: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 26

TABLE 1.5 : BASIC C++ VARIABLE TYPES

Keyword Numerical Range

Low High

Digits of precision

Bytes of memory

Char -128 127 n/a 1

Int -32,768 32,767 n/a 2

Float 3.4x10-38 3.4x1038 7 4

Double 1.7x10-308 1.1x10308 15 8

long double 3.4x104932 1.1x104932 19 10

Unsigned char 0 255 n/a 1

Unsigned int 0 65,535 n/a 2

Unsigned long 0 4,294,967,295 n/a 4 1.8.7 ARRAYS

Apart from the broad spectrum of data types, C++ supports arrays. This data

type is useful when a group of elements are to be represented by a common

name.

An array is a group of elements that share a common name, that are

differentiated from one another by their positions within the array. An array is a

collection of homogeneous data.

For example, 21, 20, 14, 25 and 13 are marks in 5 subjects of a student. To

store these five marks, five variables would be required – test1, test2, test3,

test4 and test5. For such a representation, arrays are useful. This can be

represented as test[5]. The ability of using a single name to represent a

collection of items and to refer to an item by specifying the location number

enables the programmer to develop concise and efficient programs.

Declaring arrays

An array must be declared, since it is basically a variable. The declaration is :

Page 32: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 27

Syntax: type variable-name [size];

Example: int marks[5]; This example describes an array of 5 integer elements and the elements are

numbered starting with 0. Each element is accessed by the array name followed

by its position in square brackets. This position is known as the subscript, thus

each array statement is a subscripted variable. Therefore, you would have:

mark[0], mark[1], mark[2], mark[3] and mark[4].

If the array is accessed beyond its limit, C++ does not report it as an error.

Having declared mark[5], accessing mark[5] is not a syntax error. The program

does not terminate abnormally, though it is a logical error as the last legal

element is mark[4].

ONE DIMENSIONAL ARRAY

A list of data items can be given one variable name using one subscript and such

a variable is called a one dimensional array.

Example:

# include <iostream.h> void main() { int num[10]; int i;

cout<<"Enter 10 numbers "<<endl; for (i=0;i<9;i++) cin>>num[i];

for (i=0;i<9;i++) cout<<num[i]<<endl; }

Page 33: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 28

The array storage starts from 0 and hence the loop termination is i < 10. The

second loop is to display the10 integers.

Page 34: C++ infosystems 1

Introduction to OOP Unit 1

C++ Page 29

INITIALIZATION OF ARRAYS

An array can be initialized along with its declaration.

SYNTAX: static type array-name[size]={val1,val2..};

static int count[3]={0,0,0 };

will declare the variable count as an array of size 3 and will assign zero to each

element. Note that this declares a static variable. The size parameter may be

omitted. In such cases, the compiler allocates enough spaces for all initialized

elements.

static int count[]={0,0,0};

TWO DIMENSIONAL ARRAY

The following table could be considered as a two dimensional array:

56 3 62 2 75 1

This array stores the score and the

rank of 3 students.

Then score[0][0] represents the marks of the first student and score[0][1] the

rank of the first student. C++ allows us to define such a table of items by defining

a two dimensional array. As with the single dimensional array, each element of

the array is indexed from zero to its maximum size minus one, the first index

stands for row and the second index for column. C++ uses the row major

arrangement to access the elements of the array – first number represents the

row and the second number represents the column.

Declaration

int score [3][2]

will declare a table of 3 rows and 2 columns.

Initialization

Similar to the one dimensional arrays, two dimensional arrays can also be

initialized.

Page 35: C++ infosystems 1

Introduction to OOP unit1

static int table[2][3]={0,0,0,1,1,1};

initializes the elements of the first row to zero and the second row to one. Note

that initialization is done row by row. For better degree of readability, you can

also write the same initialization in the matrix form, as :

static int table[2][3]={{0,0,0},{1,1,1}};

The inner braces are optional, but it is good practice to use them, as they

improve the readability.

Example:

# include <iostream.h> void main() { int num[3][3]; int i,j;

cout<<"Enter the numbers into the array"<<endl; for (i=0;i<3;i++) { for (j=0;j<3;j++) cin>>num[i][j]; }

for (i=0;i<3;i++) { for (j=0;j<3;j++) cout<<num[i][j]<<"\t"; cout<<endl; } } MULTIDIMENTIONAL ARRAYS

C++ permits arrays of more than two dimensions. The maximum number of

dimensions depends on the compiler.

Page 36: C++ infosystems 1

Introduction to OOP unit1

SYNTAX : type array-name[s1][s2][s3]…[sm];

1.8.8 ENUMERATED DATA TYPES

This is used when you know in advance the finite number of values a variable

can take in a program. E.g. The days of the week can only take values from

Sunday to Saturday.

An 'enum' specifier defines the set of all names that will be permissible values of

the type. These values are called 'members' of the data variable. 'Enumerated'

means that all values are listed.

These data types are treated internally as integers. The first member gets

value 0, the second 1, and so on. Changes can be done by assigning it in the

declaration. The values can be set by initializing the first value.

In example 1.3 below, Sunday is initialized the value 1. Thus Monday gets the

value 2 and so on. If the difference between the first and second value is more

than 1, the values must be specified explicitly while declaring the data type.

E.g. Sun = 10, Mon = 20, and so on.

Example:

# include <iostream.h> enum days_of_week {Sun = 1,Mon,Tue,Wed,Thu,Fri,Sat}; void main() { days_of_week day1,day2; day1 = Mon; day2 = Thu;

int diff = day2 - day1;

cout << "Days between = " << diff <<endl; if (day1 < day2) cout << "day1 comes before day2 \n"; }

1.8.9 Structure

Page 37: C++ infosystems 1

Introduction to OOP unit1

A ‘structure’ is a data type, which is used to define a heterogeneous set of data

types or a set of data items belonging to different data types.

CONSTRUCTION OF STRUCTURES

A structure construction creates a format or a template that may be used to

declare structure variables.

SYNTAX :

struct tag-name { data-type member1;

data-type member2;

...;

...;

};

The keyword struct declares a structure to hold the template. Each variable

declared in the template is called a field or member of the structure. Each

member is a data item that can belong to any data type. Each structure has a

name, called tag-name. Also note that a structure does not declare any

variables, it describes a format or template.

e.g:

struct std_info

{ char name[20];

int roll_no;

float marks; } ;

Here, std_info is the tag name, which declares a format that can store a name,

roll_no and marks. The structure variables are declared after describing the

structure given above as –

struct std_info std1, std2, std3;

or, while describing the structure, as :

Page 38: C++ infosystems 1

Introduction to OOP unit1

struct std_info { char name[20];

int roll_no;

float marks;

} std1, std2, std3;

or struct { char name[20];

int roll_no;

float marks;

} std1, std2, std3; Here tag name is not used.

Each of the variables std1, std2 and std3 has the format described in the

template. i.e., Name, roll_no. and marks.

Note:

♦ The template is terminated with a semicolon.

♦ The tag-name can be used to declare structure variables. A structure

variable can be initialized during declaration. However, it must be static (like

an array).

♦ Structure members cannot be initialized inside the template.

static struct std_info { char name[20];

int roll_no;

float marks;

} std1 = {”mahe”, 1000, 90.00};

ACCESSING STRUCTURE MEMBERS

The members of a structure are accessed using the dot operators. Eg.

Std.roll_no.

INITIALISING STRUCTURE MEMBERS

Members of a structure can be accessed using the period (.) operator.

e.g : std1.roll_no = 108;

Page 39: C++ infosystems 1

Introduction to OOP unit1

Thus, 108 is stored in roll_no, a member of std1. std1 has been declared as a

variable of structure std_info. std_info is a structure of three members - name,

roll_no, marks. All I/O operations can be carried out with structure members.

e.g : cin>>std1.marks; cout<<"student 1 scored :”<<std1.marks<<endl);

The structure variable can be initialized by specifying the values of each member

within curly braces (the values are separated by commas) and assigning this to

the variable.

SYNTAX : variable = {value1, value2, ...};

e.g. : std1 = { ”smith”,105, 91};

Here Smith is assigned to std1.name, 105 to std1.roll_no and 91 to std1.marks.

ARRAYS OF STRUCTURE

When a number of variables have to be assigned the same structure, an array

may be used instead of using number of variables, that is, the variable being

assigned the structure template, could be an array.

e.g. : struct student std[50];

defines an array called std, that contains 50 elements. Each element is of the

structure described as student.

ARRAYS WITHIN STRUCTURES

Any member of a structure can be an array. In the above examples two integer

variable mark1 and mark2 have been described to store marks in two subjects.

This could be redefined as an array of two elements,

struct student { char name[20], grade;

int rollno; int mark[2];

} ; To access the members :

std.name

std.grade

Page 40: C++ infosystems 1

Introduction to OOP unit1

std.rollno

std.mark[0]

std.mark[1]

STRUCTURE INSIDE STRUCTURES

A structure may be defined inside a structure. Nesting of structure to any depth

is allowed in C++. e.g :

struct student

{ int rollno;

struct

{ char firstname[10], lastname[20], middlename[10];

} name;

} std;

The structure student defines a template containing rollno and the structure

name. name defines a template containing firstname, lastname and

middlename. Hence, rollno would be referred to as std.rollno and firstname as

std.name.firstname.

1.9 C++ OPERATORS

'C++' supports a rich set of operators. An operator can be defined as just a

symbol that tells the compiler to perform certain mathematical or logical

manipulations.

Taxonomy of operators

♦ Assignment operators

♦ Arithmetic operators

♦ Relational operators

♦ Logical operators

♦ Increment/decrement operators

♦ Conditional operators

♦ Bitwise operators.

Page 41: C++ infosystems 1

Introduction to OOP unit1

Expressions

The following are the rules regarding expressions:

♦ A signed or unsigned variable name or constant is an expression.

♦ An expression connected by an arithmetic operator to an unsigned variable

name or an unsigned constant is an expression.

♦ An expression enclosed in parenthesis is an expression

♦ Two expressions connected by an arithmetic operator is an expression

♦ Two arithmetic operators should not occur in succession in an expression.

1.9.1 Assignment Operators

Values need to be assigned to variables. The '=' operator is used for

assignment.

int a = 5;

The syntax of an assignment is,

Variable-name = expression;

For example,

sum = a + b;

Assigns the total of contents of a and b to a variable named, sum. The variable

sum appears to the left of the equal sign, which is called the assignment

operator. On the left of this operator only a single variable can occur,

expressions and constants are strictly not allowed.

The assignment statement is called a dynamic statement because the value of

the expression on the right of assigned operator is assigned during the time of

execution, not during the time of execution, not during compilation.

The declaration of a variable and its initial assignment is possible, as a single

line. This takes the form,

[qualifer] Type identifier = constant

or

Page 42: C++ infosystems 1

Introduction to OOP unit1

[qualifer] Type identifier = predefined variable

example : auto into no = 100;

'C++' also permits the initialization of more than one variable in one statement

using multiple assignment operation.

Similarly, compound assignment operators can be used

Eg: +=, -=, /=, *= , %=

a = a + 5 or a += 5

b = b - 10 or b -= 10

c = c/2 or c /= 2

prod = prod * no or prod *= no

year = year % 4 or year %= 4

1.9.2 Arithmetic Operators

The arithmetic operators are given below.

Operator Meaning + Addition - Subtraction * Multiplication / Division % Modulus These operators can operate on any built-in data types such as, int, char, float.

But for modulus operator, operand must not be float. Note that in 'C++' a char

data type is promoted to int data type. Integer division truncates any fractional

part. You have already written many programs using this. This modulus operator

is discussed later.

Hierarchy of Arithmetic operators

When an arithmetic expression involves two or more arithmetic operators, the

hierarchy or the order of precedence of the operator is important. In 'C++',

Page 43: C++ infosystems 1

Introduction to OOP unit1

division and multiplication is done before addition and subtraction. This is known

as the hierarchy of operators or rule of precedence.

Multiplication and division have the same precedence, so do addition and

subtraction. Operators of the same precedence if appearing in one expression,

then the order in which they appear in one expression, the order in which they

are evaluated depends on their association. But using parentheses this

precedence can be overridden. That is, (a+b)/c will make the computer to

evaluate addition first and then division. But whatever is within the parenthesis

will be evaluated in the order of precedence.

Modulus Operator

The modulus operator is represented by the % (percent symbol). This returns the

remainder of the division, hence 11 mod 2 is represented in 'C++' as, 11%2 and

the result is 1, the remainder of the division. 10 % 5 is 0 as there is no remainder

after this division.

Symbolic Constant

When a numeric value or a constant is to be used in the program, then, it can be

given a symbolic definition or preprocessor directives which means, before

compilation every occurrence of the symbolic-name in the program is substituted

by the value-of-constant as given in the syntax.

SYNTAX: #define symbolic-name value-of-constant

This name is usually written in upper case to distinguish it from an ordinary

variable.

Mixed Mode

Having known the basic two types int and float, the next logical question is

whether mixing of these two types is allowed. That is, an arithmetic expression

containing an operand of type int and another of type float. This is allowed. The

integer value is automatically converted to type float for the calculation. Such

automatic conversions are known as implicit conversion.

Page 44: C++ infosystems 1

Introduction to OOP unit1

1.9.3 Type Conversions

When two operands of different types are encountered in the same expression,

the lower type variable is converted to the type of the higher type variable. These

conversions take place invisible to the user.

TABLE 1.6 : HIERARCHY OF DATA TYPES

Long double (highest order) Double Float Long Int Char (lowest order)

1.9.4 Casting

This term applies to data conversions by the programmer as opposed to the

automatic data conversions described above.

e.g. : int marks_eng, marks_kan;

float avg = (float(marks_eng) + marks_kan)/2;

In the above example, variable marks_eng is cast to float. When an arithmetic

expression is on the right hand side of the assignment, value returned is the

same type as the operands.

In this instance, both operands are of int type. Casting one to a higher type, will

cause :

♦ return type to be of the higher type (float, in this instance.)

♦ all operands to be implicitly cast to the higher type (in this instance,

marks_kan is implicitly casted to float.)

1.9.5 Relational Operators

The relational operators are symbols that are used to test the relationship

between variables or between a variable and a constant. For example,

(salary == 4000)

E.g.: Int is converted to float, double is converted to long double.

Page 45: C++ infosystems 1

Introduction to OOP unit1

(a > b)

Here, == is the operator used to test quality. A table of such relational operators

are listed below.

TABLE 1.7 RELATIONAL OPERATORS

Operator Meaning == > < != >= <=

equal to greater than less than not equal to greater than or equal to less than or equal to

Notice that some of the relational operators consist of two characters. There

should not be any space between those two characters.

1.9.6 Logical Operators

Logical operators are symbols that are used to combine expressions containing

relational operators. This circumstances will arise when you want to perform a

statement block on a combined condition, like x > 7 and x < 14. Then you code

this using an AND operator. The AND operator is represented as &&.

Example:

((x > 7) && (x < 14))

(salary >=4000 && salary <=5000)

The other logical operators are tabulated below:

TABLE 1.8 LOGICAL OPERATORS

Operation Operator AND

OR NOT

&& || !

1.9.7 Increment/Decrement Operator

Page 46: C++ infosystems 1

Introduction to OOP unit1

Apart from + and – ‘C++’ provides two very useful operators. They are ++ and --

defined as increment and decrement respectively. The ++ operator adds 1 to the

operand and -- operators decrements 1 from the operand.

Both are unary operators.

These operators can be used in two ways:

♦ pre-operator (before the variable) and

♦ post-operator (after the variable)

SYNTAX : ++ variable; --variable; (Pre-operator)

Variable++; variable--; (Post operator)

++variable is equivalent to

variable = variable + 1; or variable += 1;

--variable is equivalent to

variable = variable –1; or variable-=1;

A prefix operator first adds 1 to the operand and then the result is assigned to

the variable on left. In contrast, a postfix operator first assigns the value to the

variable on the left and then increments the operand.

Example : int i = 5; a = i++; a = ++I; a will be 5 a will be 6 i will be 6 i will be 6

1.9.8 Conditional Operator

This is a compressed version of the if - else statement. The syntax of this

statement is : c = (a > b) ? a : b;

Where : a and b are operands,

?: is the conditional operator,

> is the relational operator.

If the condition is true then value a is assigned to c otherwise b is assigned to c.

Page 47: C++ infosystems 1

Introduction to OOP unit1

1.9.9 Precedence Of Operators

In an expression, operators with higher precedence are evaluated before those

of lower precedence. Operators on the same row have equal precedence and

are evaluated left to right.

TABLE 1.9 PRECEDENCE SUMMARY

Operator Type Operators Precedence Parentheses ( ) Highest Precedence Unary ! , ++ , -- , - Arithmetic Multiplicative Additive

* , / , % + , -

Relational Inequality Equality

< , > , <= , >= == , !=

Logical And Or

&& ||

Conditional ?: Assignment = , += , -= , *= , /= , %= Lowest Precedence

1.10 DECISION STATEMENTS

You have seen that C++ programs are a collection of functions each having a

declaration part and a computational part which are executed sequentially, that is

statement by statement.

In practice, it becomes necessary to make some changes in the order of

execution and you need the in-built decision making mechanism. This is

accomplished by a set of control constructs. In accordance with the decision,

control will be transferred to another part of the computational structure, inside

the function. This decision may be,

1. One way branching.

2. Two way branching.

Boolean variables in C++

There is no datatype called boolean variable in C++. A boolean variable is one

that could take either TRUE or FALSE and nothing else.

Page 48: C++ infosystems 1

Introduction to OOP unit1

For example there can be a test,

Say, if code==0 then declare pass, if not fail.

Now the condition is code being 0 or not. That is, this expression is true only if

the code is zero. If it is not zero, then the expression fails. Now C++ achieves

this effect of boolean variable as follows:

TRUE : if the expression evaluates to a non-zero value.

FALSE : if the expression evaluates to zero.

Decision making and branching

To override the sequential flow of execution, branching is a must. At the same

time arbitrary unconditional branches are not healthy for programming.

Branching must be done based on a test. Given below are the various constructs

that achieve this effect.

1.10.1 One way branching

One way branching means evaluating a condition and then branching. In

accordance with the test advocated, set of statements are executed. This type of

decision making technique takes the form:

If (test expression)

{ statement-block }

statement-n;

This syntax is for a simple if statement. That is, the decision is made based on a

condition,

Braces { and } are used to group declarations and statement together into a

compound statement. This set of compound statement together enclosed within

parenthesis is called a block.

If (condition)

{

Page 49: C++ infosystems 1

Introduction to OOP unit1

Block of statements

}

Statement-n;

Example:

If (code ==0) printf("student has passed");

or

if (code ==0)

printf("student has passed");

The statement block can be a single statement or a group of statements. If the

logical expression is true then the statement block is executed, otherwise the

statement block will be skipped and statement-n will be executed. When the

condition is TRUE, that is when the logical expression evaluates to true then

both the statement and the statement-n are executed. The test expression is

made up of relational and logical operators.

Page 50: C++ infosystems 1

Introduction to OOP unit1

Example:

If (salary == 4000) hra = salary *.1;

If ((x > 7) && (x < 14)) { statement-block } if (salary >=4000 && salary <=5000) { statement-block } Example:

# include <iostream.h> void main() { int n1,n2; cout <<"Enter 2 random numbers \t"; cin>>n1; cin>>n2; if (n1 == n2) cout <<"Numbers are equal "<<endl; }

1.10.2 Two way branching

Two way branching is used in situations, wherein you need to trace two mutually

exclusive sets of actions.

This is accomplished by if ..then ..else construct of C++, which takes the form:

If (test expression) { statement(s) for the condition being true } else {

Page 51: C++ infosystems 1

Introduction to OOP unit1

statement(s) for the condition being false } statement-n;

If the test expression is true then the block of statement, immediately following

the if statement is executed; otherwise the second block of statement is

executed. Note that, in either case, either the true-block of statements or the

false-block of the statement alone is executed and not both.

Example:

// Program to detect larger number # include <iostream.h> void main() { int n1,n2; cout <<"Enter 2 random numbers \t"; cin>>n1; cin>>n2; if (n1 == n2) cout <<"Numbers are equal "<<endl; } // end of program

It is important that the else clause and if clause match with each other.

1.10.3 Nested if-then-else

The else clause, like the if clause, may contain a compound statement. This is a

more flexible control construct. Further, a clause of if statement may itself

contain another if statement. This is known as nested if statement.

The following example illustrates the nested if construct.

Page 52: C++ infosystems 1

Introduction to OOP unit1

Example:

If (x == 3) { if (x > 5) cout << “the numbers lies between 3 and 5 << endl; } else cout << "the number does not lie between 3 and 5" <<endl; The alternate way is by using the logical operators (AND, OR) and providing a

concise code.

Observe that an AND (&&) operation can be replaced with an if statement nested

within an if clause. Similarly an OR (II) operation can be replaced with an if

statement nested within an else clause.

1.10.4 Multi-way branching

The multiway branching can be achieved by a nested if-then-else clause.

Thereby any number of mutually exclusive statement blocks can be

accommodated.

Example: if (marks > 80) grade = ’A’; else if (marks > 60) grade = ’B’; else if (marks > 50) grade = ’C’; else grade = ’F’; 1.10.5 Switch-case

The construct switch(), which is an extension of the if..else.. statement, is used

for efficient multiway branching. The switch statement tests the value of the

expression or variable, which is of type int or int compatible, against a list of case

Page 53: C++ infosystems 1

Introduction to OOP unit1

values and when a match is found, a block of statements associated with that

case is executed. The syntax is as below:

switch (expression) { case value-1: block-1; break;

case value-2: block-2; break; case value-3: block-3; break; default : default-block; break; } statement-n;

When the switch is executed, the value of the expression is successfully

compared against the values, value-1, value-2, etc. If a case is found where

values matches with the value of the expression, then the block of statements

that follows the case is executed. If there exists no match then the default block

is executed. The default is optional. The break statement at the end of each

block indicates the end of a particular block and the execution resumes at

statement-n. If a break is not included in the end of each block, then all the

blocks following the block executed will also be executed.

To illustrate the usage of the switch construct, consider the following piece of

code:

Page 54: C++ infosystems 1

Introduction to OOP unit1

Example:

/* To check if given character is a vowel */ #include <iostream.h> void main() { char x; cout << "\n enter any char : "; cin>>x; switch(x) { case 'A': case 'a': cout<<x<<" is a vowel "<<endl; break; case 'E': case 'e': cout<<x<<" is a vowel "<<endl; break; case 'I': case 'i': cout<<x<<" is a vowel "<<endl; break; case 'O': case 'o': cout<<x<<" is a vowel "<<endl; break; case 'U': case 'u': cout<<x<<" is a vowel "<<endl; break; default : cout<<x<<" is not a vowel"<<endl; } }

1.11 PROGRAMMING CONTROL STATEMENTS

STATEMENTS AND BLOCKS

The basic format of a program in most structured programming languages is:

data <- Declaration portion

action <- control portion All the computational part, that is the action and the data onto which the action is

performed are well separated in the modern programming languages for

Page 55: C++ infosystems 1

Introduction to OOP unit1

reliability reasons. The action part is going to be a collection of computational

structures. The primitive structure is statements. For example

X = 4; I = I + 1;

The ; operates as a statement terminator. It is not necessary that a line should

have an assignment. For example, there can also be a statement just having a

semicolon. Such a statement is called as empty (null) statement. A line need not

always map to a legal ‘C++’ statement.

That is, line can also have more than one statement. This is logical because of

the fact that semicolon acts as a statement terminator. For example,

i = i + 1; I = 5;

There can also be a multiple statement. Note that = operates as an assignment

operator. That is the variable at the left hand side is assigned after the evaluation

of the expression at the right hand side and the result is stored in that variable at

the left hand side and hence this operator is called as assignment operator.

There can also be a multiple assignment statement. e.g p = q = r = 0;

This statement in one stroke assigns zero to all the three memory variables. This

is basically an initialization of three variables.

Brackets { and } are used to group declarations and statements together into a

compound statement. This set of compound statements enclosed within

parenthesis is called a block.

if (condition) { Block of statements } statement; You have seen how to declare variables. It is also possible to declare variables

inside the block. The visibility of the variable is restricted to that block only.

Page 56: C++ infosystems 1

Introduction to OOP unit1

In other words that variable whose scope is localised to a block is called a local

variable.

Example : void main() { int temp=20, x; x = tem * 5; } The variables, temp and x, have been declared exclusively for this block and is

not accessible by a statement outside the block.

1.11.1 Goto Statement

Statements are executed as independent entities and they can be grouped as a

block. However, inside a block the execution is statement by statement. Then the

control is said to be sequential. This could be overridden by a goto construct. All

languages provide this feature. This takes the form

SYNTAX: goto <label>;

A label is any valid variable name and must be followed by a colon.

goto mahe; mahe:statement1:

mahe; statement1: goto mahe:

The label can be anywhere in the program either before or after the goto

statement. Note that such control transfer occurs unconditionally. It is obvious

that the goto breaks the normal sequential execution of the program.

This is basically a control jump, which could be either forward or backward.

Consider the following code,

Page 57: C++ infosystems 1

Introduction to OOP unit1

Example:

# include <iostream.h> void main() { char c; take : cout <<"Input the character (z to exit) :"; cin >> c; if (c=='z') cout << "You have typed the right character to exit"; else { cout<<endl<<"Entered character is "<<c<<endl; goto take; } } This program uses an unconditional transfer. Until the user enters z the control

will not come out of the loop.

1.11.2 For Loop

The looping computational structures can be achieved through many control

structures in ‘C++’. The for construct is one way of doing so. Loops can be

classified as entry controlled and exit controlled loops.

The for loop given below is an entry controlled loop.

SYNTAX:

for(initialization; test condition; modifier expression)

{ body of the loop }

The initialization part that controls the loop through a variable is called loop index

or control variable.

Initialization: The control variable is initialized first with a simple assignment

statement, c=0.

Page 58: C++ infosystems 1

Introduction to OOP unit1

Test condition: The value of the control variable is tested using this test

condition. For each iteration this is performed. This is a relational expression,

such as i <10 which could determine the exit from the loop. If this relational

expression is true then the loop is executed again, otherwise control exits.

Modifier expression: At the end of the loop the control variable is transferred

back to the for statement. The control variable is modified, and the update value

of the control variable is again tested. If the condition is satisfied, the loop

continues, if not control exits.

Example:

#include <iostream.h> //Program to print the first 100 natural numbers void main() { cout <<endl<< "The first 100 natural numbers are "<<endl; for (int i=1;i<=100;i++) cout <<i<<"\t"; cout<<endl; }

You could also write a program to display all the numbers from 100 to 1, using a

decrement (negative increment), as follows:

Example:

#include <iostream.h> //Program to print the numbers from 100 to 1 void main() { cout <<endl<< "The first 100 natural numbers are "<<endl; for (int i=100;i>0;i--) cout <<i<<"\t"; cout<<endl; }

Page 59: C++ infosystems 1

Introduction to OOP unit1

One of the interesting points of this loop is that it is concise. All the three

operators – the initialization, the iterative test and the increment are stated in the

for statement.

1.11.3 The Continue Statement

This statement is used to go to the top of the loop from anywhere within the loop

during its execution.

Example:

# include <iostream.h> void main() { long dividend,divisor; char ch;

do { cout << "Dividend :"; cin >> dividend; cout << "Divisor :"; cin >> divisor; if (divisor == 0) { cout << "Illegal Divisor \n"; continue; // Goto the top of the 'do' loop. } cout << "quotient" << dividend/divisor; cout << "Remainder"<< dividend % divisor; cout << "Repeat ? (y/n) :"; cin >> ch; } while (ch!='n'); } // end of main 1.11.4 The Break Statement

In contrast to continue, break terminates the loop. It is usually used with for,

do..while, while loops and in the switch statement.

Page 60: C++ infosystems 1

Introduction to OOP unit1

Nesting of the for loop

Nesting of the for loop is permissible in C++, i.e. a body of a for loop can also

have a for structure. To pictorially visualize this circumstance, look at the

following figure,

for (x=10;x>0;x--) x=10 y 1 //outer for loop begins 2 { 3 for (y=1;y<=5;y++) 4 { 5 …… x=9 y 1 2 } 3 …. 4 } // outer loop ends 5 In nested loops the inner loops are executed first and then the outer loops. The

nesting is permissible to any depth. For better degree of readability the loops are

to be indented properly.

Skipping a part of loop

It may be necessary to skip a part of the body of the loop. That is, when loop is

in execution, on certain condition the rest of the execution of the loop concerned

is to be ignored and the loop should continue for the next iteration.

The control statement called continue is used to achieve this. This function

causes the loop to be continued, with the next iteration after updating the control

variable, without executing the rest of the statements in the loop. The continue

statement can be used only inside a loop.

for (initialization; test condition; increment) { If (condition) continue; } Example:

Page 61: C++ infosystems 1

Introduction to OOP unit1

for (i=1; i<=5; i++) { if (i==3) continue; cout << i; } For the above example, only i=1, 2, 4, 5 will be printed. When i is equal to 3,

control is returned to the beginning of the loop.

Comma operator

When the execution of the loop depends on two variables or two conditions the

for statement can be set up with two variables separated by a comma.

for (i=0,,j=n;i<=n;i++,,j--)

Note that the comma is included along with the usual semicolons. This is called

the comma operator.

Example:

#include <iostream.h> //Program to print ascending and descending numbers void main() { int n; cout <<endl<< "Enter a number "<<endl; cin>>n; cout <<endl; for (int i=0,j=n;i<=n;i++,j--) cout <<i<<"\t"<<j<<endl; cout<<endl; } Decision making and looping

Page 62: C++ infosystems 1

Introduction to OOP unit1

You have seen the constructs for different types of decision making. Upon

testing or evaluating a conditional expression the decision to branch was made.

For example, in two way decision making, two distinct blocks of statements are

executed, depending upon the value returned by the test condition. Similarly,

instead of branching the control to either of these two blocks, you can also make

it to loop. Unlike the for loop, in this construct the number of times the block is

executed is not predetermined. Looping is based on a condition. The loop

termination is only by asserting the status, say true or false of the condition. The

while, do .. while construct allows this.

1.11.5 While loop

Looping on a condition can be achieved by the while construct of C++. This is

the simplest of all control structures.

SYNTAX:

while (test condition) { body of the loop }

♦ This is an entry restricted loop

♦ That is, only on the condition being true the body of the loop is executed. In

other words, if the condition returns 0, the body of the loop is not executed

even once.

♦ This process of repeated execution, called iteration, continues until the test

condition returns false.

♦ On exiting from the loop, the control is transferred to the first statement

outside the loop.

Example:

#include <iostream.h>

Page 63: C++ infosystems 1

Introduction to OOP unit1

//Program to print natural numbers 1.. 100 using while loop void main() { int n=1; cout <<endl<<"The numbers are ;"<<endl; while (n<=100) { cout <<n<<"\t"; n++; } cout<<endl; } 1.11.6 do Loop

An alternate to the while construct is the do control structure. This is also a

decision dependent looping. But the difference here is that the condition is

evaluated at the end, i.e. after executing the body of the loop once.

while basically was entry controlled. Therefore, the body of the loop may not be

executed even once. There are occasions in programming, wherein the

execution may have to be done at least once. This effect is achieved through the

do statement.

SYNTAX:

do { body of the loop } while (condition); On reaching the do statement, the control proceeds to execute the body of the

loop. When the while statement is reached, the condition is evaluated. If the

condition is true, control is transferred to the beginning of the do loop and the

program continues to execute the body of the loop. Otherwise control is

transferred out of the loop. This loop is an exit controlled loop because, the test

condition is evaluated at the bottom of the do while loop.

Page 64: C++ infosystems 1

Introduction to OOP unit1

Example:

# include <iostream.h> //Program to print natural numbers 1.. 100 using do .. while loop void main() { int n=1; cout <<endl<<"The numbers are ;"<<endl; do { cout <<n<<"\t"; n++; } while (n<=100); cout<<endl; } 1.12 OBJECTS AND CLASSES

A class is an abstract idea that can be represented with data structures and

functions. Functions associated with a class are called methods. An object is

said to be an instance of a class.

A class combines data and functions (procedures) into a single programming

unit. This is 'Encapsulation'. Data and procedures are tied together logically. The

parts that make up a class can be protected from the rest of the program to

varying degrees. The programmer has control over the protection of individual

entries in the class definition.

Page 65: C++ infosystems 1

Introduction to OOP unit1

SYNTAX of the CLASS specifier The class specifier starts with the keyword class, followed by class name. Like a structure, the body of the class is delimited by braces and terminated by a semicolon.

class try { private : int num; public : void setdata(d) { num = d; } };

1.12.1 Private And Public

A key feature of object - oriented programming is 'data - hiding' i.e., the data is

concealed within a class, so that it cannot be accessed mistakenly by functions

outside the class. 'private' and 'public' are two types of protection available within

a class.

Items marked with 'private' can only be accessed by methods defined as part of

the class. Data is most often defined as private. The private data 'num' is set to

a value 'd' by using the function setdata. Private members can be accessed by

members of the class.

Public items can be accessed from anywhere in the program without restrictions.

Class methods are usually public. As a general rule, data should not be declared

public. Public members can be accessed by members and objects of the

class.

1.12.2 Protected

This is another type of protection available within a class. Items declared as

protected are private within a class and are available for private access in the

derived class. The derived class concept is dealt with later in this book. The

protected access will be discussed again.

Page 66: C++ infosystems 1

Introduction to OOP unit1

Consider a class 'smallobj' which has 'somedata' as its private member and

'setdata' and 'showdata' as its member functions which are public. These

functions provide the only access to the data item from outside the class. The

class is usually defined before main. Instances of the class are created and

used within main.

1.12.3 Example To Illustrate Class Concept

# include <iostream.h> class smallobj { private : int somedata; public : void setdata(int d) { somedata = d; } void showdata() { cout << "\n Data is " << somedata; } }; void main() { smallobj s1, s2; s1.setdata(1066); s2.setdata(1776); s1.showdata(); s2.showdata(); } 1.12.4 Class - Declaration And Usage

♦ Declare the class using the syntax given earlier.

♦ Defining Objects : Example – 1.12.3 defines two objects s1 and s2 of class

smallobj. Specification of the class does not create objects. It only describes

how they will look when they are created. It is the definition that actually

creates objects that can be used by the program and sets aside space for it

in memory.

♦ Calling Member Functions The member functions must always be called by

an object of it's class.

Class smallobj with 1 data member and 2 methods, is declared.

Page 67: C++ infosystems 1

Introduction to OOP unit1

To use a member function the dot operator is used. The dot operator

connects the object name and the member function. The dot operator is

called the 'class member access operator'

SYNTAX is : objectname.functionname(arguments)

E.g.: s1.setdata(1066) in Example 1.12.3.

MESSAGES

Some object - oriented languages refer to calls to member functions as

'messages'. The term 'message' is not a part of the vocabulary of C++.

STRUCTURES AND CLASSES

The only formal difference between a class and structure is that in a class the

members are private by default, while in a structure they are public by default.

Structures can include functions but the commonly practiced way is to use the

structures for data structures and classes for member functions.

EXAMPLE: TO ILLUSTRATE CLASS V/S STRUCTURE

class try struct try { { int data1 ; void func(); public : private : void func(); int data1; } } In the class specification 'private' has been omitted as it is the default option. But

in structure 'public' has been omitted.

1.13 CONSTRUCTORS

Automatic Initialization is carried out using a special member function called the

'constructor'. It is a convenient way to initialize an object when it is first created

without the need to make a separate call to a member function. Thus, a

constructor is a member function that is executed automatically whenever an

object is created. Constructors may or may not take arguments, depending on

how the object is to be constructed. There is no return value from the

constructors.

Page 68: C++ infosystems 1

Introduction to OOP unit1

A constructor always has the same name as the class itself. Every class has an

implicit constructor which need not be defined. It is called automatically for the

object as it is created. Constructors being functions, can be overloaded.

1.13.1 Example To Illustrate Constructors

# include <iostream.h> class counter { private : unsigned int count; public : counter() { count = 0; } // constructor void inc_count () { count++; } int getcount() { return count; } }; void main() { counter c1,c2; // Here the constructor is activated twice , once for each object. : :program statements : }

1.14 DESTRUCTORS

This is activated when the object is destroyed automatically when the program

ends or when the program control passes to a statement outside the scope of

the object. A destructor has the same name as the class preceded by a tilde (~)

e.g. ~counter. Destructors also have no return value. They take no arguments.

The use of these functions is to free memory allocated for the object by the

constructor.

For e.g.: If an object is used as a local variable in a function, the destructor is

invoked when the compiler returns to the calling procedure.

1.15 OVERLOADED CONSTRUCTORS

Page 69: C++ infosystems 1

Introduction to OOP unit1

Objects need to be initialized differently, thus the constructors can be overloaded

in the same way as overloading functions described earlier. However, note that

when there are constructors with arguments in the class an implicit constructor

also has to be written.

1.16 EXAMPLE TO ILLUSTRATE OVERLOADING CONSTRUCTORS

AND DESTRUCTORS

// myclass1.cpp

# include <iostream.h> class myclass { private : int num; public : myclass() { num = 0; } // default constructor myclass(int n) { num = n; } // overloaded constructor ~myclass() { cout << "\nObject destroyed !"; } //default destructor

void getdata() // to enter the value { cout << endl << "Enter an integer :"; cin >> num; } void dispdata() // to display the value { cout << endl << "Num :" << num; } }; void main () { myclass a1; // invokes default constructor myclass b1 (5); // invokes overloaded constructor

a1.dispdata(); b1.dispdata(); // displays instantiated values a1.getdata(); b1.getdata(); // enter new values a1.dispdata(); b1.dispdata(); // displays new values

} // end of program.

Page 70: C++ infosystems 1

Introduction to OOP unit1

1.17 FORMATTING DECIMAL NUMBERS

Formatting decimal numbers require manipulators other than setw().

Manipulators like setiosflags(ios ::fixed) are employed. A group of one-bit flags in

a long int in the 'ios' class determines how formatting will be carried out. To set

the concerned flags, you use the manipulator 'setiosflags' with the name of the

flag as an argument. The name must be preceded by the class name 'ios' and

the scope resolution operator(::).

The 'fixed' flag prevents numbers from being printed in exponential format. The

'showpoint' flag specifies that there will always be a decimal point, even if the

number has no fractional part. To set the precision to two digits to the right of the

decimal place, you use the 'setprecision' manipulator with the number of digits as

an argument. Once all these manipulators have been sent to cout, you can send

the number itself which will be displayed in the required format.

Formats set using the manipulators setiosflags and setprecision remain set till

another command is issued or you exit the program.

1.17.1 Example To Illustrates Formatting Decimal Numbers

# include <iostream.h>

# include <iomanip.h>

/* This program counts the number of instances i.e., the number of objects of class try*/ void main() {

int no = 1111; float basic = 2500, hra = 250; char name [ ] = "Bill Gates"; cout << "Formatted number output " ; cout << endl << "No : " << no << endl << "Name : " << name; cout << endl << "Basic :" << setiosflags(ios ::fixed) << setiosflags(ios::showpoint) << setprecision(2) << setw(10) << basic; cout << endl << "HRA :" << setw(10) << hra; cout << endl << "Total :" << setw(10) << basic + hra;

} // end of program

Page 71: C++ infosystems 1

Introduction to OOP unit1

The output of this program is : No : 1111 Name : Bill Gates Basic : 2500.00 HRA : 250.00 Total : 2750.00 1.18 STATIC CLASS DATA

In the previous examples you saw that each object in a class had its own

separate data. Now if all the objects were to share one data, a slight change in

the class specification would be sufficient. The modification required would be to

give a keyword static for the data which is to be shared. If a data item in a class

is defined as static, then only one such item is created for the entire class, no

matter how many objects there are. A member variable defined as 'static' has

similar characteristics to a normal static variable. It is visible only within the class,

but its lifetime is the entire program.

Some compilers automatically initialize a static data item, while others do not.

Page 72: C++ infosystems 1

Introduction to OOP unit1

1.18.1 TO ILLUSTRATE STATIC CLASS DATA and STATIC

FUNCTION

/* This program counts the number of instances i.e. the number of objects of class try */ # include <iostream.h> class try { private :

int id;

static int tot; public :

try () { tot++; id=tot; } // incremented each time an object is created void print() { cout << " Id is :" << id << endl; } static void printcount() {cout << "\nNumber of instances are "<< tot<< endl; }

}; int try::tot = 0; // some compilers may require this initialization void main() { try f1; cout << endl<< "f1:"; f1.print(); try f2; cout << endl<< "f2:"; f2.print(); try f3; cout << endl<< "f3:"; f3.print(); try :: printcount(); } OUTPUT OF EXAMPLE 1.18.1

f1 : Id is : 1 f2 : Id is : 2 f3 : Id is : 3 Number of instances are 3

Page 73: C++ infosystems 1

Introduction to OOP unit1

Note If a static variable was not used, count for each object would be 1.

printcount is a static function and therefore can be called directly from

main without associating it to an object, try :: printcount();

1.19 EXERCISE

1. Write a program to sort an array of numbers.

2. Write a program to display the reverse of an input string.

3. Write a program to count the number of vowels in the input string and plot it

in the form of a horizontal histogram.

E.g. MAHE E.g. MANIPAL A # A ## E # E I I # O O U U

4. Write a program to display the alphabet set along with its ASCII values in a

neat format.

5. Construct a distance class. It consists of two data members - feet (int) and

inches (float). The class must take care of the following :

Objects of the class can be initialized (instantiated)

User can enter data for the object - (if inches exceed 12; increment feet by 1

and reduce inches by 12)

User can display the object

Display the message - "Object destroyed" when the program ends.

6. Create a class to store a string. Include member functions to input and output

the data member. Also include the constructors and the destructors.

7. Create a class called time that has separate int member for hours, minutes

and seconds. The class should contain member functions to initialise the int

values to 0 or any other values. A member function should display the time in

hr:mm:ss format. The final member function should add 2 objects of type

time passed as arguments.

Page 74: C++ infosystems 1

Introduction to OOP unit1

1.20 SUMMARY

Object Oriented Programming is a way of organizing programs. The emphasis is

on the way programs are designed, not on the individual operators. OOP

programs are organized around objects, which contains both data and functions

that act on that data. A class is a template for number of objects.

C++ is a superset of C. It adds to the C language the capability to implement

OOP. It also adds a variety of other features .

A major building block of C++ programs is the function. A function named main( )

is always the first one executed when a program is executed. A function is

composed of statement which tells the computer to do something. Each

statement ends with a semicolon. A statement may contain one or more

expressions, which are sequences of variables and operators that usually

evaluate to a specific value.

Output is most commonly handled in C++ with cout object and << insertion

operator, which together cause variables or constants to be sent to the standard

output device – usually the screen. Input is handled with cin and the extraction

operator >> which causes values to be received from the standard input device –

usually the keyboard.

The built – in data types in C++ are: Char, int and long, float, double, double

long. C++ employs the arithmetic operators +, -, *, / and %. The assignment

operators +=, -=, /*, *=, %=. The increment and decrement operators ++ and –

increase or decrease a variable by 1.

Page 75: C++ infosystems 1

Introduction to OOP unit1

Answers to EXERCISE 1.19

1. # include <iostream.h> void main() { int num[10],i,j,temp;

cout << "Enter 10 numbers"<<endl; for (i=0;i<10;i++) cin >> num[i];

for (i=0;i<9;i++) { for (j=i+1;j<10;j++) { if (num[i]>num[j]) { temp = num[i]; num[i] = num[j]; num[j] = temp; } } } cout << "Numbers in ascending order "<<endl;

for (i=0;i<10;i++) cout << num[i]<<"\t"; cout<<endl; } 2. // reverse a string # include <iostream.h> # include <string.h> void main() { char name[50]; cout<<"input a string"<<endl; cin.getline(name,'\n'); int n=strlen(name); for (int i=n-1;i>=0;i--) cout<<name[i]<<endl; } 3. # include<iostream.h>

Page 76: C++ infosystems 1

Introduction to OOP unit1

void main() { char s[80],row[5]; int a[]= {0,0,0,0,0}; int i,j;

row[0]='a'; row[1]='e'; row[2]='i'; row[3]='o'; row[4]='u';

cout<<"enter a string:"; cin.getline(s,'\n'); for (i=0;s[i]!='\0';i++) { switch(s[i]) { case 'A': case 'a': a[0]++; break; case 'E': case 'e': a[1]++; break; case 'I': case 'i': a[2]++; break; case 'O': case 'o': a[3]++; break; case 'U': case 'u': a[4]++; break; default : break; } } for (i=0;i<5;i++) { cout<<row[i]<<"\t"; for (j=1;j<=a[i];j++)

Page 77: C++ infosystems 1

Introduction to OOP unit1

cout<<"#"; cout<<endl; } } 4. //program to display the alphabet set # include<iostream.h> void main() { int c; for (c=65;c<=122;c++) { if (c>90 && c<97) continue; cout<<c<<"="<<(char)c<<"\t"; } }

5. #include<iostream.h> class distance { private : int feet; float inches; public : distance() {feet=0;inches=0.0;} distance(int f,float i){feet=f; inches=i;} void getdist() { cout<< "Enter the feet";cin>>feet; cout<< "enter the inches";cin>>inches; while(inches>=12) { feet++; inches-=12; } } void showdist() { cout<<feet<< "\'-"<< inches<< "\"";} ~distance() {cout<<"Object destroyed"<<endl;} };

Page 78: C++ infosystems 1

Introduction to OOP unit1

void main() { distance d1,d2(5,40.0); d2.showdist(); d1.getdist(); d1.showdist(); }

6. # include <iostream.h> # include <string.h> class string { private : char *str; public : string() {str= new char[1]; strcpy(str,"\0");} string(char *s) {str=new char[strlen(s)+1];strcpy(str,s);} void getdata() { cout <<"enter a string"; cin.getline(str,'\n'); } void dispdata() { cout <<"String entered is "<<str<<endl;} ~string() {delete str;cout<<"\n Destroy"; } }; void main() { string s1("welcome"),s2; s1.dispdata(); s2.getdata(); s2.dispdata(); } 7. #include <iostream.h> class time {private : int hrs,mins,secs; public : time() { hrs=0;mins=0;secs=0;} time(int h, int m, int s) { hrs=h; mins=m;

Page 79: C++ infosystems 1

Introduction to OOP unit1

secs=s;} void getdata() { cout<< "Enter hours";cin>>hrs; cout<< "Enter minutes";cin>>mins; cout<< "Enter seconds";cin>>secs; while(secs>=60) { secs-=60; mins++;} while(mins>59) { mins-=60; hrs++;} } void dispdata() { cout<<hrs<<":"<<mins<<":"<<secs<<endl; } void add_time(time t1,time t2) { secs=t1.secs+t2.secs; mins=t1.mins+t2.mins; hrs=t1.hrs+t2.hrs; if (secs>=60) { secs-=60; mins++;} if (mins>=60) {mins-=60; hrs++;} } }; void main() { time time1,time2,time3; time1.getdata(); time2.getdata(); time1.dispdata(); time2.dispdata(); time3.add_time(time1,time2); time3.dispdata(); }

Page 80: C++ infosystems 1

Introduction to OOP unit1

UNIT 2 OPERATOR OVERLOADING, INHERITANCE

Structure

2.0 Introduction 2.1 Objectives 2.2 Operator Overloading 2.3 Overloading Unary Operators

2.3.1 Nameless Temporary Objects 2.3.2 Limitation of Increment Operators

2.4 Overloading Binary Operator 2.4.1 Overloading Arithmetic Operators 2.4.2 Concatenating String's using '+' 2.4.3 Copy Constructor 2.4.4 Exercise to implement the String class

2.5 Multiple Overloading 2.5.1 Overloading Comparison Operators 2.5.2 Overloading Assignment Operators

2.6 Data Conversion 2.6.1 Conversions between Basic types 2.6.2 Conversions between Objects and Basic types 2.6.3 Conversions between Objects of different classes

2.7 Function Overloading 2.8 Exercise to store Employee information 2.9 Inheritance

2.9.1 Derived Class and Base Class 2.9.2 Derived Class Constructors 2.9.3 Overriding Member Functions 2.9.4 Private and Public Inheritance 2.9.5 Access Specifiers - When to use what? 2.9.6 Class Hierarchies 2.9.7 Abstract Base Class

2.10 Levels of Inheritance 2.11 Multiple Inheritance

2.11.1 Member functions in Multiple Inheritance

Page 81: C++ infosystems 1

Introduction to OOP unit1

2.11.2 Constructors in Multiple Inheritance 2.11.3 Ambiguity in Multiple Inheritance

2.12 Containership: Classes within classes 2.13 Inheritance and Program Development 2.14 Exercise 2.15 Summary

2.0 INTRODUCTION

Operator Overloading is one of the most exciting features of OOP. Operator Overloading gives you the opportunity to redefine the C++ language within a class. By using classes to create new kinds of variables, and operator overloading to create new definition for operator, you can extend C++ to be a new language of your own design. Another kind of operation, data type conversion, is closely connected with Operator Overloading in C++. C++ handles the conversion of simple types like int and float automatically, but conversions involving user-defined types require some work on the programmers part.

OOP uses a method called Inheritance to modify a class to set ones need. Modifying a class library does not require compilation. There is no modifying of any class from the library. Inheritance means deriving new classes from the base class from the existing class. The existing class is called as base class and the class, which is derived, is called the derived class. Deriving a new class from an existing one allows redefining a member function of the base class and also adding new members to the derived class.

2.1 OBJECTIVES

At the end of this unit you will be able to,

♦ Overload the unary and binary operators.

♦ Convert basic data type to user-defined data type and visa – versa.

♦ Overload functions

♦ Create new classes from existing classes.

2.2 OPERATOR OVERLOADING

C++ programs can overload existing operators with some other operations. If the operator is not used in the context as defined by the

Page 82: C++ infosystems 1

Introduction to OOP unit1

language, then the overloaded operator if defined will be executed. Overloaded operators are those that have been redefined within a C++ class using the keyword 'operator' followed by an operator symbol. All operators can be overloaded except . , .* , :: , ?= and preprocessor symbols #, ##. So, the term operator overloading refers to giving the primitive C++ operator additional functionality when they are applied to user-defined data types.

2.3 OVERLOADING UNARY OPERATORS

Unary operators as discussed earlier are +, -, ++ and --. The syntax of

overloading is:

return type operator unary operator (arguments) { function body }

Example 2.1: Overloading The Unary Operator ++

# include <iostream.h>

class counter

{

private : unsigned int count;

public : counter() {count = 0;}

int get_count () {return count;}

++ overloaded

};

void main()

{

counter c1,c2;

cout << "\nc1 = " << c1.get_count();

cout << "\tc2 = " << c2.get_count();

c1++; c2++; ++c2; // Using overloaded ++ operator. cout << "\nc1 = " << c1.get_count();

void operator ++ () { count++;}

Page 83: C++ infosystems 1

Introduction to OOP unit1

cout << "\tc2 = " << c2.get_count();

}

Output of Example 2.1

c1 = 0 c2 = 0

c1 = 1 c2 = 2

The operator is applied once to c1 and twice to c2. Both prefix and postfix

notation is used on c2.

The function declaration void operator ++ () tells the compiler to call this member

function whenever the ++ operator is encountered, provided the operand is of

type counter. Since member functions can always access the particular object

for which they have been called, this operator requires no arguments. So, if the

operand is a basic type like an int, the compiler will use its built-in routine to

increment it.

Notice that the return type of the operator is void. Therefore, it does not return

any value. Hence, it cannot be used in assignment statements as in c1 = c2++;

To rectify this, you have to specify the return type as the name of the object,

create a temporary object and return it. This is shown in Example 2.2.

In this program, operator overloading is done as follows:

1. member data count is incremented

2. a new item temp is created of counter type

3. the incremented value is assigned to this variable - temp

4. temp is returned.

Expressions like c1++ now return a value, so they can be used in other expressions such as c2 = c1++; and c2++.get_count();

Example 2.2: Illustrates Operator Return Values

# include <iostream.h>

class counter

{

Page 84: C++ infosystems 1

Introduction to OOP unit1

private : unsigned int count;

public : counter() { count = 0; }

counter(int x) { count = x; }

int get_count() {return count;}

counter operator ++ ()

{ count ++;

counter temp;

temp.count = count;

return temp;

}

};

void main()

{

counter c1,c2;

cout << "\nc1 = " << c1.get_count() << "\nc2 = " << c2.get_count();

c1++; c2 = c1++;

cout << "\nc1 = " << c1.get_count() << "\nc2 = " << c2++.get_count();

}

2.3.1 Nameless Temporary Objects

In Example 2.2, a temporary object of type counter was created for the exclusive purpose of providing a return value for the ++ operator. The next example shows another approach to the same problem without using a temporary object.

Example 2.3: Illustrates Nameless Temporary Objects

# include <iostream.h>

class counter

{

private : unsigned int count;

Page 85: C++ infosystems 1

Introduction to OOP unit1

public : counter () {count = 0;}

counter (int c) { count = c; }

int get_count() { return count; }

counter operator ++ ()

{

count++;

return (*this);

}

};

void main()

{

counter c1,c2;

cout << "\nc1 = " << c1.get_count() << "\nc2 = " << c2.get_count();

c1++; c2 = c1++;

cout << "\nc1 = " << c1.get_count() << "\nc2 = " << c2++.get_count();

}

this is a special pointer that points to the current object. It has been used here

to return the incremented value without creating a new object.

2.3.2 Limitation Of Increment Operators

When applied to basic data types prefix and postfix operators are two different operators. But when they are overloaded there is no distinction between prefix and postfix notation. The expression c2 = c1++ has exactly the same effect as c2 = ++c1; In both cases c1 is assigned to c2. If you need the basic data type implementation for the overloaded function, then it requires two overloaded operators, one for prefix and one for postfix.

operator ++ (); // prefix. operator ++ (int); // postfix.

Page 86: C++ infosystems 1

Introduction to OOP unit1

The second declaration uses a dummy int argument, which is set to 0 automatically by the postfix ++ operator. This extra argument allows the compiler to distinguish the two forms.

2.4 OVERLOADING BINARY OPERATORS

This is very similar to overloading unary operators. This section is divided into two parts: overloading arithmetic operators, overloading comparison operators.

2.4.1 Overloading Arithmetic Operators

The first example in this section illustrates overloading arithmetic operator '+' to add objects of class distance. The second example illustrates overloading '+' to add polar co-ordinates.

EXAMPLE 2.4 Illustrates Overloading '+' To Add Objects Of Class Distance

# include <iostream.h>

class distance

{ private : int feet;

float inches;

public : distance () { feet = 0; inches = 0.0; }

distance (int ft, float in) { feet = ft; inches = in; }

void getdist()

{ cout << "\nEnter feet : "; cin >> feet;

cout << "\nEnter inches : "; cin >> inches; }

void showdist()

{ cout << feet << "\'-" << inches << '\"'; }

distance operator + (distance); };

distance distance :: operator + (distance d2) {

int f = feet + d2.feet;

float i = inches + d2.inches;

while (i >= 12.0)

Page 87: C++ infosystems 1

Introduction to OOP unit1

{ i -= 12.0; f++; }

return distance (f,i);

/* temporary variable is not created, the overloaded constructor is called to

create distance(f, i) this is automatically returned. */ }

void main()

{

distance dist1; distance dist2(11,6.25);

dist1.getdist();

distance dist3 = dist1 + dist2;

distance dist4 = dist1 + dist2 + dist3;

cout << "\ndist1 = "; dist1.showdist();

cout << "\ndist2 = "; dist2.showdist();

cout << "\ndist3 = "; dist3.showdist();

cout << "\ndist4 = "; dist4.showdist();

}

In class 'distance' the declaration for the operator + () function looks like distance operator + (distance); the function returns a value of type 'distance' and takes one argument of type 'distance'.

When the compiler encounters an expression like distance dist3 = dist1 + dist2; and finding only distance argument types, it uses the member function operator + (). Note that though '+' operator needs two operators, only one is supplied to the function. The answer lies in the fact that the argument on the left of the operator (here, dist1) is the object of which the operator is a member function and the object on the right of the operator (dist2) is furnished as an argument to the operator.

In operator + () function, the left operand is accessed directly - since this is the object of which the function is a member - using feet and inches. The right operand is accessed as function's argument, as d2.feet and d2.inches. The operator returns a value, which can be assigned or used in other ways; in this case, it is assigned to dist3.

Page 88: C++ infosystems 1

Introduction to OOP unit1

Generalizing this, an overloaded operator always requires one less argument than its number of operands, since one operand is the object of which the operator is a member function. Hence unary operators require no arguments (See Example 2.1).

Adding Polar Coordinates By Overloading '+' Operator

The formula to convert from polar to rectangular co-ordinates are :

x = radius * cos(angle); y = radius * sin(angle);

To convert from rectangular to polar, you use :

angle = atan (y/x); radius = sqrt (x * x + y * y);

EXAMPLE 2.5 Illustrates Adding Polar Coordinates

# include <stdio.h>

# include <math.h>

class polar

{ private : double radius;

double angle;

double getx() { return radius * cos(angle); }

double gety() { return radius * sin(angle); }

public :

polar () { radius = 0.0; angle = 0.0; }

polar (float r, float a)

{ radius = r; angle = a; }

void display()

{ cout << "(" << radius << "," << angle << ")"; }

polar operator + (polar p2)

{ double x = getx() + p2.getx();

double y = gety() + p2.gety();

double r = sqrt (x * x + y * y);

double a = atan(y/x);

return polar(r,a); } };

Page 89: C++ infosystems 1

Introduction to OOP unit1

void main()

{

polar p1(10.0,0.0);

polar p2(10.0,1.570796325);

polar p3;

p3 = p1 + p2;

cout << "\np1 = "; p1.display();

cout << "\np2 = "; p2.display();

cout << "\np3 = "; p3.display();

}

2.4.2 Concatenating Strings Using '+'

Concatenation is the process of joining 2 strings into one. This is achieved using the function strcpy or strcat, prototyped in string.h. The '+' operator can be overloaded to concatenate two strings.

2.4.3 Copy Constructor

When a class is being designed, the designer normally supplies the default

constructor and the overloaded constructor. For example, to instantiate an

object of class, class1,

class1 cl1; default constructor will be called. class1 cl1(100); default constructor will be called.

Suppose,

class1 cl1; default constructor will be called. class1 cl2(cl1) ; A memberwise copy takes place. or

class1 cl2=cl1; A memberwise copy takes place.

To prevent this memberwise copy, it is necessary to provide the copy constructor.

The memberwise copy which the compiler does is dangerous if the object contains a pointer. For example, class class1

{ private : char *name;

Page 90: C++ infosystems 1

Introduction to OOP unit1

public :

class1() { strcpy(name,"\0");}

};

class1 cl1;

creates object cl1, with a pointer named, name pointing at a memory location x,

initialized to NULL.

class1 cl2(cl1);

creates object cl2, with a pointer named name pointing at memory x, which is copied from cl1.

Due to the memberwise copy, both objects have pointers pointing at the same memory location, resulting in one object being dependent on the other. Therefore, it is necessary to provide a copy constructor in this class. The use of the copy constructor is demonstrated in the exercise that follows.

2.4.4 Exercise To Implement The String Class.

Create a string class. Provide default constructor, overloaded constructor and copy constructor.

#include <iostream.h>

#include <string.h>

#include <conio.h>

class string

{

private :

char *str;

public :

string() {str=new char[1];strcpy(str,"\0");}

string(char *s) {str = new char[strlen(s)+1]; strcpy(str,s);}

string(string &s) {str=strdup(s.str);cout<<"\ncopy called";}

Page 91: C++ infosystems 1

Introduction to OOP unit1

show() {cout << endl<< str;}

change(char *ss) {strcpy(str,ss);}

// Overloading the assignment operator so that memberwise copy does not take

place.

string& operator = (string &s)

{

str= strdup(s.str);

cout << "\n assignment called";

return (*this);

}

// destructor to free the memory

~string() { delete str; cout<< "\n destroy";}

};

main()

{

clrscr();

string s1("welcome"); // Calls overloaded constructor

string s2=s1; //Calls copy constructor

string s3(s2); //Calls copy constructor

string s4;

s4=s1; //Calls overloaded assignment

s1.show();

s2.show();

s3.show();

s4.show();

s1.change("\t changed");

s1.show();

s2.show();

s3.show();

s4.show();

Page 92: C++ infosystems 1

Introduction to OOP unit1

getch();}

2.5 MULTIPLE OVERLOADING

Overloading '+' operator to add objects of class distance, to add polar co-ordinates and to concatenate two strings can be done in the same program. The procedure is known as multiple overloading. The compiler selects the correct function to carry out the "addition" based on the type of the operand.

2.5.1 Overloading Comparison Operators

Just as the arithmetic operators have been overloaded, the relational

operators can also be overloaded.

The following example shows how to overload the 'less than' (<) operator. EXAMPLE 2.6 OVERLOADING COMPARISON OPERATORS #include <iostream.h>

enum boolean {false,true};

class distance

{ private : int feet;

float inches;

public : distance ()

{ feet=0, inches=0.0; }

distance (int ft, float in)

{ feet=ft; inches=in; }

void getdist()

{ cout<<" \nEnter feet :"; cin >> feet;

cout<<" \nEnter inches :"; cin >> inches; }

void showdist()

{ cout<< feet<< "\'-" << inches << "\" "; }

boolean operator <(distance d2)

Page 93: C++ infosystems 1

Introduction to OOP unit1

{ float bf1 = feet + inches/12;

float bf2 = d2.feet+ d2.inches/12;

return (bf1<bf2)? true:false; }

};

void main()

{ distance dist1, dist2;

dist1.getdist(); dist2.getdist();

cout<<"\n dist1= " ; dist1.showdist();

cout<<"\n dist2= " ; dist2.showdist();

if (dist1<dist2) cout << "\ndist1 is less than dist2";

else cout << "\ndist1 is greater than dist2";

}

The approach used in the operator < () function in example 2.6 is similar to

overloading the + operator in example 2.4 except that here the overloaded

function operator < ( ) has a return type of boolean (defined in the enum

statement at the beginning of the program). The return value is true or false,

depending on the comparison of the two distances. The comparison is made by

converting both distances to floating point feet and comparing them using the

normal < operator.

2.5.2 Overloading Assignment Operator

In the following example, you shall overload the += operator. This operator combines the addition and assignment into one step. x+=y is the same as x=x+y EXAMPLE 2.7 OVERLOADING += OPERATOR #include <iostream.h>

class distance

Page 94: C++ infosystems 1

Introduction to OOP unit1

{ private : int feet ;

float inches;

public : distance () { feet = 0 ; inches = 0.0;}

distance (int ft, float in) { feet =ft; inches = in; }

void get_dist()

{ cout << " \n Enter feet:"; cin>> feet;

cout << "\n Enter Inches:"; cin >> inches; }

void show_dist()

{ cout << feet << "\'-" <<inches << ‘\"'; }

void operator += (distance); // function prototype

};

void distance :: operator += (distance d2) // function declared externally

{ feet += d2.feet; inches += d2.inches;

if (inches >=12.0) { inches -= 12.0; feet++; }

}

void main() { distance dist1; distance dist2(11,6.25);

dist1.get_dist(); cout<< "\ndist1="; dist1.show_dist();

cout << "\ndist2 = "; dist2.showdist();

dist1 += dist2; cout << "\n After addition";

cout << "\ndist1 = "; dist1.showdist();

}

In the operator += () function in the above example, the object that takes on the

value of the sum is the object of which the function is a member. Thus, it is feet

and inches that are given values, not temporary variables used only to return an

object.

2.6 DATA CONVERSION

The = operator will assign a value from one variable to another in statements like i1 = i2; where i1 and i2 are integer variables or user defined objects. Thus, assignments between types - Basic or userdefined, are handled by the compiler without any special instructions.

Page 95: C++ infosystems 1

Introduction to OOP unit1

2.6.1 Conversions Between Basic Types

To convert between basic types you use 'casting'. Casting provides explicit conversion between datatypes. Implicit conversion occurs during evaluation of mixed expressions. Example

int x,y;

float z;

x = (x + y) / z;

Since z is a float datatype, (x+y) is converted to float implicitly by the compiler. The result is stored in x by implicit conversion to int.

2.6.2 Conversions Between Objects And Basic Types

The conversion between object and Basic data types needs a separate routine to define the conversion. The following example shows how to convert between a basic data type and a user defined data type.

Example 2.8 Illustrates Conversions Between Objects And Basic

Types

// converts distance to meters and vice-versa.

# include <iostream.h>

const float MTF = 3.280833;

class distance

{ private : int feet; float inches;

public : distance() {feet = 0; inches = 0.0;}

distance (int ft, float in) { feet = ft; inches = in;}

distance(float meters)

{ float fltfeet = MTF * meters;

feet = int (fltfeet);

inches = 12 * (fltfeet - feet); }

Page 96: C++ infosystems 1

Introduction to OOP unit1

void getdist()

{ cout <<"\n Enter feet :"; cin >> feet;

cout <<"\n Enter inches :"; cin >> inches; }

void showdist() { cout << feet << "\'-" << inches << '\"';}

operator float () { float f = inches / 12;

f= f+float (feet);

return f/MTF;

}

};

void main() {

Distance dist1 = 2.35;

cout << "\ndist1 = "; dist1.showdist();

dist1 = 0.0; cout << "\ndist1 = "; dist1.showdist();

distance dist2(5,10.25);

float meters = float (dist2); // uses conversion function to convert

cout << "\ndist2 = " << meters << "meters";

meters = dist1; cout << "\ndist1 = " << meters << "meters ";

}

Example 2.8 illustrates both types of conversions - basic to userdefined and vice-versa. From Basic To User-Defined

The constructor, distance (float meters) converts a basic data type (float) to

user defined data type (distance). This function is called when an object of type

distance is created with a single argument. The function assumes this argument

represents meters. It converts the argument to feet and inches, and assigns the

resulting values to the objects data members.

From User-Defined To Basic

Page 97: C++ infosystems 1

Introduction to OOP unit1

Here, you overload the cast operator, thus creating a conversion function. The

function in example 2.8 which achieves this is the operator float() function. This

operator takes the value of the distance object of which it is a member, converts

this value to a float value representing meters and returns this value. This

operator is called by the statement, meters = float (dist2);

The statement meters = dist1 also has the same effect. Here, the compiler starts by looking for an overloaded = operator. But, when it doesn't find one and it sees the conversion function, it uses that instead.

EXAMPLE 2.9 Conversion Between Strings And String Objects // Convert between ordinary strings and class string.

# include <iostream.h>

# include <string.h>

const int sz = 80;

class string

{ private : char str[sz];

public : string() {str[0] = '\0';}

string(char s[]) // Convert string to class string object.

{ strcpy(str,s);}

void display() { cout << str; }

operator char * () { return str; }

};

void main()

{ string s1; char xstr[50] = "\nManipal Institute";

s1 = xstr; // uses 1-argument constructor.

Page 98: C++ infosystems 1

Introduction to OOP unit1

s1.display();

string s2 = " Of Computer Education.\n";

strcpy(xstr,s2); //uses conversion function.

cout << xstr;

}

Output of Example 2.9

Manipal Institute Of Computer Education.

2.6.3 Conversions Between Objects Of Different Classes

Conversions between objects of different classes can be done in the same way as the conversion between basic and user-defined types. This topic can be studied under two sections:

♦ Conversion routine in source object.

♦ Conversion routine in destination object.

Routine In Source Object

When the conversion routine is in the source class, it is implemented as a

conversion function. Example 2.10 shows the conversion between class rec and

class polar.

Example 2.10 Conversion From Polar To Class Rec Using Routine In Polar (Source Object).

# include <iostream.h>

# include <math.h>

class rec

{ private: double xco, yco;

public : rec() { xco = 0.0; yco = 0.0;}

rec(double x, double y)

{ xco = x; yco = y;}

void display()

Page 99: C++ infosystems 1

Introduction to OOP unit1

{ cout <<"(" << xco << "," << yco << ")";}

}; // end of rec class declaration

class polar

{ private: double radius,angle;

public : polar() { radius = 0.0; angle = 0.0; }

polar(double r, double a)

{ radius = r; angle = a;}

void display()

{ cout <<"(" << radius << "," << angle << ")";}

operator rec()

{ double x = radius * cos(angle);

double y = radius * sin (angle);

return rec(x,y);

}

}; // end of polar class declaration

void main()

{ rec rec1; polar pol1(10.0,0.785398);

rec1 = pol1;

cout << "\npol1 = "; pol1.display(); cout << "\nrec1 = "; rec1.display();

}

In example 2.10 the statement rec1 = pol1; needs conversion as rec and pol are

objects of two different classes. The conversion function is written as a member

function of the polar class (i.e. source object).

Routine In Destination Object

In example 2.10 you defined the conversion routine in the source object as its member function. The following example illustrates how to define the routine in the destination object. For this, you use a constructor with one argument.

Example 2.11 Converts From Polar To Rec Using Routine In Class Rec Destination).

Page 100: C++ infosystems 1

Introduction to OOP unit1

# include <iostream.h>

# include <math.h>

class polar

{ private : double radius, angle;

public : polar() { radius = 0.0; angle = 0.0;}

polar (double r, double a) { radius = r; angle = a; }

void display() { cout << "(" << radius << "," << angle << ")"; }

double getr() { return radius; }

double geta() { return angle; }

};

class rec

{ private : double xco, yco;

public : rec() { xco = 0.0; yco = 0.0; }

rec(double x, double y) { xco = x; yco = y; }

void display()

{cout << "(" << xco << "," << yco << ")"; }

rec(polar p)

{

float r = p.getr(); float a = p.geta();

xco = r * cos(a); yco = r * sin(a);

}

};

void main()

{ rec rec1; polar pol1(10.0,0.785398);

rec1 = pol1;

cout << "\npol1 = "; pol1.display(); cout << "\nrec1 = "; rec1.display();

}

Page 101: C++ infosystems 1

Introduction to OOP unit1

The conversion routine is a one-argument constructor, from the rec class rec(polar p). The function sets the object of which it is a member to the rectangular coordinates that correspond to the polar coordinates of the object received as an argument.

To perform the conversion, this constructor must be able to access the data

values of the polar object sent as an argument. The polar class contains the two

routines to allow this double getr(); and double geta();.

The statement rec1 = pol1 in main() of example 2.11 invokes the one -

argument constructor and the conversion is done.

Table 2.1 Conversions - When To Use What ?

Conversion Type Routine in Destination Routine in Source

Basic to Basic (Built - in Conversion Functions)

Basic to Class Constructor NA

Class to Basic Not available Conversion function

Class to Class Constructor Conversion function

Precautions While Overloading Use similar meaning : Do not overload '+' operator for subtraction. It can be confusing to the user.

♦ Use similar syntax : For better readability and reusability, try to use syntax

similar to the existing usage of the operator.

♦ Restrict the number : Too many overloaded operators causes the listing to

be less readable instead of more.

♦ Avoid ambiguity : Avoid doing the same conversion in more than one way

as the compiler will not know which function to use.

♦ Not all operators can be overloaded : Operators that cannot be overloaded

are :

Page 102: C++ infosystems 1

Introduction to OOP unit1

:: - Scope resolution operator ?: - Conditional operator

.* - Pointer to member operator . - Dot operator

2.7 Function Overloading

The following example illustrates overloading of functions. The function cout

used in the example is an output function, provided in iostream.h. It displays the

message/value on standard output (normally the VDU.)

In this example, a function 'repchar' is overloaded to print a sequence of

characters. What should be the output if there are no arguments or if there is

one character as argument or if there is one character and one integer as the

argument depends on the function body of the respective functions.

The function definition for each function is written according to the data it

receives. Thus, there will be three different functions with the same name but

with a different set of arguments and a different function definition for each.

Example 2.12 # include <iostream.h>

void repchar();

void repchar(char);

void repchar(char, int);

void main()

{

repchar(); // prints + 45 times.

repchar('='); // prints = 45 times.

repchar('>',30); // prints > 30 times.

} // end of main

void repchar() {

for (int j = 0; j<45; j++)

cout << '+';

Page 103: C++ infosystems 1

Introduction to OOP unit1

cout << endl;

}

void repchar(char ch) {

for (int j = 0; j<45; j++)

cout << ch;

cout << endl;

}

void repchar (char ch, int n)

{

for (int j = 0; j < n; j++)

cout << ch;

cout << endl;

}

Output for the above example will be as follows: +++++++++++++++++++++++++++++++++++++++++++++ ============================================= >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

2.8 EXERCISE TO STORE EMPLOYEE INFORMATION /* class employee stores employee information. You can use calc() function to

return average salary */

# include <istream.h>

#include <string.h> // to use strings

class employee

{

private :

int eno;

char name[20];

int basic;

Page 104: C++ infosystems 1

Introduction to OOP unit1

public:

void getdata() // to enter the data

{ cout << “Enter employee no:”; cin>> eno; cin.get();

cout <<“Enter name :”; cin.getline(name,’\n’);

cout <<“Enter Salary :”; cin>>basic;

}

void dispdata() // to display the value

{ cout << “Employee no:” <<eno;

cout << “Name :”<<name;

cout << “Salary :”<<basic;

}

float calc(employee x)

{ float temp;

temp= (float(basic)+x.basic)/2; // int basic is casted to float type

return temp;

};

void main() { employee a1, b1;

a1.getdata(); b1.getdata();

float average =a1.calc(b1); /* object a1, invoke function calc(), b1 is passed

as parameter */

cout << endl<<“Average salary: “<< average;

} // end of program

2.9 INHERITANCE

Inheritance is the process of creating new classes, called derived classes, from existing classes, the existing class is the base class. The derived class inherits all the capabilities of the base class but can add properties

Parameter received

basic of object that calls calc() function -i.e. instance varible

Page 105: C++ infosystems 1

Introduction to OOP unit1

of its own. The base class is unchanged by this process. Inheritance has two important advantages.

♦ Code reusability : it permits code reusability. Once a base class is written and

debugged, it need not be checked again, but can nevertheless be adapted to

work in different situations. Reusing code saves time and money and

increases a program's reliability. A programmer can use a class created by

another person or company, and without modifying it, derive other classes

from it that are suited to particular situations.

♦ The derived class can add data and function members to the class without

affecting the base class behavior. This is data abstraction.

♦ The protection can be increased in derived classes, but cannot be

decreased, that is - a class item declared as protected in a class cannot be

made public later in the derived classes. Making a public item protected or

private in a derived class is allowed.

2.9.1 Derived Class And Base Class

To derive from another class, the class declaration is modified. The base class

name is linked with the new class name, when the class is declared as :

class derived_class_name : public base_class_name

Access specifiers public or private can be used while deriving from the base

class. This determines the availability of the base class members to derived

class.

Example 2.14 Illustrates Derived And Base Classes

// Inheritance with counter class

# include <iostream.h>

class counter // base class

{ protected : unsigned int count; // Note : not private

public : counter ( ) {count = 0;}

Page 106: C++ infosystems 1

Introduction to OOP unit1

counter (int c) {count = c;}

int getcount( ) {return count;}

counter operator ++ ( ) { count++; return counter(count); }

};

class countdown : public counter // Derived class

{ public : counter operator -- ( )

{ count--; return counter(count); }

};

void main( )

{ countdown c1;

cout << "\nc1 = " << c1.getcount( );

c1++; c1++; c1++;

cout << "\nc1 = " << c1.getcount( );

c1--; c1--;

cout << "\nc1 = " << c1.getcount( );

}

The statement class countdown : public counter specifies that countdown is

derived from counter. Thus counter is the base class and countdown is the

derived class.

Accessing Base Class Members A member function in the base class can be used by objects of the derived class.

This is called 'accessibility'. This can be done by:

♦ Substituting base class constructors

♦ Substituting base class member functions.

In Example 2.14, the statement countdown c1; causes an object of class countdown to be created and initialized to zero. This is possible because,

Page 107: C++ infosystems 1

Introduction to OOP unit1

when a constructor is not specified in the derived class, the compiler will choose an appropriate constructor from the base class.

The object of countdown class also uses the operator ++() and getcount() functions from the counter class to increment and to display the count respectively. These are from the base class.

The Protected Access Specifier Protected, is another type of protection available within a class. Items declared as protected are private within a class and available for private access in the derived class. The data count is declared as a protected member for the class counter because private members cannot be accessed outside the class. Protected member can be accessed by the classes derived from the base class. The following table gives the difference between the three access specifiers - private, public and protected.

TABLE 2.2 Access Specifiers Access

Specifiers

Accessible from

own class

Accessible from

derived class

Accessible from

objects outside class

Public Yes Yes Yes

Protected Yes Yes No

Private Yes No No

Base Class Unchanged ! Even if other classes have been derived from it, the base class remains unchanged. It is to be noted that the base class objects cannot use any data members or member functions of the derived class.

2.9.2 Derived Class Constructors

In example 2.14 you saw that when an object of class countdown was declared,

it called the constructor of the base class counter. But, to initialize a value to the

object of class countdown, the base class constructor is not used by the

compiler. Only those base class constructors which take no arguments, are

available to the derived class. So, you must write a new set of constructors for

the derived class to allow initialization of the derived class objects.

Page 108: C++ infosystems 1

Introduction to OOP unit1

Example 2.15 Constructors In Derived Class # include <iostream.h>

class counter

{ protected : unsigned int count;

public : counter( ) { count = 0; }

counter(int c) { count = c;}

int getcount( ) { return count; }

counter operator ++ () { count++; return counter(count); }

};

class countdown : public counter

{ public : countdown ( ) : counter( ) { } ;

countdown (int c) : counter (c) { };

/* the base class constructors are called in the derived class constructor */

countdown operator -- ( ) { count --; return

countdown(count); }

};

void main() {

countdown c1; countdown c2(100);

cout << "c1 = " << c1.getcount( );

cout << "c2 = " << c2.getcount( );

c1++; c1++; c1++;

c2--; c2--;

countdown c3 = c2--;

cout << "c1 = " << c1.getcount() << endl ;

cout << "c2 = " << c2.getcount() << endl;

cout << "c3 = " << c3.getcount() << endl;

}

In example 2.15, you see that the declaration of a constructor in the derived

class is as countdown( ) : counter( ) { } and countdown(int x ) : counter(x ) { }

Page 109: C++ infosystems 1

Introduction to OOP unit1

The derived class constructors call the base class constructors. Any additional

statements can be written inside the braces. In this example, the derived class

constructors do nothing additional, so there are no statements within the braces.

In this case, the value of count is passed to the derived class constructor which

in turn passes it to the base class constructor which does the actual initialization.

The one argument is also used in the assignment statements like countdown c3

= c2--;

Dangers of Protected

You should know that there is a disadvantage of making class protected. Say

you have written a class library, which you are distributing, to the public. Any

programmer who buys this library can access protected members of your

classes by simply deriving other classes from them. To avoid corrupted data, it is

often safer to force derived classes to access data in the base class using only

public functions in the base class, just as ordinary main() programs must do. You

will need to weigh the advantages of protected against its disadvantages in your

own programs.

2.9.3 Overriding Member Functions

The derived class can have member functions, which has the same name as the

member functions of the base class.

The example 2.16 shows the manipulation of data storage object called stack.

The stack is basically an array of integers. The restriction here is that the data is

stored and removed from the same end. Hence, the last data stored is the first to

be removed. Hence, you say that it follows LIFO (Last in first out) logic. You use

the function push( ) for storing values into the stack and pop( ) to remove data

values from the stack.

In the example, the base class has two functions - push( ) to store values into

the stack and pop( ) to remove values from the stack. Since the stack is an array

of integers, an erroneous result is obtained if you try to push values into a full

stack (add values to the array after the maximum index) or pop values from an

Page 110: C++ infosystems 1

Introduction to OOP unit1

empty stack (No values have been stored in the stack) . Hence top must have

values in the range 0 to MAX.

But, you do not check the value of top in the base class. Hence, a second class

stack2 is derived from the class stack. So, stack is the base class and stack2 is

the derived class.

Example 2.16 Overriding Base Class Member Functions # include <iostream.h>

# include <process.h>

const int MAX = 10;

class stack // Does not check for the range of variable top.

{ protected : int st[MAX]; int top;

public : stack() { top = -1; }

void push (int var) { st [++ top] = var; }

int pop() { return st[top--]; }

/* For a right answer the top value must be < MAX. */

};

class stack2 : public stack // Checks for the range of top .

{

public :

void push(int var) // Function name same as base class function

{ if (top +1< MAX)

stack :: push(var);

else

{ cout << "\n Error : Stack full "; exit (1); }

}

int pop() // Function name same as base class function

{

if (top > =0) return stack :: pop();

else

{ cout << "\n Error : Stack Empty "; // top < 0

Page 111: C++ infosystems 1

Introduction to OOP unit1

exit (1);

}

}

}; // end of class

void main()

{

stack2 s1;

s1.push(11); s1.push(22); s1.push(33);

cout << endl << s1.pop(); cout << endl << s1.pop();

cout << endl << s1.pop(); cout << endl << s1.pop();

}

The derived class stack2 has the same functions as the base class. When the

push() function is called by an object of the derived class, the function described

in the derived class is executed. Hence, you say the derived class member

functions override the base class member functions. The range of top is checked

in the member function of the derived class and hence the correct values can be

obtained. If the value of top is out of range, an error message is given and the

program is terminated. Note that the derived class functions call the base class

functions through the statements stack :: push(var) and return stack :: pop();

The scope resolution operator (::) is used for this purpose. Using this operator

allows us to specify exactly what class the called function is a member of.

Inheritance In The Distance Class

Consider the class distance (see example 2.4). It does not have a method to tell

the user whether the distance is in the positive or the negative direction. i.e., the

distance class assumes that the distances to be represented would always be

positive. In order to add the facility for giving negative distances, you will derive a

new class from 'distance'. This is illustrated in Example 2.17.

Page 112: C++ infosystems 1

Introduction to OOP unit1

Example 2.17 Inheritance In Class Distance

//DISTSIGN class derived from DISTANCE adding the use of signs

# include <iostream.h>

# include <conio.h>

enum positive_negative {negative,positive};

class distance

{

int feet;

float inches;

public :

distance() { feet = 0; inches = 0.0; }

distance ( int ft, float in)

void getdist() ;

void showdist() { cout << end1<< "Distance is : ";

cout << feet << "feet " << inches << "inches";

}

void operator += (distance d2);

}

void distance :: operator += (distance d2)

{feet=feet+d2.feet;

inches =inches +d2.inches;

while (inches >=12)

{

feet++; inches =inches -12.0;

}

}

distance:: distance (int ft, float in) { feet=ft; inches=in;

while (inches >= 12)

{ feet ++; inches = inches -12;}

}

Page 113: C++ infosystems 1

Introduction to OOP unit1

void distance :: getdist () { cout<<end1<< "Enter feet :";

cin >> feet ;

cout << "Enter inches :";

cin >> inches;

while (inches >= 12)

{

feet++;

inches = inches - 12;

}

}

class distsign : public distance

{

private :

positive_negative sign;

public :

distsign() : distance () { sign = positive;}

distsign(int ft,float in,positive_negative sg=positive) : distance(ft,in)

{sign=sg;}

void getdist()

{ distance::getdist();

char ch;

cout << "enter sign +/- "; cin >> ch;

sign = ((ch=='+') ?positive:negative);

}

void showdist()

{

distance :: showdist();

cout << ((sign == positive) ? '+': '-');

Page 114: C++ infosystems 1

Introduction to OOP unit1

}

};

void main()

{

clrscr();

distsign d1;

d1.getdist();

d1.showdist();

getch();

};

Output of Example 2.17

Enter feet :10

Enter inches :6.25

Enter sign (+ or -):-

a = (-)10'6.25"

b = (+)11'6.25"

c = (-)100'5.5"

They reflect the constructors in the distance class. There are two constructors.

The first takes no arguments. The second takes two/three arguments since the

third argument is optional. If no argument is given the sign is set to pos (+). The

setting of values to feet and inches is done by the base class constructor which

is invoked from the derived class.

Member Functions In Distsign The getdist() function in distsign allows a 'sign' to be entered in addition to the

feet and inches. The showdist() function displays this sign alongwith feet and

inches. This is illustrated in the output of Example 2.17. All member functions of

the derived class call the respective function from the base class and perform

some additional functions. Only the additional features are written in the member

Page 115: C++ infosystems 1

Introduction to OOP unit1

functions of the derived class. Thus, you are using the base class code in the

derived class. This is a good example for 'code reusability'.

2.9.4 Private And Public Inheritance

In the above examples, the derived classes were specified as :

class derived_class_name : public base_class_name. Here the keyword public specifies that the objects of the derived class are able to access the public member functions of the base class.

In contrast to this, if the keyword private is used, the objects of the derived class

cannot access public member functions of the base class. Since objects can

never access private or protected members of a class, the result is that no

member of the base class is accessible to objects of the derived class.

The following example shows the various valid and invalid access of the

variables.

Example 2.18 Access Combinations class A // Base Class

{

private : int privdataA;

protected : int protdataA;

public : int pubdataA;

};

class B : public A // publicly derived class

{

public : void funct()

{

int a;

a = privdataA; // Error

Page 116: C++ infosystems 1

Introduction to OOP unit1

a = protdataA; // O.K.

a = pubdataA; // O.K.

}

};

class C : private A // privately derived class

{

public : void funct()

{ int a;

a = privdataA; // Error

a = protdataA; // O.K.

a = pubdataA; // O.K.

}

};

void main( ) // main function

{ int a; B objB;

a = objB.privdataA; // Error

a = objB.protdataA; // Error

a = objB.pubdataA; // O.K. since B is public.

C objC;

a = objC.privdataA; // Error

a = objC.protdataA; // Error

a = objC.pubdataA; // Error since C is private.

}

Example 2.18 specifies a base class A with private, protected, and public data items. Two classes B and C are derived from A. B is publicly derived and C is privately derived. Objects of the publicly derived class B can access public members of the base class A, while objects of the privately derived class C cannot. If any access specifier is not supplied when creating a class, private is assumed.

Page 117: C++ infosystems 1

Introduction to OOP unit1

2.9.5 Access Specifiers : When To Use What ?

Suppose, there is a function in the base class that works fine with the objects of

the base class but gives erroneous results with objects of the derived classes

and there is no function of the same name in the derived class to override the

base class. To prevent the objects of the derived class calling this function two

methods can be employed.

♦ Make a dummy function with the same name for the derived class and print

an error message.

Or

♦ Make the derived class private. Now, the function will not be accessible to

objects of the derived class, although it will still be accessible to objects of

the base class.

2.9.6 Class Hierarchies

In all the previous examples, inheritance has been used to add functionality to an

existing class. Inheritance can also be used as a part of the original design of a

program. Then the base class has the highest level in the class hierarchies. The

classes derived from the base class get the second level of hierarchy. The

classes derived from the derived classes get the third level and so on.

The next example illustrates this. Here the employee is the base class and is at

the first level of hierarchy. The division of employees as manager, scientist, and

labourer are derived from 'employee' and form the second level.

EXAMPLE 2.19 Models Employee Database Using Inheritance

# include <iostream.h>

class employee // Contains name and number of the employee.

{

private : char name[80];

unsigned long number;

Page 118: C++ infosystems 1

Introduction to OOP unit1

public :

void getdata()

{

cout << "\n Enter last name "; cin.getline(name,80);

cout << "\n Enter number "; cin >> number;

}

void dispdata()

{ cout <<"\n Name :" << name ;cout << "\n Number : " << number;

}

};

class manager : public employee

{ private : char title [80];

public : void getdata()

{ employee :: getdata( );// Call base class member function

cout << "Enter title : "; cin.getline(title,80);

}

void dispdata()

{ employee :: dispdata( );//Call base class member function

cout << "\n Title :" << title << endl;

}

};

class scientist : public employee

{ private : int papers;

public : void getdata()

{ employee :: getdata();

cout << "Enter papers published :"; cin >> papers;

}

void dispdata()

{ employee :: dispdata();

cout << "\n Number of publications :" << papers;

}

Page 119: C++ infosystems 1

Introduction to OOP unit1

};

void main()

{

manager m1;

scientist s1;

cout<<endl << "Manager "; m1.getdata(); cout << "\nData "; m1.dispdata();

cout << endl << "Scientist "; s1.getdata(); cout << "\nData "; s1.dispdata();

}

2.9.7 "Abstract" Base Class

Classes used only for deriving other classes (e.g. : employee in example 2.19) are called abstract classes, meaning that no actual objects of this class are created. Note that no objects of the base class employee are defined. It is used as a general class, which acts as a base from which other classes are derived.

Assume a labourer class. Though a labourer is an employee, there is no unique identification for the class and hence the labourer class operates identically to the base class. Deriving a separate class for the labourer may seem unnecessary, but by making it a separate class the fact that all classes are descended from the same source employee is emphasized. 2.10 LEVELS OF INHERITANCE

Classes can be derived from derived classes also. The following segment

illustrates this.

class A

{ };

class B : public A // First level of inheritance

{ };

class C : public B // Second level of inheritance

{ };

Hence B is derived from A and C is derived from B. Now, you have two levels of

inheritance.

Page 120: C++ infosystems 1

Introduction to OOP unit1

EXAMPLE 2.20 Models Student Database # include <iostream.h>

# include <string.h>

class student

{

private : int id; char name[20];

public : student()

{ id = 0; strcpy(name,"\0");

student(int i, char *n)

{ id = i; strcpy(name, n);

void getdata()

{cout << "\n Roll Number "; cin >> id;

cout << "\n Name :";cin.get(); cin.getline(name,20);

}

void dispdata()

{cout << "\nId = " << id << "\nName = " << name;}

};

class marks : public student // First level of inheritance

{

protected : int mks[3];

public : marks() : student() { mks[0]=mks[1]=mks[2] = 0;}

marks(int i, char *n, int a, int b, int c) : student(i,n)

{ mks[0] = a; mks[1] = b; mks[2] = c; }

void getdata() {

student :: getdata();

for (int i=0; i<3; i++)

{ cout << "\n Enter marks " << i+1; cin >> mks[i]; }

}

void dispdata() {

student :: dispdata();

Page 121: C++ infosystems 1

Introduction to OOP unit1

for (int i=0; i<3; i++)

{ cout << "\n Marks in subject " << i+1 <<" is ";

cout << mks[i]; }

}

};

class report : public marks // Second Level of Inheritance.

{

private : int tot;

public : report () { tot = 0; }

report (int i, char *n, int a, int b, int c) : marks (i,n,a,b,c)

{ tot = a + b + c; }

void getdata()

{

marks :: getdata(); tot = mks[0] + mks[1] + mks[2];

}

void dispdata()

{

float avg = tot / 3.0; marks :: dispdata();

cout << "\n Total = " << tot;

cout << "\n Average = " << avg;

}

};

void main( )

{ report r1(9701, "Poornima", 76, 87, 90);

r1.getdata( );

r1.dispdata( );

}

In the above example, the student class is the base class. The marks class is

derived from student and forms the first level of inheritance. The report class is

derived from marks class. This forms the second level of inheritance as the

Page 122: C++ infosystems 1

Introduction to OOP unit1

report class is derived from marks, which is derived from student. The data

members of marks class is specified as protected because the total is calculated

in the reports class.

2.11 MULTIPLE INHERITANCE

A class can be derived from more than one base class. This is called multiple

inheritance. The syntax is as follows:

class A { }; // Base Class A

class B { }; // Base Class B

class C : public A, public B // C is derived from A and B

{ };

The base classes from which C is derived are listed following the colon on C's

specification separated by commas.

Multiple Inheritance can be illustrated by the following diagram.

CLASS HIERARCHY BASE CLASS 1 BASE CLASS 2 Derived Class 1 Derived Class 2 Derived Class 3

Figure 1 In the above diagram, the base classes are at a higher level of hierarchy than

the derived classes. The arrow gives the relation ‘derived from’ . Here, all the

derived classes have been derived from both base classes. This is called

multiple inheritance.

2.11.1 Member Functions In Multiple Inheritance

Page 123: C++ infosystems 1

Introduction to OOP unit1

Using member functions of the base classes is described through the following

example.

EXAMPLE 2.21 Illustrates Multiple Inheritance

# include <iostream.h>

# include <string.h>

class student

{

private : int id; char name[20];

public : student()

{ id = 0; strcpy(name,"\0");

student(int i, char *n)

{ id = i; strcpy(name, n);

void getdata()

{cout << "\n Roll Number "; cin >> id;

cout << "\n Name :";cin.get(); cin.getline(name,20);

}

void dispdata()

{cout << "\nId = " << id << "\nName = " << name;}

};

class marks {

protected : int mks[3];

public : marks() { mks[0]=mks[1]=mks[2] = 0;}

marks(int a, int b, int c)

{ mks[0] = a; mks[1] = b; mks[2] = c; }

void getdata() {

for (int i=0; i<3; i++)

{ cout << "\n Enter marks " << i+1; cin >> mks[i]; }

}

void dispdata() {

for (int i=0; i<3; i++)

Page 124: C++ infosystems 1

Introduction to OOP unit1

{ cout << "\n Marks in subject " << i+1 <<" is ";

cout << mks[i]; }

}

};

class report : private student, private marks // Multiple Inheritance.

{

private : int tot;

public : report() : student () , marks() { tot = 0; }

report (int i, char *n, int a, int b, int c)

: student(i, n), marks(a, b, c)

{ tot = a + b + c; }

void getdata()

{

student :: getdata();

marks :: getdata(); tot = mks[0] + mks[1] + mks[2];

}

void dispdata()

{

float avg = tot / 3.0;

student :: dispdata(); marks :: dispdata();

cout << "\n Total = " << tot;

cout << "\n Average = " << avg;

}

};

void main( )

{

report r1(9701, "Poornima", 76, 87, 90);

r1.getdata( ); r1.dispdata( );

}

The getdata() and the dispdata() functions in report class will include a call to functions in the student class by the statements student :: getdata();

Page 125: C++ infosystems 1

Introduction to OOP unit1

and student :: dispdata(); and the marks class by the statements marks :: getdata() and marks :: dispdata(); . Since the objects of the derived classes never call the routines of the base classes, the derivation is made private instead of public.

2.11.2 Constructors In Multiple Inheritance

The statements are written similar to those of example 2.17. The two base

classes are separated by commas. The syntax for this:

dcname () : bcname1() , bcname2()

{ extra statements needed }

where dcname is the derived class name; bcname1 and bcname2 are the names of the base classes.

If there are arguments passed, the modified syntax is:

dcname (dcarg + bcarg1 + bcarg2) : bcname1 (bcarg1) , bcname2 (bcarg2)

{ extra statements needed }

where dcname is the derived class name; bcname1 and bcname2 are the

names of the base classes. dcarg are the arguments required for the derived

class constructor bcarg1 and bcarg2 are the arguments for constructors of the

base classes.

This has been illustrated in the example 2.21 in the report class.

2.11.3 Ambiguity In Multiple Inheritance

The most common ambiguity is shown in the example below. When both the

base classes have a function with the same name and you call the function with

the object of the derived class, the compiler will not know which function to use.

Hence, it should be specified clearly by writing the base class name in the calling

statement.

Example 2.22 Ambiguity In Multiple Inheritance

Page 126: C++ infosystems 1

Introduction to OOP unit1

# include <iostream.h>

class A

{ public : void show { cout << "\n Class A"; }

};

class B

{ public : void show { cout << "\n Class B"; }

};

class C : public A, public B { };

void main()

{

C objc; objc.show(); // Error : ambiguous function call

objc.A::show(); // Call the member function of A

objc.B::show(); // Call the member function of B

}

Thus, the scope - resolution operator is used to resolve ambiguity.

2.12 CONTAINERSHIP : CLASSES WITHIN CLASSES

In Inheritance, if a class B is derived from class A, B has all characteristics of A in addition to its own. Hence you can say that "B is a kind of A". So, inheritance is sometimes called as a "kind of" relationship. There is another kind of relationship called a "has a" relationship, or containership. In OOP, this relation occurs when you have an object of class A in class B as shown.

class A

{ };

class B

{ A a; // A is contained in B. };

This relation can be used instead of inheritance. Thus, the employee database

problem gives the following relationships :

Example 2.23 Containership With Student And Marks

Page 127: C++ infosystems 1

Introduction to OOP unit1

# include <iostream.h>

# include <string.h>

class student

{

private : int id; char name[20];

public : student()

{ id = 0; strcpy(name,"\0");

student(int i, char *n)

{ id = i; strcpy(name, n);

void getdata()

{cout << "\n Roll Number "; cin >> id;

cout << "\n Name :";cin.get(); cin.getline(name,20);

}

void dispdata()

{cout << "\nId = " << id << "\nName = " << name;}

};

class marks {

private : int mks[3]; student s;

public : marks() { mks[0]=mks[1]=mks[2] = 0;}

marks(int a, int b, int c) { mks[0] = a; mks[1] = b; mks[2] = c; }

void getdata() { s.getdata();

for (int i=0; i<3; i++)

{ cout << "\n Enter marks " << i+1; cin >> mks[i]; }

}

void dispdata()

{

s.dispdata();

for (int i=0; i<3; i++)

{ cout << "\n Marks in subject " << i+1 <<" is ";

Page 128: C++ infosystems 1

Introduction to OOP unit1

cout << mks[i]; }

}

};

void main( )

{

marks m1;

m1.getdata( ); m1.dispdata( );

}

2.13 INHERITANCE AND PROGRAM DEVELOPMENT

Inheritance is a very useful concept when it comes to program development.

Thus, if programmer A creates a class, it can be improved by programmer B and

used by programmer C and D. This is possible only due to the software

reusability feature of C++. Thus, OOP makes programming more flexible, but

more complex.

2.14 EXERCISE

1. Overload the == operator to compare the two string objects.

2. Overload the + operator to add two distance objects.

3. Overload the -= operator to subtract two distance objects.

4. Create a student class which stores the id, name and fees of the student.

Derive a class to store the marks in three subjects of the student. Give the

necessary interface to it.

5. Modify the time class from Exercise 7 in Unit 1 so that instead of a function to

add time it uses the overloaded operator + to add 2 times.

6. A publishing company markets both books and audio cassette version of its

work. Create a class publication that stores the title and price of a

publication. From this class derive 2 classes book which adds a page count

Page 129: C++ infosystems 1

Introduction to OOP unit1

and tape which adds a playing time in minutes. Each of these 3 classes

should have a getdata() function to get its data from the user at the

keyboard, and a putdata() function to display its data.

2.15 SUMMARY

This unit covers the concept of OOP – Polymorphism. Polymorphism means one

thing having many forms. It is a very powerful concept, which gives C++

language a facility to redefine itself into a new language. There are 2 types of

polymorphism – operator overloading and function overloading.

An operator can be overloaded to perform different operations on different data

types in different content. All forms of operators can be overloaded to perform a

set of distinct operations on objects. These instructions are to be given in

member functions called operation function. Arithmetic operators, comparison

operators and most other operators can be overloaded. Even the cast operators

can be overloaded to perform conversion between objects and basic data types

and between objects of different classes.

Inheritance is the most powerful use of a class and the most important concept

of OOP. It is the mechanism using which reusability of code is achieved.

Libraries of classes can be distributed like libraries of functions. A new class can

be derived from an existing one having all the properties of the old one in

addition to new members and enhancements.

ANSWER TO EXCERISE 2.14 1. //Overload the == operator to compare the 2 strings

#include <iostream.h>

#include <string.h>

class string

{

private : char * str;

Page 130: C++ infosystems 1

Introduction to OOP unit1

public :

string() {str=new char[1];strcpy(str,"\0");}

string(char *s) {str=new char [strlen(s)+1]; strcpy(str,s);}

~string() {delete str; cout<<"\n Destroy";}

int operator==(string &st)

{ int a;

if (stricmp(str,st.str)==0)

return 1;

else

return 0;

}

void display() {cout <<endl <<str;}

void getdata() { cout <<"Enter a string"<<endl;

cin.getline(str,'\n');}

};

void main()

{ string s1,s2;

s1.getdata();

s2.getdata();

s1.display();

s2.display();

if (s1==s2)

cout<< "Both strings are equal"<<endl;

else

cout<< "Strings are not equal"<<endl;

}

Page 131: C++ infosystems 1

Introduction to OOP unit1

2. // Overloading + operator

# include<iostream.h>

class distance

{ private : int feet;

float inches;

public : distance() {feet=0;inches=0.0;}

distance(int f,float i) {feet=f;inches=i;}

void getdist()

{ cout<< "Enter the feet";cin>>feet;

cout<< "enter the inches";cin>>inches;

while(inches>=12)

{ feet++;

inches-=12;

}

}

void showdist()

{ cout<<feet<< "\'-"<<inches<<"\""<<endl;}

~distance()

{cout<<"Object destroyed"<<endl;}

distance operator + (distance);

};

distance distance :: operator + (distance d)

{ distance d1;

d1.feet=feet+d.feet;

d1.inches=inches+d.inches;

if (d1.inches>=12.0)

{ d1.inches-=12.0;

d1.feet++;

Page 132: C++ infosystems 1

Introduction to OOP unit1

}

return d1;}

void main()

{ distance dist1,dist2,dist3;

dist1.getdist();

dist2.getdist();

dist3 = dist1 + dist2;

dist1.showdist();

dist2.showdist();

dist3.showdist();

}

3.

#include<iostream.h>

class distance

{ private : int feet;

float inches;

public : distance() {feet=0;inches=0.0;}

distance(int f,float i) {feet=f;inches=i;}

void getdist()

{ cout<< "Enter the feet";cin>>feet;

cout<< "enter the inches";cin>>inches;

while(inches>=12)

{ feet++;

inches-=12;

}

}

Page 133: C++ infosystems 1

Introduction to OOP unit1

void showdist()

{ cout<<feet<< "\'-"<<inches<<"\""<<endl;}

~distance()

{cout<<"Object destroyed"<<endl;}

void operator -= (distance);

};

void distance :: operator -= (distance d)

{ distance d1;

feet -= d.feet;

inches -= d.inches;

if (inches>=12.0)

{ inches-=12.0; feet++; }

}

void main() {

distance dist1,dist2;

dist1.getdist();

dist2.getdist();

dist1.showdist();

dist1 -= dist2;

dist1.showdist();

dist2.showdist();

}

4.

# include<iostream.h>

# include <string.h>

# include <iomanip.h>

class student {

private : int id; char name[20]; float fees;

public : student(){id=0;strcpy(name,"\0");fees=0.0;}

Page 134: C++ infosystems 1

Introduction to OOP unit1

student (int i,char *n,float f) { id=i; strcpy(name,n); fees=f;}

void getdata() {

cout <<"Enter id";cin>>id;cin.get();

cout <<"Enter name"; cin.getline(name,'\n');

cout<<"Enter fees"; cin>>fees;

}

void dispdata() {

cout<<"id is "<<id<<endl <<"name is"<<name<<endl;

cout<<"fees is"<< setiosflags(ios::fixed)

<< setiosflags(ios::showpoint)<<setprecision(2)<<setw(10)<<fees;

}

};

class marks : private student

{ private : int marks[3];

public : marks():student() {marks[0]=marks[1]=marks[2]=0;}

marks(int i,char *n,float f,int a,int b,int c):student(i,n,f)

{ marks[0]=a;

marks[1]=b;

marks[2]=c;}

void getdata()

{

student ::getdata();

for (int i=0;i<3;i++)

{ cout<<"\n enter marks"<<i+1;cin>>marks[i];}

}

void dispdata()

{ student ::dispdata();

for (int i=0;i<3;i++)

{cout<<"\n marks in subject"<<i+1<<"is";cout<<marks[i];}

}

Page 135: C++ infosystems 1

Introduction to OOP unit1

};

void main()

{ marks m1(9901,"Asha",4000,60,70,80);

m1.getdata();

m1.dispdata();

}

5.

#include <iostream.h>

class time

{private : int hrs,mins,secs;

public :

time() { hrs=0;mins=0;secs=0;}

time(int h, int m, int s) { hrs=h; mins=m; secs=s;}

void getdata() {

cout<< "Enter hours";cin>>hrs;

cout<< "Enter minutes";cin>>mins;

cout<< "Enter seconds";cin>>secs;

while(secs>=60)

{ secs-=60;

mins++;}

while(mins>59)

{ mins-=60; hrs++;}

}

void dispdata() {

cout<<hrs<<":"<<mins<<":"<<secs<<endl;

Page 136: C++ infosystems 1

Introduction to OOP unit1

}

time operator + (time t1)

{ time t2;

t2.secs=secs+t1.secs;

t2.mins=mins+t1.mins;

t2.hrs =hrs +t1.hrs;

if (t2.secs>=60) { t2.secs-=60; t2.mins++;}

if (t2.mins>=60) {t2.mins-=60; t2.hrs++;}

return t2;

}

};

void main()

{

time time1,time2,time3;

time1.getdata();

time2.getdata();

time1.dispdata();

time2.dispdata();

time3=time1+time2;

time3.dispdata();

}

6.

//publication class & derived class

#include<iostream.h>

const int LEN=80;

class publication

{

private : char title[LEN];

float price;

public : void getdata()

Page 137: C++ infosystems 1

Introduction to OOP unit1

{ cout<<"\n enter title:";cin>>title;

cout<<"enter price";cin>>price;

}

void putdata()

{ cout<<"\n title:"<<title;

cout<<"\n price:"<<price;

}

};

class book : private publication

{ private : int pages;

public : void getdata()

{ publication ::getdata();

cout<<"enter number of pages:";

cin>>pages; }

void putdata()

{ publication :: putdata();

cout<<"\n pages:"<<pages;

}

};

class tape : private publication

{ private : float time;

public :

void getdata()

{ publication ::putdata();

cout<<"\nenter playing time :";cin>>time;

}

void putdata()

{ publication :: putdata();

cout<<"playing time:"<<time;

Page 138: C++ infosystems 1

Introduction to OOP unit1

}

};

void main()

{

book book1; tape tape1;

book1.getdata(); tape1.getdata();

book1.putdata(); tape1.putdata();

}

Page 139: C++ infosystems 1

Introduction to OOP unit1

UNIT 3 TEMPLATES, POINTERS AND GRAPHICS

Structure

3.0 Introduction 3.1 Objectives 3.2 Template

3.2.1 Generalized Stack Header File 3.2.2 Using The Stack Header file to Create Integer Stack 3.2.3 Using The Stack Header file to Create Character Stack 3.2.4 Creating Stack Header file Using Templates 3.2.5 Using the Template To Create Stack 3.2.6 Inheritance of Class Stack Using Templates 3.2.7 Using the Class Stack

3.3 Address And Pointers 3.4 Memory Management In C++

3.4.1 The new Operator 3.4.2 The delete Operator

3.5 Linked Lists for storing Data 3.5.1 Create And Display Contents of a Linked List 3.5.2 Inserting a Node into the List

3.6 An Array of Pointers to Objects 3.7 Pointers to Pointers 3.8 Debugging Pointers 3.9 Graphics IN C++ 3.10 Text Mode Graphics Functions 3.11 Graphics Mode Graphics Functions

3.11.1 Setting Up Graphics Mode 3.11.2 Position Functions 3.11.3 Drawing Shapes 3.11.4 Miscellaneous Functions 3.11.5 Filling Patterns 3.11.6 Cursor Control 3.11.7 Text Output 3.11.8 Clearing Graphics Screen 3.11.9 Ending Graphics Mode 3.11.10 Illustrates Some Graphics Functions

3.12 Inheritance in Graphics 3.12.1 Illustrates Inheritance In Graphics

3.13 Simulating Moving Objects 3.14 Using cout with Graphics 3.15 Exercise 3.16 Summary

Page 140: C++ infosystems 1

Introduction to OOP unit1

3.0 INTRODUCTION

The Stack class that was created in Unit 2 could be used with a specific type of

data, i.e. int. But if this class has to be used with any type of data, then the class

has to be generalized.

Pointer is variable that holds the address of a data item. Pointers are commonly

used in the following areas while programming:

♦ Accessing array elements.

♦ Passing arguments to a function when the function needs to modify the

original arguments.

♦ Passing arrays and strings to functions.

♦ Obtaining memory from the system – Dynamic memory allocation.

♦ Creating data structures such as linked lists.

C++ includes an extensive collection of graphics oriented library functions. Using these functions you can create an image on the screen. Graphics and OOP work together particularly well because objects can represent specific images, such as balls or text boxes. Graphics provides a visual way to see objects in action. Turbo C++ graphics functions fall into two categories:

♦ those that work in the text mode

♦ those that work in the graphics mode

The text mode graphic functions are concerned with placing the text in certain areas of the screen. The graphics – mode functions allow you to draw dots, lines, and shapes (like circles, rectangles, and ellipse etc.), add color to lines and areas, and perform many other graphics – related activities. Graphics mode functions require a graphics monitor and adapter card such as CGA, EGA or VGA.

Page 141: C++ infosystems 1

Introduction to OOP unit1

3.1 OBJECTIVES

♦ Create templates or Parameterized data types that defines a general class.

♦ Usage of Templates with different types of data.

♦ Understand pointers.

♦ Creating linked list for storing datas.

♦ Creating graphics images using Object Oriented techniques.

3.2 TEMPLATES

In the previous unit, you have created classes which includes variables of different data types as its private data members. For e.g.: Consider the stack class described in Unit 2 (see example 2.16). It has an array of integers as its private members to store values. It also has an integer variable top to keep track of the index. This stack has a disadvantage and that is, it can store only integer values. If you need a stack to store float or character data, you have to define a second class for float data and a third class for character data. If you could generalize the stack class, this difficulty would not arise. If the class stack is generalized, you can use it in many programs. So it would be helpful if you create a header file with this class. The header files have an extension of '.h'. E.g. iostream.h is a system defined header file containing the classes required for standard input and output. As you include iostream.h in any of our programs, you can also include the user defined header files in various programs. This is another example for the code reusability feature of C++.

The following example illustrates how to create a generalized stack without using

templates.

Here, the data type of the stack required is denoted by a variable name. In the

program, which requires the stack header file, the stack file is included after

Note : To include a user defined header file, you use " " instead of < > to specify the header file name.

E.g. # include "newhead.h" where newhead.h is a user defined header file.

Page 142: C++ infosystems 1

Introduction to OOP unit1

defining what the variable stands for. This can be done using the typedef

statement.

3.2.1 Example To Generalized Stack Header File

Create the file and save it under the name stack_h.h. (Do not compile this file)

# include <iostream.h>

# define MAX 10

class stack

{

private : D st[MAX]; int top;

public :

stack() { top = -1;}

void push (D var)

{ st[++top] = var; } D pop() { return(st[top--]); } }; In the above example, a header file is created for the class stack. When this file

is to be included in a program, the name of the file has to be enclosed in double

quotes. This signifies that the included header file is a user defined header file.

The following example uses the stack defined in example 3.1.1

3.2.2 Using The Stack Header File To Create Integer Stack

typedef int D; // Defining the data type of the stack. # include “stack_h.h” // Filename of the stack header

main()

Page 143: C++ infosystems 1

Introduction to OOP unit1

{

int s; stack s1;

s1.push(50); s1.push(60);

s = s1.pop(); cout << s;

}

The following example shows how to use the same header file to create a stack of characters. 3.2.3 Using The Stack Header File To Create Character Stack

typedef char D; // Defining the data type of the class # include “stack_h.h” // Filename of the stack header main() {

char s; stack s1;

s1.push(‘a’); s1.push(‘b’);

s = s1.pop(); cout << s;

}

So, from examples 3.1.2 and 3.1.3, it is evident that you can create a general stack class, which can be used in more than one program. This facilitates code reusability. (The above method can also be used in C programs.)

In C++ , you have a structure that defines such general classes. This structure is called 'template' or 'Parameterised data types'. The statement that declares such classes is

template <class T>

where template is a keyword , class indicates that a datatype is the parameter and T is the name given instead of the datatype for declaring

Note : The header file <iostream.h> has not been included in examples 1.2.2 and 1.2.3 because it has already been included in stack.h.

Page 144: C++ infosystems 1

Introduction to OOP unit1

the private variables of the class. If you have any other arguments it can be specified by using comma as the separator. After this statement you give the class specifier using the datatype as T. The template is stored in a separate header file to promote code reusability.

In the example given below, the statements # ifndef and # endif indicates to the compiler that if the file has already been compiled once, it is not necessary to do it again for the same program. 3.2.4 Creating Stack Header File Using Templates

Create this file and name it stack_h.h. Do not compile this file. # include <iostream.h> template <class T, int MAX> class stack { private : T st[MAX]; int top; // Since top is a index, it is always a integer. public : stack() { top = -1; } void push(T var) { st[++top] = var; } T pop() { return (st[top--]); } };

The following example illustrates how to use the declared template. 3.2.5 Using Templates To Create Stack

# include "stack_h.h" // Include header file.

main()

Note: T is the template defined. The parameters for the stack to be created has

to be passed to it when creating an object of the class. If the parameter is

a datatype then it is indicated by the word class. If the parameter is a

value of a particular data type then the data type is to be specified in the

template statement. E.g. integer for MAX in Example 3.1.4. The header

file has to be included in the program file and should not to be compiled

on its own.

Page 145: C++ infosystems 1

Introduction to OOP unit1

{ stack <int, 3> s1; // Declares a stack for maximum 3 integers.

stack <char, 5> s2; // Declares a stack for maximum 5 characters.

s1.push(50); s2.push(‘a’);

int x1 = s1.pop();

char x2 = s2.pop();

cout << x1 << x2 << endl;

} Note that in the above example you did not use the typedef statement to declare

the stack. Instead, you sent the datatype and the size as parameters

enclosed in < > when you declared a object of the class stack.

The following two examples give illustrate the use of templates. Here you will use inheritance in the header file. Two templates have been defined - one for the base class and the other for the derived class.

Writing the template for the base class follows the same procedure as the previous program. When this class derives another class, a separate template statement is to be written for the derived class as shown in the syntax below :

3.2.6 Inheritance Of Class Stack Using Templates

(create file named, stackt_h.h. Do not compile) # include <iostream.h>

const int MAX = 3;

template <class T>

template <arguments for derived class>

class derivedclass : public baseclass<values for arguments of baseclass>

{

// Class specification for derived class.

};

Page 146: C++ infosystems 1

Introduction to OOP unit1

class stack

{

protected :

T st[MAX]; int top;

public :

stack() {top = -1;}

void push(T var)

{st[++top] = var;}

T pop()

{ return st[top--];}

};

template <class X>

class stack1 : public stack<X>

{

public :

void push(X var)

{

if (top+1 < MAX) stack<X>::push(var);

else

cout<< "\n Error! Stack full!\n";

}

X pop()

{

if (top >= 0) stack<X>::pop();

else

cout << "\n Error! Stack Empty\n";

}

};

Page 147: C++ infosystems 1

Introduction to OOP unit1

To include the header file in our program, you have to give the statement #include “stackt_h.h” where stackt_h.h contains the specifier for class stack. The program, which uses the class stack defined in Example 3.1.6, is shown below. 3.2.7 Using The Class Stack

# include <conio.h>

# include "stackt_h.h" // Include the header file.

main()

{

stack1<char> s1;

stack1<int> s2;

char x; int x1;

clrscr();

s1.push('a'); s1.push('b'); s1.push('c');

s1.push('d'); // Gives Error as output

x = s1.pop(); cout << x << endl;

x = s1.pop(); cout << x << endl;

x = s1.pop(); cout << x << endl;

x= s1.pop(); // Gives Error as output

getch(); // Press any key to continue.

s2.push(50); s2.push(60); s2.push(70);

s2.push(80); // Gives Error as output

x1 = s2.pop(); cout << x1 << endl;

x1 = s2.pop(); cout << x1 << endl;

x1 = s2.pop(); cout << x1 << endl;

x1 = s2.pop(); // Gives Error as output

getch(); } // Press any key to continue.

Page 148: C++ infosystems 1

Introduction to OOP unit1

3.3 ADDRESSES AND POINTERS Every byte in the computer's memory has an address. Addresses are basically numbers that start at 0 and end at the highest address, which will vary according to the amount of memory available in the computer. For e.g. the highest address for 640K of memory is 65535. Note that the address of a variable is not the same as its contents. The address

is the memory location, which is used to store the variable contents. The

address of a variable can be got by using the address of (&) operator.

E.g. cout << &var1;

This statement prints the address of the variable var1. The output will be a number like 0x8f4ffff4, which is a hexadecimal number. Variables can also be defined as pointers in the program.

For e.g. int *p;

Here p is a pointer variable which stores an address of the location where the integer variable is stored. cout << p; //This statement prints the value in p which is a address.

cout << *p; //This statement prints the integer value stored in the location pointed to by the integer pointer p.

3.4 MEMORY MANAGEMENT IN C++

When an array is defined, the compiler sets aside memory for the array data. Arrays are a useful source of data storage, but they have a serious drawback because you have to know in advance how much data will be stored and declare an array of that size. This is because the compiler requires the array size to be a constant. In such cases you can define large arrays. But there will be wastage of space. To overcome this, C++ has two operators. They are ♦ new This operator allocates the memory.

♦ delete This operator deallocates the memory.

3.4.1 The New Operator

Page 149: C++ infosystems 1

Introduction to OOP unit1

This operator obtains memory from the operating system and returns a pointer to

its starting point.

The new operator has the same operation as the malloc function of C. But, this

operator is superior in that it returns a pointer to the appropriate data type, while

malloc’s pointer must be cast to the appropriate type.

3.4.2 The delete Operator

This operator deallocates the memory allocated to the pointer variable. If the

program reserves many chunks of memory using new operator, eventually all the

available memory will be reserved and the system will crash. To ensure safe and

efficient use of memory, the new operator is matched by a corresponding delete

operator that returns memory to the operating system.

Example 3.1 Illustrates both new and delete operators. # include <iostream.h>

# include <string.h >

void main()

{

char *str = “Education is the ability to meet life’s situations”;

int len = strlen(str);

char * ptr;

ptr = new char[len + 1]; // set aside memory : string + ‘\0’.

strcpy(ptr,str);

cout << endl << “ptr = “ << ptr;

delete ptr ; // release ptr’s memory.

}

In the above example the statement

Page 150: C++ infosystems 1

Introduction to OOP unit1

delete ptr;

returns to the system whatever memory was pointed to by ptr.

Deleting the memory does not delete the pointer that points to it and does not change the address value in the pointer. However, this address is no longer valid; the memory it points to may be now filled with something entirely different.

new AND delete OPERATORS IN CLASSES

The next example illustrates how to use the new and delete operators in classes.

The new operator is used in the constructor so that the memory is allocated

when the object is created. The delete operator is usually used in the destructor

to return the memory to the operating system when the object is destroyed.

Example 3.2 String Class Using new And delete Operators # include <iostream.h>

# include <string.h>

class string

{

private :

char * str;

public :

string (char *s)

{ int length = strlen(s);

str = new char[length + 1]; // Allocates memory to string.

strcpy(str, s);

}

~string()

{ delete str; // Deallocates the memory. }

void display()

{ cout << str; }

};

Page 151: C++ infosystems 1

Introduction to OOP unit1

void main() {

string s1 = “Manipal Institute of Computer Education.”;

cout << endl << “s1 = “; s1.display();

}

3.5 LINKED LISTS FOR STORING DATA

C++ has memory data structures like arrays, files and structure. Though these

allow for quite flexible storage, some applications may require the data to be

structured differently. This can be achieved using linked lists.

Data structures have two levels – the physical level and logical level.

At the physical level, the data structure is concerned with the actual storage

location of data and the relationship of the different data items.

At the logical level, the data structure is concerned with the defined data

relationships, their physical locations as such are not considered, i.e., the next

data to be read is maintained logically. A linked list is one such logical data

structure.

A linked list is a data structure such that there is one starting data item, and each

data item (including the start data) contains a pointer to the next data in

sequence. The last data item in the list stores a special value that marks the end

of the list. Each data item in the list is known as a node. The building block for a

linked list is the structure data type of C++.

The linked list provides a more flexible storage system in that it does not use

arrays at all. Instead, space for each data item is obtained as and when needed

with new and each item is connected or linked to the next data item using a

pointer. Hence, the individual items do not need to be located contiguously in

memory the way the array elements are; they can be scattered anywhere. It is

basically a chain of pointers. These are also called as non - linear lists.

The advantage of using a list is that,

Page 152: C++ infosystems 1

Introduction to OOP unit1

♦ We can preserve the logical order even though we have a random

physical order.

♦ Memory is used efficiently (optimum use of memory)

♦ New nodes can be inserted at any points.

♦ Any node can be deleted.

The following figure illustrates a list with 3 nodes.

The above picture represents a structure containing num (an int data) and *next (

a pointer to the next data item). Each data-pointer pair is a node of the linked list

or data list.

struct node {

int num;

struct node *next;

} *first;

In the above example, first is a pointer to a structure with two members, an integer num and a pointer next. To connect the pointer to the structure members, the arrow operator ( ->) is used. Example : first -> num

Creation of a linked list has been illustrated in example 3.4.1. The individual data

items, or links, are represented by structures of type link. Each structure contains

an integer - representing the object’s single data item - and a pointer to the next

link. The list itself stores a pointer to the link at the head of the list.

The linklist class has only one member data item : the pointer to the start of the

list. When the list is first entered, the constructor initializes this pointer, first, to

7FD2:0FC2 7FD2:0FC4 0

7 2 1 num

*next

7FD2:0FC2 7FD2:0FDE 7FD2:0FC4 Address

Page 153: C++ infosystems 1

Introduction to OOP unit1

NULL. The NULL constant is defined in the MEM.H header file (which is included

in the IOSTREAM.H file) to be 0. This value serves as a signal that a pointer

does not hold a valid address. In example 3.4.1 a link whose next number has a

value of NULL is assumed to be at the end of the list.

3.5.1 Create And Display Contents Of A Linked List

# include <iostream.h>

# include <conio.h>

struct node

{

int data;

node * next;

};

class linklist

{

private :

node* first; // Points to the first node in the list.

node* last; // Points to the last node in the list.

public :

linklist()

{

first = NULL;

}

void additem (int d); // Appends a node to the list.

void display(); // Displays the list contents.

};

Page 154: C++ infosystems 1

Introduction to OOP unit1

void linklist :: additem(int d) { node * newlink = new node; newlink-> data = d; newlink-> next = NULL; if (first == NULL) { first = newlink; last = first; } else { last -> next = newlink; last = newlink; } } void linklist :: display() { node* current = first; while (current != NULL) { cout << endl << current->data; current = current->next; } } void main() { linklist l1; clrscr(); l1.additem(25); l1.additem(36); l1.additem(49); l1.additem(64); l1.display(); getch(); }

Page 155: C++ infosystems 1

Introduction to OOP unit1

The function additem() adds an item to the linked list. A new node is inserted at

the end of the list. A new structure is created of type node by the statement

node * newlink = new node; This creates memory for the new node structure with new and saves the pointer

to it in the newlink variable. The structure is then inserted at the end of the list.

The function display() displays the contents of the list. A temporary variable is

used to traverse the list and simultaneously print the values on the screen until

you find a next that is NULL, denoting the end of the list.

Note: The link structure in example 3.4.1 contained a pointer to the same kind

of structure. This could also be done using classes as shown below,

Class c1

{

c1 *ptr;

};

However, while a class can contain a pointer to an object of its own

type, it cannot contain an object of its own type.

class c1

{ c1 obj; // Not allowed.

};

This is true of structures as well as classes.

Page 156: C++ infosystems 1

Introduction to OOP unit1

3.5.2 Example For Inserting A Node Into The List

// Link list class with INSERT interface

#include<iostream.h>

#include<conio.h>

struct list

{

int data;

list *next;

};

class linklist

{

private :

list *head;

list *last;

public:

linklist() { head=NULL;}

void additem(int d);

void insert();

list * search(int n);

void display();

void remove();

~linklist();

};

Page 157: C++ infosystems 1

Introduction to OOP unit1

// To add a new item to the list

void linklist :: additem(int d)

{

list *newitem = new list;

newitem -> data = d;

newitem -> next = NULL;

if (head==NULL)

{

head=newitem;

last=head;

}

else

{

last->next = newitem;

last=newitem;

}

}

// To display the entire list

void linklist :: display()

{

list *disp = head;

cout << endl<<"Contents of the list :" <<endl;

while (disp)

{

cout << " "<< disp->data;

disp=disp->next;

}

}

// To insert data into the list

void linklist :: insert()

Page 158: C++ infosystems 1

Introduction to OOP unit1

{

int n1,n2;

linklist::display();

cout << "\nEnter number before which to insert ";

cin >> n1;

cout << "Enter number to insert ";

cin >> n2;

if (head->data == n1) // Data at the head

{

list * newlink = new list;

newlink->data = n2;

newlink->next = head;

head=newlink;

}

else

{

list * temp=search(n1);

if (temp==NULL)

{

cout << "Number not found in the list ";

return;

}

list *newlink = new list;

newlink -> data = n2;

newlink -> next= temp->next;

temp->next = newlink;

}

}

// To search for a particular Data and return the address of the previous node

list * linklist :: search (int d)

{

Page 159: C++ infosystems 1

Introduction to OOP unit1

list *ptr=head;

while (ptr) {

if (ptr->next->data==d)

return ptr;

ptr=ptr->next;

}

return NULL;

}

void linklist::remove()

{

int r;

display();

cout << "\n Enter number to delete ";

cin >> r;

if (head->data==r)

{

list *temp = new list;

temp=head;

head=head->next;

delete temp; } else { list *temp=new list; temp=search(r); if (temp==NULL) { cout << "Number not found in the list "; return; }

Page 160: C++ infosystems 1

Introduction to OOP unit1

list *rem=temp->next; temp->next=temp->next->next; delete rem; } display(); }

// destructor linklist::~linklist() { list *temp,*hold; temp=head; while(temp != NULL) { hold = temp->next; delete temp; temp=hold; } } void main() { linklist l1; clrscr(); l1.additem(5); l1.additem(15); l1.additem(25); l1.additem(35); l1.display(); l1.insert(); l1.display(); l1.remove(); getch(); }

3.6 AN ARRAY OF POINTERS TO OBJECTS A common programming construction is an array of pointers to objects. This arrangement is more flexible than placing the objects themselves in an array. Example 3.3 An array of pointers to objects

Page 161: C++ infosystems 1

Introduction to OOP unit1

# include <iostream.h>

class person

{

protected: char name[40];

public: void setname(void) { cout<<"Enter name"; cin>>name; }

void printname(void) { cout<<"\n Name is :"<<name; }

};

void main(void)

{ person* persptr[100];

int n=0;

char choice;

do

{

persptr[n]=new person;

persptr[n]->setname();

n++;

cout<<"Enter another (y/n)?";

cin>>choice;

} while(choice=='y');

for(int j=0;j<n;j++) {

cout<<"\nPerson number"<<j+1;

persptr[j]->printname();

}

} // end of main

The main ( ) function defines an array, Persprt, of 100 pointers to type person. In

a do loop it then asks the user to enter a name. With this name it creates a

person object using new, and stores a pointer to this object in the array persptr.

Page 162: C++ infosystems 1

Introduction to OOP unit1

3.7 POINTERS TO POINTERS Your next example demonstrates an array of pointers to objects, and shows how

to sort these pointers based on data in the object. This involves the idea of

pointers to pointers.

Example 3.4 # include<iostream.h>

# include <string.h>

class person

{

protected: char name[40];

public: void setname(void) { cout<<"Enter name:";cin>>name; }

void printname(void) { cout<<"\n"<<name; }

char* getname() { return name; }

};

void main(void)

{

void bsort(person**, int);

person* persptr[100];

int n=0;

char choice;

do

{ persptr[n]=new person;

persptr[n]->setname();

n++;

cout<<"Enter another (y/n)?";

Page 163: C++ infosystems 1

Introduction to OOP unit1

cin>>choice;

} while(choice=='y');

cout<<"\nUnsorted list:";

for (int j=0;j<n;j++) { persptr[j]->printname(); }

bsort(persptr,n);

cout<<"\nSorted list";

for(j=0;j<n;j++) { persptr[j]->printname(); }

}

void bsort(person** pp,int n)

{

void order(person**,person**);

int j,k;

for (j=0;j<n-1;j++)

for (k=j+1;k<n;k++)

order(pp+j,pp+k);

}

void order(person** pp1,person** pp2)

{

if(strcmp((*pp1)->getname(),(*pp2)->getname())>0)

{

person* temp=*pp1;

*pp1=*pp2;

*pp2=temp;

}

}

Actually, when we sort person objects, we do not move the objects themselves; we move the pointers to the objects.

You will notice that the first argument to the bsort ( ) function, and both the arguments to order ( ) have the type person**. What do these two asterisks mean?. These arguments are used to pass the address of the array persptr, or – in the case of order ( ) – the addresses of the elements of the array. If this were an array of type person, then the address of the

Page 164: C++ infosystems 1

Introduction to OOP unit1

array would be type person* . However the array is of type pointers to person, or person* so its address is type person**. The address of a pointer is a pointer to a pointer.

3.8 DEBUGGING POINTERS

Pointers can be the source of mysterious or catastrophic program bugs. The most common problem is that the programmer has failed to place a valid address in a pointer variable. When this happens, the pointer can end up pointing anywhere in the memory. It could be pointing to the program code, or to the operating system. If the programmer then inserts a value into the memory using the pointer, the value will write over the program or operating instructions, and the computer will crash. Example:

gotoxy(1,10);

cout<<"speed"<<speed;

//Debugging pointers

int *intptr;

void main()

{

*intptr=37;

}

When intptr is defined it is given the value 0, since it is external. The single program statement will attempt to insert value 37 into the address at 0. However the runtime error – checking unit, built into the program by the compiler will display the message:’ Null pointer assignment’ indicating that you have failed to initialize a pointer properly. One way to localise the program is to set a Watch window on the contents of 0

address, waiting for any change in the value pointed to by 0. When it changes

you have found the offending program statement.

3.9 GRAPHICS IN C++

Graphics provide a visual way to see objects in action. Turbo C++ graphics functions fall into two categories:

Page 165: C++ infosystems 1

Introduction to OOP unit1

♦ those that work in the text mode

♦ those that work in the graphics mode

The text mode graphic functions are concerned with placing text in certain areas of the screen. The graphics-mode functions allow you to draw dots, lines, and shapes (like circles, rectangles, and ellipse etc.), add colour to lines and areas, and perform many other graphics-related activities.

3.10 TEXT - MODE GRAPHICS FUNCTIONS The text mode graphics functions need no preparation before use. You can start

using the functions without any prior initialization.

THE window ( ) FUNCTION This function takes four integer arguments that determine the left, top, right, bottom coordinates of the window. Text written by certain functions will appear inside the window, starting at the top left corner. Text too long for the width is automatically wrapped at the right edge. Text that goes beyond the bottom of the window causes the contents of the window to scroll upward. Syntax: window (int left, int top, int right, int bottom);

This function does not draw a border around the window, it only confines text to

a rectangular area. So, you cannot see the window unless you start typing in it,

The default coordinates for this function are the entire screen.

THE cputs( ) FUNCTION This function writes a string of text to a window. Syntax : cputs (string);

A peculiarity of cputs( ) is that it does not translate a newline character (‘\n’) into the carriage-return-plus-linefeed combination. This must be done by the user by inserting both a linefeed (represented by ‘\n’ character) and a carriage-return (represented by the ‘\r’ character) whenever you want to start a new-line. THE clrscr( ) FUNCTION

This function erases the text window. Syntax : clrscr( );

Page 166: C++ infosystems 1

Introduction to OOP unit1

When a window is not initialized, this function can be used to erase the entire screen. THE gotoxy( ) FUNCTION This library function positions the cursor within a text window. Since text is

usually written starting at the cursor position, this allows us to position text where

you want it.

Syntax : gotoxy (int x, int y);

where x is the column number

y is the row number

for the position where the text is to be placed on the screen.

THE putch( ) FUNCTION This library function displays a single character at the cursor position.

Syntax : putch(char ch);

Its parameter is the character to be displayed.

3.11 GRAPHICS - MODE GRAPHICS FUNCTIONS In graphics mode the basic element is a pixel. Pixel is a abbreviation for picture

element. The number of pixels (resolution) on the screen depends on the

hardware. Each pixel displays a single dot on the screen. Any pixel can be

suppressed or illuminated.

Graphics-mode programs use a completely different set of functions from text-

mode programs to put images on the screen. A graphics program must also

perform some preliminary work to set the appropriate graphics mode.

3.11.1 Setting Up Graphics Mode

detectgraph() FUNCTION

This function checks the system and returns two integer parameters : a value representing the system's graphics driver and a value for the recommended graphics mode if an adapter is installed. If a negative driver

Page 167: C++ infosystems 1

Introduction to OOP unit1

value is returned, it indicates the absence of a graphics adapter. The mode value is the highest resolution possible with that adapter. Syntax : detectgraph(int *driver, int *mode);

Example 3.5 Illustrates Detectgraph Function

# include <graphics.h>

# include <iostream.h>

main()

{

int g_dr, g_mode; detectgraph(&g_dr,&g_mode);

if (g_dr < 0) cout << "No graphics Adapter\n";

}

The function detectgraph can be called directly or indirectly. The function given above makes a direct call to the function. The constant DETECT makes an indirect call to the function. The above program could be rewritten as illustrated in Example 3.15.

Example 3.6 Illustrates Detect Constant

# include <graphics.h>

# include <iostream.h>

main()

{

int g_dr, g_mode;

g_dr = DETECT;

if (g_dr < 0) cout << "No graphics Adapter\n";

}

initgraph( ) FUNCTION

This library function must be executed before any other graphics mode functions can be used. This requires the GRAPHICS.H header file. Syntax : initgraph(int *driver, int *mode, char *path);

where *driver is the graphics driver, given by an integer.

Page 168: C++ infosystems 1

Introduction to OOP unit1

*mode is the graphics mode, given by an integer.

*path is a string indicating where the driver is available.

3.11.2 Position Functions

getmaxx() and getmaxy() FUNCTIONS

These functions return the maximum pixels in each row (number of columns) and each column (number of rows) of the screen. The values depend on the resolution of the screen. On a 640 X 200 resolution screen, getmaxx() returns 639 and getmaxy() returns 199.

Syntax : int getmaxx();

int getmaxy();

Example : int x = getmaxx();

int y = getmaxy();

getx() and gety() FUNCTIONS

The functions getx() and gety() return the current x and y coordinates.

Syntax : int getx();

int gety();

Example : int x = getx();

int y = gety();

3.11.3 Drawing Shapes

The functions described in this section, helps us to draw different shapes like

line, circle, etc. on the screen.

Note : The driver is a file with the extension BGI. Each type of hardware

requires a different driver. A null string (“”) indicates driver is in the

current directory.

Page 169: C++ infosystems 1

Introduction to OOP unit1

line() FUNCTION

This function is used to draw a line, it requires the starting coordinates and the ending coordinates of the line. Syntax : line(start_col, start_row, end_col, end_row)

Example : line(0, 0, getmaxx(), getmaxy() );

will draw a diagonal line from the top left corner to the bottom right corner.

circle() FUNCTION

This function requires three parameters - the x and the y values of the center and the radius. Syntax : circle(center_col, center_row, radius);

Example : circle(getmaxx()/2, getmaxy()/2, 50);

draws a circle at the center of the screen with a radius of 50 pixels. arc() FUNCTION

This function draws a circular arc using that specified center, start and end angles and radius. Syntax : arc(column, row, st_angle, end_angle, radius);

Example : arc(50,50,0,90, 50);

draws an arc of radius 50 with center at 50,50.

ellipse() FUNCTION

This function draws an ellipse or an elliptical arc using the specified center, start and end angles and horizontal and vertical radius. Syntax: ellipse(cen_col, cen_row, st_angle, end_angle, hor_rad, ver_rad);

Example : ellipse(50,50,0,90,50,20);

draws an ellipse of given dimensions with 50,50 as the center of the ellipse.

3.11.4 Miscellaneous Functions

setcolor() FUNCTION

This function sets the current drawing color. Syntax : setcolor(int color);

Example : setcolor(RED);

Page 170: C++ infosystems 1

Introduction to OOP unit1

circle(250,250,15);

will draw a circle with border red.

setlinestyle() FUNCTION

This sets the line width and style for drawing subsequent lines. Syntax : setlinestyle(linestyle, upattern, thickness);

where linestyle could be any one of the values in Table - 3.1

TABLE 3.1

VALUES OF LINESTYLE FOR SETLINESTYLE FUNCTION

Constant Value Draws a

SOLID_LINE 0 solid line

DOTTED_LINE 1 dotted line

CENTER_LINE 2 center line

DASHED_LINE 3 line of hyphens

USERBIT_LINE 4 user defined style upattern Should contain a sequence of on and off bits

representing a pattern for drawing the line. If linestyle is

not USERBIT_LINE the value of upattern is ignored.

thickness Could be NORM_WIDTH, value 1(normal width) or THICK_WIDTH, value 3 (three times as thick).

3.11.5 Filling Enclosed Regions

In this section, the functions useful for filling the shapes have been introduced. floodfill() FUNCTION

This function fills a bounded region with colour. Syntax : floodfill(column, row, border);

where column, row is a point inside the area to be filled,

border is the color of the border of the area to be filled.

setfillstyle() FUNCTION

Page 171: C++ infosystems 1

Introduction to OOP unit1

This function sets the fill pattern and color. Syntax : setfillstyle(pattern, color);

where pattern could be any of the values in Table 3.2

TABLE 3.2 VALUES FOR PATTERN OF SETFILLSTYLE FUNCTION

Constant Pattern Value

EMPTY_FILL Background colour 0

SOLID_FILL Foreground colour 1

LINE_FILL Horizontal lines 2

LTSLASH_FILL /// Pattern (Thin lines) 3

SLASH_FILL /// Pattern (Thick lines) 4

BKSLASH_FILL \\\ Pattern (Thick lines) 5

LTBKSLASH_FILL \\\ Pattern (Thin lines) 6

HATCH_FILL Light cross Hatch 7

XHATCH_FILL Heavy cross Hatch 8

INTERLEAVE_FILL Interleaving lines 9

WIDE_DOT_FILL Sparse dots 10

CLOSE_DOT_FILL Densely packed dots 11

USER_FILL User defined pattern 12

3.11.6 Cursor Control

moveto() FUNCTION

This function moves the cursor to the specified location in the graphics screen. Syntax: moveto(column, row);

Example: moveto(100,100);

positions the cursor at location 100,100 on the screen.

3.11.7 Text Output

Page 172: C++ infosystems 1

Introduction to OOP unit1

outtext() and outtextxy() FUNCTIONS

Both these functions are used to display text on the screen in the graphics mode. The function outtext() displays the text at current cursor position while the outtextxy() function positions the cursor and displays the given text. Syntax : outtext(text_string);

This function is usually used after the moveto() function.

Syntax : outtextxy(column, row, text_string);

Example : outtextxy(50,50,”MICE”); prints MICE at 50, 50.

settextstyle() FUNCTION

This function is used to specify the font, direction and character size to be used

for subsequent text output in graphics mode.

Syntax : settextstyle(font, direction, char_size);

where font can be any of the values from Table 3.3. All these fonts are read from special files, with extension .CHR, during run time.

TABLE 3.3 VALID FONT VALUES

Constant Value Displays DEFAULT_FONT 0 Letters in default font

TRIPLEX_FONT 1 Stroked triplex letters

SMALL_FONT 2 Stroked small letters

SANS_SERIF_FONT 3 Stroked sans serif letters

GOTHIC_FONT 4 Stroked gothic letters

direction can be any of the values from the table 3.4

TABLE 3.4

VALUES FOR DIRECTION

Constant Value Displays text HORIZ_DIR 0 horizontally, left aligned

VERT_DIR 1 vertically, top aligned

Page 173: C++ infosystems 1

Introduction to OOP unit1

char_size magnifies all stroked letters specified number of times (unless it is 0) i.e.

if char_size is 2, magnification is 2 times. Maximum magnification is 10.

settextjustify() FUNCTION

This function is used to change the default alignment of horizontal and vertical output. Syntax : settextjustify(horiz, vert);

where horiz can be any of the values from Table 3.5

TABLE 3.5

Constant Value Displays text LEFT_TEXT 0 Left Aligned (default)

CENTER_TEXT 1 Centered text

RIGHT_TEXT 2 Right Aligned text

vert can be any of the values from Table 3.6

TABLE 3.6

Constant Value Displays text BOTTOM_TEXT 0 Bottom Aligned CENTER_TEXT 1 Centered TOP_TEXT 2 Top Aligned (Default)

getmaxcolor() FUNCTION This function returns an integer to represent the maximum number of colours supported by the current driver. getpixel() and putpixel() FUNCTIONS

The getpixel() function returns an integer to represent the colour of the pixel at the co-ordinates specified. Syntax : getpixel(column, row);

Example : int i = getpixel(100, 100); stores in the variable i, the value of the

pixel representing its colour.

Page 174: C++ infosystems 1

Introduction to OOP unit1

The putpixel() function plots the pixel at the specified location.

Syntax : putpixel(column, row, colour);

Example : putpixel(100,100, RED); displays a red coloured point at 100,100.

3.11.8 Clearing Graphics Screen

cleardevice() FUNCTION

This function clears the graphics screen and positions the cursor at 0, 0. Syntax : cleardevice();

3.11.9 Ending Graphics Mode

closegraph() FUNCTION This function must be used when no more graphics routines are to be used. It releases the memory reserved by graphics system and restores the screen to the video mode that was active before initgraph(). Syntax : closegraph();

3.11.10 Illustrates Some Graphics Functions

# include <iostream.h>

# include <graphics.h>

main()

{

int g_dr, g_mode; int x,y;

g_dr = DETECT;

initgraph(&g_dr, &g_mode, "");

x = getmaxx()/2;

Page 175: C++ infosystems 1

Introduction to OOP unit1

y = getmaxy()/2;

setcolor(RED);

setlinestyle(SOLID_LINE, 0, NORM_WIDTH);

rectangle(0, 5, 635, 165); circle(x, y, 100);

setfillstyle(WIDE_DOT_FILL, 1); floodfill(50, 50, RED);

setfillstyle(SLASH_FILL, 3); floodfill(x,y,RED);

settextstyle(GOTHIC_FONT , HORIZ_DIR, 6);

outtextxy(50, 50, "HELLO!" );

settextstyle(SANS_SERIF_FONT, VERT_DIR, 5);

outtext("MICE");

getch();

cleardevice();

moveto(getmaxx()/2, getmaxy()/2);

settextjustify(CENTER_TEXT, CENTER_TEXT);

setcolor(YELLOW);

outtext("MANIPAL INSTITUTE OF COMPUTER EDUCATION");

getch();

closegraph();

}

3.12 INHERITANCE IN GRAPHICS This section illustrates inheritance in graphics. The program draws a triangle, rectangle and a circle by taking as input the center point coordinates and the radius. For the triangle and the rectangle the required points are calculated using the

input obtained.

The base class is set_para. This is used to set the parameters for the linestyle,

fillstyle etc. with which the figure is to be drawn. The classes circle1, rectangle1,

triangle1 etc. are all derived from setpara. These classes draw the respective

figure.

The problem has been solved in Example 3.11.1

Page 176: C++ infosystems 1

Introduction to OOP unit1

3.12.1 Example To Illustrates Inheritance In Graphics

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

int gd = DETECT,gm;

class set_para

{

private:

int color; //0..15 for

int fill_pattern; //0..12 setfillstyle

int line_width; //1&3 for

int line_style; //0..4 setting

int upat; //0&1 line style

public :

int xc, yc, radius;

void draw() {

setfillstyle(fill_pattern,color);

setlinestyle(line_style,upat,line_width);

}

set_para(int c,int fp,int lw,int ls,int up) {

xc = getmaxx()/2; yc = getmaxy()/2;

color = c; fill_pattern = fp;

line_width = lw; line_style = ls;

upat = up;

}

};

class triangle1 : public set_para

{

private:

Page 177: C++ infosystems 1

Introduction to OOP unit1

int pts[8];

public:

void tria(int r)

{

set_para::draw();

radius = r;

pts[0]=xc; pts[1]=yc-radius;

pts[2]=xc-radius; pts[3]=yc+radius;

pts[4]=xc+radius; pts[5]=yc+radius;

pts[6]=xc; pts[7]= yc-radius;

fillpoly(4,pts);

}

triangle1(int c,int fp,int lw,int ls,int up):set_para(c,fp,lw,ls,up)

{ }

};

class circle1 : public set_para

{

public:

void circl(int r) {

set_para::draw(); radius = r;

circle(xc,yc,radius); floodfill(xc,yc,getmaxcolor());

}

circle1(int c,int fp,int lw,int ls,int up):set_para(c,fp,lw,ls,up) {

}

};

class rectangle1 : public set_para

{

public :

void rect(int r) {

set_para::draw(); radius = r;

Page 178: C++ infosystems 1

Introduction to OOP unit1

rectangle(xc-radius, yc-radius, xc+radius, yc+radius);

floodfill(xc,yc,getmaxcolor());

}

rectangle1(int c,int fp,int lw,int ls,int up):set_para(c,fp,lw,ls,up) {

}

};

void main() {

initgraph(&gd,&gm,""); cleardevice();

setbkcolor(6);

rectangle1 r(6,9,1,0,1); r.rect(125);

circle1 c(7,9,1,1,0); c.circl(100);

triangle1 t(15,11,1,1,1); t.tria(80);

getch();

closegraph();

}

Setviewport The setviewport function sets the current viewport for graphics outputs.

The viewports arguments are given in absolute screen cordinates.

void setviewport(left, top, right, bottom, clip);

The clip argument is 0 or non-zero. If the value is non-zero all drawings will be

clipped to the current viewport.

Clearviewport

The clearviewport function clears the current viewport.

clearviewport();

Fillellipse

Fillellipse draws and fills an ellipse.

Page 179: C++ infosystems 1

Introduction to OOP unit1

Void fillellipse (int x, int y, int xradius, int yradius);

x,y - refer to the center of ellipse xradius - refers to the horizontal axis

yradius - refers to the vertical axis EXAMPLE 3.7

#include <graphics.h>

#include <conio.h>

#include <dos.h>

void plane(int x,int y) { line (x,y,x+10,y-3);

line (x+10,y-3,x+25,y-2);

line (x+25,y-2,x+29,y-7);

line (x+29,y-7,x+27,y);

line (x+27,y,x,y);

line (x+11,y-1,x+15,y-1);

}

main()

{

int gm,gd,i,w;

detectgraph(&gd,&gm);

initgraph(&gd,&gm,"");

setviewport(300,100,500,200,0);

setbkcolor(WHITE);

setfillstyle(SOLID_FILL,RED);

bar(0,0,200,100);

for(i=100;i+200 > 0;i = i-5)

{

delay(100);

setfillstyle(SOLID_FILL,RED);

bar(0,0,200,100);

setfillstyle(SOLID_FILL,YELLOW);

Page 180: C++ infosystems 1

Introduction to OOP unit1

fillellipse(88,3,12,9);

plane(i,10);

plane(i+15,30);

plane(i+50,13);

plane(i+70,70);

outtextxy(i,50,"Let us hope they are Birds and not war planes");

}

getch();

clearviewport(); closegraph();

}

3.13 simulating moving objects When connected with a graphics display, a whole world of Object – Oriented

animation opens up to the C++ programmer.

As a simple example. Let us make a class of molecules that can bounce around

in a closed container.

Member functions of molecule erase the molecule at its old position, calculate the new position, and draw the molecule at the new position. This is how the animation effect – an object moving on the screen – is achieved, by continually erasing and redrawing the object. Here’s the listing for MOLECULE. Example 3.8 Simulating moving objects # include <graphics.h>

# include <conio.h>

# include <stdio.h>

# include <stdlib.h>

const int RAD=5;

Page 181: C++ infosystems 1

Introduction to OOP unit1

const int MAX=6;

const int DIST=(RAD+MAX);

const int LEFT=0;

const int TOP=0;

const int RIGHT=639;

const int BOTTOM=479;

enum hdir { hSTOP=0,hRIGHT,hLEFT};

enum vdir { vSTOP=0,vDOWN,vUP};

class molecule

{

private: int xco,yco;

int oldx,oldy;

int speed;

hdir horz;

vdir vert;

COLORS color;

public:

molecule (int x,int y,int s,hdir h,vdir v,COLORS c)

{xco=x;yco=y;speed=s;horz=h;vert=v;color=c;}

void erase();

void calculate();

void draw();

};

void molecule::erase()

{

setcolor(DARKGRAY);

circle(oldx,oldy,RAD);

setfillstyle(SOLID_FILL,BLACK);

floodfill(oldx,oldy,DARKGRAY);

setcolor(BLACK);

circle(oldx,oldy,RAD);

Page 182: C++ infosystems 1

Introduction to OOP unit1

}

void molecule::calculate()

{

oldx=xco;

oldy=yco;

switch(horz)

{

case hSTOP:break;

case hRIGHT:xco +=speed;break;

case hLEFT:xco-=speed;break;

}

if (xco<=LEFT+DIST)

horz=hRIGHT;

else if (xco>=RIGHT-DIST)

horz=hLEFT;

switch(vert)

{

case vSTOP:break;

case vDOWN:yco+=speed;break;

case vUP:yco-=speed;break;

}

if(yco<=TOP+DIST)

vert=vDOWN;

else if(yco>=BOTTOM-DIST)

vert=vUP;

}

void molecule :: draw()

{

setcolor (color);

circle (xco,yco,RAD);

Page 183: C++ infosystems 1

Introduction to OOP unit1

setfillstyle(SOLID_FILL,color);

floodfill(xco,yco,color);

}

void main()

{

/* initialize graphics mode */

initgraph(&gdriver, &gmode, "\\tc3\\bgi");

errorcode = graphresult();

if (errorcode != grOk)

{

printf("Graphics error: %s\n", grapherrormsg(errorcode));

printf("Press any key to halt:");

getch();

exit(1);

}

molecule m1(100,120,2,hRIGHT,vUP,BLUE);

molecule m2(150,220,2,hLEFT,vUP,GREEN);

molecule m3(200,140,3,hRIGHT,vDOWN,CYAN);

molecule m4(250,240,3,hLEFT,vDOWN,RED);

molecule m5(300,160,3,hRIGHT,vUP,MAGENTA);

molecule m6(150,350,4,hLEFT,vUP,LIGHTGREEN);

molecule m7(150,350,4,hLEFT,vSTOP,LIGHTGRAY);

molecule m8(150,350,4,hSTOP,vUP,BROWN);

rectangle(LEFT,TOP,RIGHT,BOTTOM);

while(!kbhit() )

{

m1.calculate();m1.erase();m1.draw();

m2.calculate();m2.erase();m2.draw();

Page 184: C++ infosystems 1

Introduction to OOP unit1

m3.calculate();m3.erase();m3.draw();

m4.calculate();m4.erase();m4.draw();

m5.calculate();m5.erase();m5.draw();

m6.calculate();m6.erase();m6.draw();

m7.calculate();m7.erase();m7.draw();

m8.calculate();m8.erase();m8.draw();

}

closegraph();

}

A molecules’ direction has two components: x and y. To calculate its new position, you either add or subtract the speed to the x position, depending on the angle. You do the same for the y position. If either of these generations brings the molecule to the edge of the screen, we change the appropriate component of the direction, so that the molecule appears to bounce off the wall. To draw the molecule, you draw the outline of a circle and fill it with the same color. To erase it you draw over it with a dark gray circle, then fill it with black and erase it.

3.14 Using Cout With Graphics You can fall back on ordinary character – based output with Cout. This works in

graphics mode, and although the text appears rather crude in the graphics

environment, it does not provide a quick and dirty way to generate text output.

This approach is sometimes helpful in debugging, when you want to check the

values of variables but do not want to go to the trouble of using outtext ( ) or the

debugger.

3.15 EXERCISE 1. Create a template for arrays.

2. Create a template for singly linked list.

3. Create a class to create and display strings of a linked list.

4. Create a class for creating a double linked list.

Page 185: C++ infosystems 1

Introduction to OOP unit1

3.16 Summary Pointers are variables that hold address values. Pointers are defined using an asterisk (*). A data type is always included in pointer definitions, since the compiler must know what is being pointed to, so that it can perform arithmetic correctly on the pointer. The address operator & is used to store the address of a variable. You can access the thing pointed to using the asterisk in a different way, as the indirection operator, meaning contents of the variable pointed to by. Array elements can be accessed using pointer notation. Like other address, the

address of an array is a constant, which can be assigned to a variable, can be

incremented and changed in other ways.

The new operator obtains a specified amount of memory from the system and

returns a pointer to the memory. This operator is used to create variable and

data structures during program execution. The delete operator releases memory

obtained with new.

Classes and structures may contain data members that are pointers to their own

type. This permits the creation of complex data structures like linked lists.

Turbo C++ has 2 kinds of functions called graphics functions. The first works

only with text displays and is concerned with displaying text in a rectangular area

of the screen called a window. The key function in this mode is window(), which

defines the rectangular area.

The second kind of graphics function requires a graphics display. Programs that

uses these functions must initialize the display system to a graphics mode using

the initgraph() function, and terminates with the closegraph( ) function.

Library function can write lines, squares, and polygons on the screen, use

different line widths, and fill shapes with color. Text in a variety of fonts can be

displayed, and its size, color and positions can be manipulated.

ANSWERS FOR EXERCISE 3.15 1.

# include<iostream.h>

Page 186: C++ infosystems 1

Introduction to OOP unit1

const int MAX=5;

template<class t>

class array

{ protected : t arr[MAX];int i;

public :

array(){i=-1;}

void store(t var)

{ arr[++i]=var;}

void disp()

{ int k;

for (k=0;k<MAX;k++)

cout<<arr[k]<<endl;}

};

template <class x>

class array1 : public array<x>

{ public :

void store(x var)

{ if (i+1<MAX)

array<x>::store(var);

else

cout<<"\n error array full\n";

}

};

void main()

{

array1 <int> a1;

a1.store(10); a1.store(20); a1.store(30);

a1.disp();

Page 187: C++ infosystems 1

Introduction to OOP unit1

array1 <char> a2;

a2.store('a'); a2.store('b'); a2.disp();

}

2. #include <conio.h>

#include <iostream.h>

#define NULL 0

enum bool {FALSE,TRUE};

template <class T>

class Data

{

public :

virtual void setdata(T&) =0;

virtual T getdata() = 0;

};

class Link

{

Link *prev;

Link *next;

public:

Link() { next=NULL;prev=NULL;}

linkto(Link *l) { next=l; if (l) l->prev=this;}

Link * nextlink() {return next;}

Link * prevlink() {return prev;}

};

template <class T>

class Node : public Data<T>, public Link

{

private :

T data;

public :

Page 188: C++ infosystems 1

Introduction to OOP unit1

Node() :Link() {}

Node(T& val) {data = val;}

void setdata(T &dat) { data = dat;}

T getdata() { return data;}

};

template <class T>

class list

{

private : Node <T> *head;

Node <T> *tail;

public:

list() {head=tail=NULL;}

bool isempty() {if (head==NULL) return FALSE;

else return TRUE;

}

void display_list();

void add_data(T data) { Node <T> * temp= new Node<T>;

temp->setdata(data);

if (head==NULL)

{

head=tail=temp;}

else

{

tail->linkto(temp);

tail=temp;

}

}

};

Page 189: C++ infosystems 1

Introduction to OOP unit1

template <class T>

void list <T> :: display_list()

{

Node <T> *tmp= head;

cout << endl << "Data in the list ";

while (tmp)

{

cout << endl << tmp->getdata();

tmp=(Node <T> *) tmp->nextlink();

}

}

void main()

{

list <int> l1;

l1.add_data(100);

l1.add_data(200);

l1.add_data(300);

l1.add_data(300);

l1.add_data(300);

l1.display_list();

list <char> l2;

l2.add_data('z');

l2.add_data('j');

l2.add_data('k');

l2.add_data('v');

l2.add_data('b');

l2.display_list();

getch();

} 3. //strings of linked list

Page 190: C++ infosystems 1

Introduction to OOP unit1

# include<iostream.h>

# include<string.h>

# include <conio.h>

struct node

{ char name[20];

node *next;

};

class linklist

{ private : node *first;

node *last;

public : linklist(){first=NULL;}

void additem(char *s);

void display();

};

void linklist :: additem(char *s)

{ node *newline=new node;

strcpy(newline->name,s);

newline->next=NULL;

if (first==NULL)

{ first=newline;

last=first;

}

else

{ last->next=newline;

last=newline;

}

};

void linklist ::display()

{ node *current=first;

Page 191: C++ infosystems 1

Introduction to OOP unit1

while (current!=NULL)

{ cout<<endl<<current->name;

current=current->next;

}

}

void main()

{

linklist l1;

clrscr();

l1.additem("niki");

l1.additem("asha");

l1.additem("shaila");

l1.additem("usha");

l1.display();

getch();

}

4. //double linked list

#include <iostream.h>

struct node

{ int data;

node *next;

node *prev;

};

class linklist

{ private :

node *first;

Page 192: C++ infosystems 1

Introduction to OOP unit1

node *last;

public :

linklist()

{ first=NULL; }

void additem(int d);

void disp_forward();

void disp_backward();

};

void linklist ::additem(int d)

{ node *newlink=new node;

node *temp=new node;

newlink->data=d;

newlink->next=NULL;

if (first==NULL)

{ first=newlink;

first->prev=NULL;

last=first;

}

else

{ temp=newlink;

temp->prev=last;

last->next=temp;

last=newlink;

}

}

void linklist ::disp_forward()

{ node *current=first;

while(current!=NULL)

{ cout<<endl<<current->data;

Page 193: C++ infosystems 1

Introduction to OOP unit1

current=current->next;

}

}

void linklist ::disp_backward()

{ node *current=last;

while(current!=NULL)

{ cout<<endl<<current->data;

current=current->prev;

}

}

void main()

{

linklist l1;

l1.additem(10);

l1.additem(20);

l1.additem(30);

cout <<"Elements in forward direction"<<endl;

l1.disp_forward();

cout <<endl<<"Elements in backward direction"<<endl;

l1.disp_backward();

}

Page 194: C++ infosystems 1

Introduction to OOP unit1

UNIT 4 FILES & STREAMS,POLYMORPHISM & VIRTUAL FUNCTIONS Structure

4.0 Introduction 4.1 Objectives 4.2 Files And Streams

4.2.1 Stream Class Hierarchy

4.3 Files

4.4 Manipulating ASCII Files

4.4.1 Creating An ASCII String File

4.4.2 Reading An ASCII String File

4.4.3 Character Input/Output

4.4.4 Creating a File using put()

4.4.5 Creating a File using get()

4.4.6 Detecting End of File

4.5 The fstream Class

4.6 Manipulating binary Files

4.6.1 Creating a Student File

4.6.2 Displaying Student File

4.7 Positioning the stream pointer

4.7.1 Functions to Move the File Pointer

4.7.2 Illustrates seekg() function

4.8 Objects that Reads and writes themselves

4.9 The ios Flags

4.10 Friend Functions and Classes

4.10.1 Illustrates Friend Functions

4.10.2 Friend Classes

4.10.3 Exercise

4.10.4 Disadvantages of Friend Class/Functions

4.10.5 Advantages of Friend Functions

4.10.6 Example for Overload >> and << for Class Marks

Page 195: C++ infosystems 1

Introduction to OOP unit1

4.11 Command Line Parameters

4.11.1 Use of Command Line Parameters To Add Numbers given as

Command Line Parameters

4.12 Redirection in C++

4.12.1 Output Redirected to Printer

4.13 Polymorphism

4.14 The C++ Pointer Rule

4.15 Virtual Function

4.15.1 Illustrates Virtual Functions

4.16 Example to Demonstrate Polymorphism

4.17 Pure Virtual Functions and Abstract Class

4.17.1 Example for Virtual Functions in Graphics

4.18 Exception

4.18.1 Example for Exception

4.19 Exercise

4.20 Summary

4.0 INTRODUCTION

Most programs need to read and write data to disk files. In this unit you will learn

how to perform these activities using C++ streams. A stream is a general name

given to a flow of data. Different streams are used to represent different kinds of

data flow. Each stream is associated with a particular class, which contains

member functions and definitions for dealing with that particular kind of data flow.

Each file in C++ is an object of a particular stream class.

You can read and write to files using cout and cin. These predefined objects

normally represent the display and the keyboard, but they can be redirected by

the user to represent disk files. Redirection is a technique that allows the user

considerable flexibles in the way programs are used.

The concepts of encapsulation and data hiding ensure that nonmember

functions should not be able to access an object’s private or protected data i.e. if

Page 196: C++ infosystems 1

Introduction to OOP unit1

you are not a member, you cannot get it. But this can be achieved by using

friend functions.

Virtual means existing in effect but not in reality. A virtual function is one that

does not really exist but nevertheless appears real to some parts of a program.

Command line arguments are used when invoking a program for DOS. They are

used to pass the name of a data file to an application.

4.1 OBJECTIVES

At the end of this unit, you will be able to:

♦ Understand the stream class Hierarchy.

♦ Stores the contents into a data file.

♦ Retrieves the contents from a data file.

♦ How to use friend functions in a class.

♦ Pass arguments to a program from the operating system i.e. command line

arguments.

♦ Redirection in C++.

♦ Polymorphism and virtual functions.

4.2 STREAM

A Stream is a general name given to a flow of data. Each stream is associated

with a particular class, which contains member functions and definitions for

dealing with that particular kind of data flow.

4.2.1 Stream Class Hierarchy

The ios class is the base class. It contains many constants and member

functions common to input and output operations. E.g. showpoint and fixed flags

used for numeric output. The ios class derives two classes - istream and

ostream.

The istream class includes all functions for input of data. It includes member

functions like get(), getline(), read(). The overloaded extraction operator >> is a

Page 197: C++ infosystems 1

Introduction to OOP unit1

member of the istream class. The cin object, representing the standard input

stream, usually directed from the keyboard, is a predefined object of the

istream_withassign class, which is derived from the istream class.

The ostream class includes all functions for output of data. It includes member

functions like put(), putline() and write(). The overloaded insertion operator << is

a member of the ostream class. The cout object, representing the standard

output stream, usually directed to the video display, is a predefined object of the

ostream_withassign class, which is derived from the ostream class.

The iostream class is derived from both istream and ostream class by multiple

inheritance. The iostream_withassign class is derived from iostream class. The

<baseclass>_withassign classes add assignment perators to their base classes.

The classes used for input and output to the video display and keyboard are

declared in the header file iostream.h. The classes used for disk I/O are included

in the file fstream.h.

fstream.h incorporates iostream.h. Therefore, you need not explicitly open

iostream.h. The hierarchy of the classes included in the iostream and fstream

classes is shown in the form of a diagram.

Page 198: C++ infosystems 1

Introduction to OOP unit1

4.3 FILES

Files are of two types

♦ ASCII files

♦ binary files.

ASCII files are those files created by storing each character. They can also be

called as text files.

Binary files are those files created by storing a block of memory (array or

structure or class) . These are also called non-ASCII files.

ios pointer streambuf istream fstreambase ostream filebuf iostream ifstream fstream ofstream istream_withassign iostream_withassign ostream_withassign iostream.h fstream.h

Figure 4.1 : Stream Class Hierarchy.

Page 199: C++ infosystems 1

Introduction to OOP unit1

4.4 MANIPULATING ASCII FILES

To transfer a string to the file, you declare an object to be a member of the

ofstream class and initialize it to the filename that you want to use. This

initialization sets aside various resources for the file and accesses the file of that

name on the disk. You can use the insertion operator << to output text to the

file.

As in C, there is no need to open or close the file. This is automatically done by

the constructors and the destructors of the ostream class.

To see the text in the file you can display it with the DOS TYPE command or

open the file in any editor.

4.4.1 Example To Creating An Ascii String File

# include <fstream.h> void main() { ofstream outfile ("out.txt"); // Open file for output. outfile << "Creating an ASCII file" << endl; outfile << "C++ is said to be the superset of C" << endl; outfile << "We are using the Turbo C++ 3.0 Version" << endl; } To obtain a string to the file, you declare an object to be a member of the

ifstream class and initialize it to the filename that you want to use. To read a

string, you can use the istream member function getline(variable, length); This is

illustrated in the example given below.

4.4.2 Example For Reading An Ascii String File.

# include <fstream.h> void main() { const int max = 80; char buffer[80]; ifstream infile ("out.txt"); // Declare file for input. while (infile) // Check for End of File.

Page 200: C++ infosystems 1

Introduction to OOP unit1

{ infile.getline(buffer,max); cout << buffer; } }

4.4.3 Character Input /Output

To manipulate a file character by character, you use the member functions put()

for output to file or get() for input from file.

4.4.4 Example For Creating A File Using put()

# include <fstream.h> void main() { ofstream tstfile ("out.dat");

char text[ ] = "This is a text line"; int i=0;

while (text[i]) tstfile.put(text[i++]); }

4.4.5 Example For Reading A File Using get().

# include <fstream.h> void main() { ifstream tstfile ("out.dat");

char ch; int i=0; while (tstfile) { ch = tstfile.get( ); cout << ch; } } 4.4.6 Detecting End-Of-File

Page 201: C++ infosystems 1

Introduction to OOP unit1

The ifstream objects have values that can be tested for various error conditions.

If a condition is true, the object returns a zero value, otherwise it returns nonzero

value. One of these conditions is the end of file (EOF). The above program

checks for the end of file in a while loop.

4.6 THE FSTREAM CLASS

Till now, you created an object for either reading from or writing to the file. You

can also create a file for operating in more than one modes. The advantage of

using more than one mode is that you can read and write from the file without

having to close and open the file each time in either read or write mode.

If you want to use the file for both input and output simultaneously, you declare

the a stream to be an object of fstream class. To associate the file with the

stream, you have to open the file using the open() member function in the

required modes.

In the open() function you include several mode bits to specify certain aspects of

the file object you are opening. The options are given in the table.

TABLE 4.1 - MODES FOR OPENING FILES

DESCRIPTION in Open for reading (default for ifstream).

out Open for writing (default for ofstream).

app start reading or writing at the end of the file (append).

ate erase file before reading or writing (truncate).

nocreate error when opening if file does not already exist.

noreplace error when opening for output if file already exists, unless ate or app is set.

binary open file in binary (not text) mode.

Page 202: C++ infosystems 1

Introduction to OOP unit1

E.g. open("data.dat",ios::in | ios::out | ios::app);

will open the file, data.dat for input or output or append modes. The in and out

modes are included because you want to use the file for both reading and

writing. The app mode is used to retain the previous contents of the file.

The vertical bar between the flags cause the bits representing these flags to be

ORed together bitwise, so that several flags can apply simultaneously.

After opening the file, the necessary manipulations can be done. Finally, the file

has to be closed using the close() member function.

4.6 MANIPULATING BINARY FILES

The binary files can be used to store or retrieve objects to and from the file.

To write to the file, you use the function, write() which takes two arguments - a

pointer to the block and the size of the block.

Similarly to get the contents from the file, you use the function, read() which

takes two arguments - a pointer to the block and the size of the block.

The following example creates a student file by declaring an object of fstream

class. Though the file can be opened in many modes, in the following two

examples, it has been opened in only one mode (read [in] / write [out] ).

The examples also illustrate the read () and write() member functions which are

usually used for transfer of data block from and to the file.

4.6.1 Example For Creating A Student File

# include <fstream.h> class student { private : int rno; char name[10]; float fees; public : void getdata() { cout << "Roll Number: "; cin >> rno; cout << endl << "name :"; cin.get(); cin >> name; cout << endl << "fees :"; cin >> fees;

Page 203: C++ infosystems 1

Introduction to OOP unit1

} void dispdata() { cout << "Roll Number = " << rno <<endl; cout << "Name = " << name << endl; cout << "Fees = " << fees << endl; } }; void main() { student s1; fstream stdfile; stdfile.open ("std.dat", ios::out|ios::binary); // Open file for output. char wish; // Writing to the file. do { s1.getdata(); stdfile.write( (char *)&s1, sizeof(student)); cout << "Continue ? y/n"; cin >> wish; } while (wish == 'y' || wish == 'Y'); stdfile.close(); // Close the file. }

4.6.2 Example For Displaying A Student File

# include <fstream.h> class student { private : int rno; char name[10]; float fees; public : void getdata() { cout << "Roll Number: "; cin >> rno; cout << endl << "name :"; cin.get(); cin >> name; cout << endl << "fees :"; cin >> fees; }

Page 204: C++ infosystems 1

Introduction to OOP unit1

void dispdata() { cout << "Roll Number = " << rno <<endl; cout << "Name = " << name << endl; cout << "Fees = " << fees << endl; } }; void main() { student s1; fstream stdfile;

stdfile.open("std.dat",ios::in|ios::binary); stdfile.read( (char *)&s1,sizeof(student)); while (stdfile) { s1.dispdata(); stdfile.read( (char *)&s1,sizeof(student)); } stdfile.close(); }

4.7 POSITIONING FILE POINTERS

When you can open a file in more than one mode using the fstream class, it is

not necessary to close the file and open it again when you need to switch from

one mode to the other. But if you are writing and reading in different positions of

the file then, the stream pointers have to be positioned appropriately.

Each file object has associated with it two integer values called the get pointer

and the put pointer. These are also called the current get position and the

current put position, or simply the current position. These values specify the byte

number in the file where reading or writing will take place.

4.7.1 Functions To Move The File Pointer

seekg( ) and seekp( )

seekg () - for get pointer

seekp () - for put pointer

Page 205: C++ infosystems 1

Introduction to OOP unit1

These functions take two arguments.

The first argument is the relative offset i.e. the number of bytes the file pointer

has to be moved. (+ for forward and - for backward. )

The second argument is the position of the file pointer from where the offset is to

be considered. The default argument for this is the beg (beginning of the file). It

can take values ios::beg (beginning), ios::end (end of file), and ios::cur (current

pointer position).

E.g. : seekg(-5, ios::end); moves the get pointer 5 bytes backward from the end

of the file.

THE tellg () or tellp() FUNCTION

These functions return the current position of the get or put pointer in bytes.

The following example illustrates the use of seekg() function. The seekp()

function is also used in a similar manner whenever necessary.

4.7.2 Example To Illustrate seekg() Function

# include <fstream.h> # include <io.h> # include <string.h> class student { private : int rno; char name[10]; float fees; public : void getdata() { cout << "Roll Number: "; cin >> rno; cin.get(); cout << endl << "name :"; cin >> name; cout << endl << "fees :"; cin >> fees; } void dispdata() { cout << "Roll Number = " << rno <<endl; cout << "Name = " << name << endl; cout << "Fees = " << fees << endl; } };

Page 206: C++ infosystems 1

Introduction to OOP unit1

void main() { student s1; fstream stdfile; char wish; stdfile.open ("std.dat",ios::app | ios::out | ios::in|ios::binary); do // Writing to the file. { s1.getdata(); stdfile.write( (char *)&s1, sizeof(student)); cout << "continue ? ( y / n )" << endl; cin >> wish; }while (wish == 'y' || wish== 'Y');

stdfile.seekg (0); // moves the file pointer to beginning of the file. stdfile.read( (char *)&s1,sizeof(student)); while (!stdfile.eof()) // Reading from file. { s1.dispdata(); stdfile.read( (char *)&s1,sizeof(student)); } stdfile.close(); }

4.8 OBJECTS THAT READ AND WRITE THEMSELVES

Sometimes it makes sense to let each member of a class read and write itself to

a file. In this example you can add member functions – diskout ( ) and diskin ( ) –

to the person class. These functions allow a person object to write itself to a disk

and read itself back in.

Page 207: C++ infosystems 1

Introduction to OOP unit1

4.8.1 Example For Objects that Read and Write Themselves

# include<fstream.h> class person { protected: char name[40]; int age; public: void getdata(void) { cout<<"\nEnter name";cin>>name; cout<<"\nEnter age";cin>>age; } void showdata(void) { cout<<"\nName:"<<name; cout<<"\nAge:"<<age; } }; void main(void) { person pers;char ch; fstream infile; infile.open("Person.dat",ios::binary|ios::out|ios::in); do { cout<<"\nEnter persons data"; pers.getdata(); infile.write((char*)&pers,sizeof(pers)); cout<<"\nEnter another person(y/n)"; cin>>ch; } while(ch=='y'); infile.seekg(0,ios::end); int endposition=infile.tellg(); int n=endposition/sizeof(person); cout<<"\nThere are"<<n<<"persons in file";

Page 208: C++ infosystems 1

Introduction to OOP unit1

cout<<"\nEnter person number"; cin>>n; int position=(n-1)*sizeof(person); infile.seekg(position); infile.read((char*)&pers,sizeof(pers)); pers.showdata(); }

4.9 THE ios FLAGS

Till now, you have been using the ios flags for various reasons like formatting

decimal output, setting the appropriate flags and so on. A list of all the flags and

its use is given in the table below :

TABLE 4.2

THE ios FLAGS

Flag Purpose skipws Skip whitespace on input. left Left - justify output. right Right - justify output. internal Use padding after sign or base indicator. dec Decimal Conversion. oct Octal Conversion. hex Hexadecimal Conversion. showbase Use base indicator on output. showpoint Use decimal point in floating - point output.. uppercase Uppercase hex output. showpos Preface positive integers with '+'. scientific Floating - point notation with E (E.g. : 6.4575E2). fixed Fixed floating - point notation (645.75). unitbuf Flush all streams after insertion. stdio Flush stdout and stderr after insertion.

4.10 FRIEND FUNCTIONS AND CLASSES

These are used when you want to override the security provided by the classes.

Page 209: C++ infosystems 1

Introduction to OOP unit1

For e.g. When the data of two objects is to be added and they are members of

different classes, the addition function cannot be an individual member function

of either class because it must be possible to access the private members of

both the classes. You can then declare a function to be a friend of both the

classes and use it to do the necessary calculations.

When a class B is declared to be a friend of another class A then, the members

of class A (private and public) can be accessed withi class B.

♦ The friend function can be declared anywhere, that is, as private or as public.

It is not governed by the access specifiers.

♦ Friend functions are not transitive. That is, if X is a friend of Y and Y is a

friend of Z, it does not imply that X is a friend of Z.

♦ Friendship, however, can be inherited.

4.10.1 Example To Illustrates Friend Functions

# include <iostream.h> class newclass; // Forward declaration.

class myclass { private : int mydata; public : myclass( ) { mydata = 0; } myclass (int n ) { mydata = n; } friend int addclass (myclass, newclass); // Friend Function. };

class newclass { private : int newdata; public : newclass ( ) {newdata = 0; } newclass (int n ) { newdata = n; } friend int addclass (myclass, newclass); };

int addclass (myclass mc, newclass nc) {

Page 210: C++ infosystems 1

Introduction to OOP unit1

int tot; tot = mc.mydata + nc.newdata; return (tot); }

void main( ) { myclass m1(100); newclass n1(200); cout << "\nThe sum of the data of the two classes is " << addclass(m1,n1); } 4.10.2 Friend Classes

The member functions of a class can all be made friends at the same time when

you make the entire class a friend.

4.10.3 Example of Friend Classes

# include<iostream.h> class alpha { private: int data1; public: alpha(){ data1=99; } friend class beta; }; class beta { public: void func1(alpha a) {cout<<"\ndata1:"<<a.data1;} void func2(alpha a) {cout<<"\ndata1:"<<a.data1;} void func3(alpha a) {cout<<"\ndata1:"<<a.data1;} }; void main() { alpha a; beta b; b.func1(a); b.func2(a);

Page 211: C++ infosystems 1

Introduction to OOP unit1

b.func3(a); }

In the alpha the entire class beta is proclaimed a friend. Now all the member

functions of beta can access the private data of alpha.

4.10.4 Disadvantage Of Friend Class/Functions

The aim of using object oriented programming is to protect the data members

from accidental or deliberate modifications. The data is to be accessed only

through the member functions of that class. By declaring a friend, the private

variables can be accessed by the friend which defeats the purpose of OOP.

4.10.5 Advantage Of Friend Functions

The istream and ostream classes overload the >> and << operators for system

defined data types. These overloaded functions can be used in any user defined

class to give a better interface to the data type defined. To overload >> and <<

for any userdefined data type, the functions have to be declared as a friend of

the user defined class.

This creates similarity between the objects of system defined data types and

user-defined data types, i.e. user-defined objects can be input or output using

the cin or cout statements without a member function in that class.

Note : The prototype of the overloaded >> operator in the istream class is as follows :

istream& operator >> (istream& , datatype& );

The prototype of the overloaded << operator in the ostream class is as follows :

ostream& operator << (ostream& , datatype& ); The following example illustrates how to overload >> and << operators for the

class marks.

4.10.6 Example For Overloaded >> And << For Class Marks

# include <iostream.h> class marks {

Page 212: C++ infosystems 1

Introduction to OOP unit1

private : int roll; int mks;

public : marks( ) // Default Constructor { roll = -1; mks = 0; } marks( int m, int n) // Overloaded Constructor { roll = m; mks = n; }

friend ostream& operator << (ostream& ostrm, marks& m);

friend istream& operator >> (istream& istrm, marks& m); };

ostream& operator << (ostream& ostrm, marks& m) { ostrm <<endl << "Roll No : " << m.roll << endl << "Marks : " << m.mks; return ostrm; }

istream& operator >> (istream& istrm, marks& m) { cout << endl << "Enter Roll number : " ; istrm >> m.roll; cout << endl << "Enter marks : "; istrm >> m.mks; return istrm; } void main( ) { marks m1; cin >> m1; // input is done using the friend function cout << endl << "The record is ......."; cout << m1; // output is done using friend function }

4.11 COMMAND - LINE ARGUMENTS

The arguments that are passed to a program from the operating system along

with a command as it begins to execute are known as command - line

arguments.

The exe version of any program can be used like a command to execute the

program at the command line. To receive the command - line arguments,

usually two parameters are passed.

Page 213: C++ infosystems 1

Introduction to OOP unit1

The two command line parameters used by a C++ program are argc (argument

count) and argv (argument value). The argc is an integer which is the number of

words in the command. The argv is an array of character pointers which stores

the words in the command.

E.g. copy file1 file2

For this DOS command,

argc = 3. argv[0] = "copy" argv[1] = "file1" argv[2] = "file2"

4.11.1 EXAMPLE FOR USE OF COMMAND LINE PARAMETERS TO

ADD NUMBERS GIVEN AS COMMAND - LINE PARAMETERS.

// add.cpp - program file. # include <iostream.h> # include <stdlib.h> # include <process.h> void main(int argc, char *argv[ ]) { int i, sum = 0; if (argc < 3) { cout << "Enter atleast two integers to add "; exit (-1); } else { for (i = 1; i < argc; I++) sum = sum + atoi (argv[ i ]); cout << "Sum of the numbers is : " << sum << endl; } } Note : This program can be executed at the DOS prompt as :

A > add 10 20 30 40 50

where 'add' is the name of the file where the program is typed.

Output

Sum of the numbers is : 150

A>

To go to the DOS prompt directly from the compiler choose File, DOS

Shell option. After executing the program, type exit at the DOS prompt to

return to the compiler.

Page 214: C++ infosystems 1

Introduction to OOP unit1

A second method to execute any C++ program having command line

arguments is as follows :

In the Run menu of the compiler, there is an option for Arguments. When

the option is chosen, type the arguments in the box provided. (Do not write

the filename in the box.) The program can then be executed in the usual

manner without having to go to the DOS prompt.

4.12 REDIRECTION IN C++

Redirection is a technique, that allows the user considerable flexibility in the way

the programs are used. Output from a program is normally to the standard

output file and this output can be redirected to a secondary storage file or to the

printer. Similarly, input redirection can be used to read data from a secondary

storage file instead of the standard input file, the keyboard.

The following example implements the DOS TYPE command with the output

being redirected to the printer.

Note :The type command is used to display the contents of any ASCII file. To

redirect the output to the printer, the command would be

type filename > prn To implement this using C++, open an object of ostream for printer.

4.12.1 Example For Output Redirected To Printer.

// Filename : outprn.cpp # include <fstream.h> # include <process.h> void main( int argc, char *argv[ ]) { if (argc <= 1) { cerr << "Enter a file name"; exit(-1); } ifstream infile(argv[1]);

Page 215: C++ infosystems 1

Introduction to OOP unit1

if (!infile) { cerr << endl << "Cannot open file " << argv[1]; exit(-1); }

char ch;

ostream outfile;

outfile.open("PRN"); // open file for printer. while (infile) { infile.get(ch); outfile << ch; } outfile.close(); } To execute this program at the DOS prompt, you can use the command,

A > outprn out.txt

outprn - name of the C++ program file.

out.txt - file to be printed.

4.13 POLYMORPHISM

Polymorphism means "many forms". In C++, the meaning of polymorphism is

the ability to access different implementations of a function using the same

name.

There are two levels at which polymorphism operates. Compile-time

polymorphism and run-time polymorphism. Compile-time polymorphism has

already been demonstrated through operator overloading and function

overloading. Both are a subtle form of polymorphism since in both cases a

single entity is used to refer to two or more things.

Page 216: C++ infosystems 1

Introduction to OOP unit1

Run-time polymorphism is based on virtual functions, derived classes and base

class pointers.

4.14 THE C++ POINTER RULE.

The rule as given in C++ terms is as follows. A Pointer declared as pointing to

base class can be used to point to an object of a derived class of that base

class, but a pointer to a derived class cannot be used to point to an object of the

base class or to any of the derived classes of the base class.

In the program given below, there is a base class named, vehicle. You are

allowed to declare a pointer to the vehicle class which is the base class and use

that pointer to refer to object of either the base class or any of the derived

classes.

This is exactly what you do in the main program. You declare a single pointer

which points to the vehicle class and use it to point to objects of each of the

classes - car, truck and boat.

4.15 VIRTUAL FUNCTION

Virtual functions are functions which are declared with the key word virtual in the

base class.

Example,

virtual void dispdata() { cout << " This is the base class";}

These virtual functions may or may not be implemented again in the derived

classes. If it is implemented, the declaration must be identical to that of the base

class except for the word, virtual.

void dispdata() { cout << "Roll number "<< roll; }

Below is an example program with a virtual function and exhibits dynamic binding

or polymorphism as it is called.

4.15.1 Example to Illustrate Virtual Function

Page 217: C++ infosystems 1

Introduction to OOP unit1

#include <iostream.h> class vehicle { protected : int wheels; float weight; public : virtual void message(void) { cout << "Vehicle message\n "; } };

class car : public vehicle { int passenger_load; public : void message(void ) { cout << "Car message\n";} };

class truck : public vehicle { int passenger_load; float payload; public : int passengers(void) { return passenger_load;} }; class boat : public vehicle { int passenger_load; public : int passengers(void) { return passenger_load;} void message( void) { cout << "Boat message\n ";} };

main() { vehicle *vc; vc =new vehicle; vc � message () ; vc=new car; vc � message () ;

Page 218: C++ infosystems 1

Introduction to OOP unit1

vc=new truck; vc � message () ; vc=new boat; vc � message () ; delete vc; } The output will be,

Vehicle message

Car message

Vehicle message

boat message

Note : The keyword virtual only appears in the base class. All classes that

derive this class will have the corresponding method automatically

declared virtual by the system.

Since the method named message() is declared to be virtual method in its

declaration in the base class, anytime you refer to this method with a pointer to

the base class, you actually execute the method associated with one of the

derived classes if there is a method available in the derived class and if the

pointer is actually pointing to that derived class.

1. The decision of which method to call is not made during the time when the

code is compiled, but, when the code is executed. This dynamic binding and

can be very useful in some programming situations. In fact , there are only

three different calls made, because the class named truck does not have a

method message(), so the system simply uses the method from the base

class to satisfy the message passed. For this reason a virtual function must

have an implementation available in the base class which will be used if there

is not one available in one or more of the derived classes.

2. The structure of the virtual function in the base class and each of the derived

classes is identical. The return type and the number and the types of the

Page 219: C++ infosystems 1

Introduction to OOP unit1

parameters must be identical for all, since a single statement can be used to

call any one of them.

3. If the keyword VIRTUAL is used the system will use late binding, which is

done at runtime, but if the keyword is not included, early binding will be

used. What these words actually mean is that with late binding the compiler

does not know which method will actually respond to the message because

the type of the pointer is not known at compile time. With early binding ,

however, the compiler decides at compile time, what method will respond to

the message sent to the pointer.

4.16 EXAMPLE TO DEMOSTRATE POLYMORPHISM

A class named, mice, keeps track of the products being sold and added to stock.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream.h> #include <conio.h> // Base class Product class product { protected : char *name; public : product() { name = NULL;} product(char *n) { name=strdup(n);} ~product() {delete name;} virtual void which_product() { cout << "Just a product";} }; class soap : public product { public : soap() : product() {} soap(char *n) : product (n) {} void which_product() { cout << "Soap named "<<name;} };

Page 220: C++ infosystems 1

Introduction to OOP unit1

class paste : public product { public : paste() : product() {} paste(char *n) : product (n) {} void which_product() { cout << "Tothpaste named "<<name;} };

class mice { private : int maxproducts; int nowproducts; product **stock; public: mice(int n); ~mice(); int accept(product *d); product* sell(int n); void listproducts(); }; // Constructor mice :: mice(int n) { maxproducts=n; nowproducts=0;

stock = new product *[maxproducts];

for (int i=0;i < maxproducts; ++i) stock[i]=NULL; }

// Destructor mice :: ~mice() { delete stock; }

// ACCEPT member function int mice :: accept(product *d)

Page 221: C++ infosystems 1

Introduction to OOP unit1

{ if (nowproducts==maxproducts) return 0; ++nowproducts; int i=0;

while (stock[i] != NULL) ++i; stock[i]=d; return i+1; }

// SELL member function product* mice :: sell(int n) { if (n > nowproducts) return NULL; --n; if (stock[n] != NULL) { product *temp=stock[n]; stock[n]=NULL; --nowproducts; return temp; } else return NULL; }

// LISTPRODUCTS member function void mice :: listproducts() { if (nowproducts==0) return; for (int i=0;i<nowproducts;++i) {

Page 222: C++ infosystems 1

Introduction to OOP unit1

if (stock[i]==NULL) continue;

cout << "\n Product " << i <<" "; stock[i]->which_product(); } }

void main() { clrscr(); mice m(10); soap s1("rexona"); soap s2("lux"); soap s3("lifebuoy"); paste p1("colgate"); paste p2("close-up"); m.accept(&s1); m.accept(&s2); m.accept(&s3); m.accept(&p1); m.accept(&p2); product *p =m.sell(2); cout << "Product sold :"; p->which_product(); m.listproducts(); getch(); } Output will be :

Product sold : soap named Lux.

And a list of the other products.

4.17 PURE VIRTUAL FUNCTIONS AND ABSTRACT CLASSES

A class that contains a pure virtual function is called an abstract class. Objects

of an abstract class cannot be defined but they are used to derive child classes.

A pointer to abstract class can be defined.

Page 223: C++ infosystems 1

Introduction to OOP unit1

A pure virtual function is one, which is declared with the keyword virtual and

initialized to 0. That is, there in no implementation of the function. The functions

will be implemented in the derived classes.

virtual void showdata() = 0;

Pure virtual functions must be implemented or declared in the derived classes.

Pure Virtual Function

A pure virtual function is a virtual function with no body. In the notation =0, the

equal sign has nothing to do with assignment; the value 0 is assigned to

anything. The =0 syntax is simply how we tell the compiler that a function will be

pure – that is, have no body.

4.17.1 Example for Virtual Functions in a Graphics

In main ( ), you setup an array, ptrarr, of pointers to shapes. Next we create

three objects, one of each class, and place their addresses in an array. Now it is

easy to draw all 3 shapes. The statement ptrarr [ j ] draw ( ); does all this as the

loop variable j changes.This is a powerful approach to combining graphics

elements, especially when a large number of objects need to be grouped

together and drawn as a unit.

# include<graphics.h> # include<conio.h> const int w=50; class shape { protected: int xco,yco; int linecolor; int fillcolor; public: shape() { xco=0;yco=0;linecolor=WHITE;fillcolor=WHITE;} void set(int x,int y,int lc,int fc)

Page 224: C++ infosystems 1

Introduction to OOP unit1

{ xco=x;yco=y;linecolor=lc;fillcolor=fc;} void colorize() { setcolor(linecolor); setlinestyle(SOLID_LINE,0,THICK_WIDTH); setfillstyle(SOLID_FILL,fillcolor); } virtual void draw()=0; }; class ball:public shape { public: ball(): shape() {} void set(int x,int y,int lc,int fc) { shape::set(x,y,lc,fc); } void draw() { shape::colorize(); circle(xco,yco,w); floodfill(xco,yco,linecolor); } }; class rect:public shape { public: rect():shape() {} void set(int x,int y,int lc,int fc) { shape::set(x,y,lc,fc); } void draw() { shape::colorize(); rectangle(xco-w,yco-w,xco+w,yco+w); floodfill(xco,yco,linecolor);

Page 225: C++ infosystems 1

Introduction to OOP unit1

moveto(xco-w,yco+w); lineto(xco+w,yco-w); } }; class tria:public shape { public: tria():shape() {} void set(int x,int y,int lc,int fc) { shape::set(x,y,lc,fc); } void draw() { shape::colorize(); int triarray[]={xco,yco-w, xco+w,yco+w, xco-w,yco+w}; fillpoly(3,triarray); } }; void main() { int driver,mode; driver=DETECT; initgraph(&driver,&mode,"x:\tc3\bgi"); shape* ptrarr[3]; ball b1; rect r1; tria t1; b1.set(100,100,WHITE,BLUE); r1.set(100,200,WHITE,RED); t1.set(100,300,WHITE,GREEN); ptrarr[0]=&b1; ptrarr[1]=&r1; ptrarr[2]=&t1; for (int j=0;j<3;j++)

Page 226: C++ infosystems 1

Introduction to OOP unit1

ptrarr[j]->draw(); getche(); closegraph(); }

4.18 EXCEPTIONS

Exceptions provide a systematic, object – oriented approach to handling runtime

errors generated by C++ classes. For example a constructor in a user – written

string class might generate an exception if the application tries to initialize an

object with a string that is too long.

Not all errors can be handled by exception. For example, some errors are

detected, not by the program but by the OS, which then terminates the

application.

When exceptions are used, this is called ‘throwing an exception’. In the

application we install a separate section of code to handle the error. This is

called ‘Exception handler’ or ‘catch block’. Any code in the application that uses

objects of the class is enclosed in a ‘try block’. So the exception mechanism

uses 3 new C++ keywords: throw, catch and try.

4.18.1 A Simple Exception Example

# include<iostream.h> const int MAX=3; class stack { private: int st[MAX];int top; public: class range { }; stack(){top=-1;} void push(int var) { if(top>=MAX-1) throw range();

Page 227: C++ infosystems 1

Introduction to OOP unit1

st[++top]=var; } int pop() { if(top<0) throw range(); return st[top--]; } }; void main() { stack s1; { try s1.push(11); s1.push(22); s1.push(33);

cout<<"1"<<s1.pop()<<endl; cout<<"2"<<s1.pop()<<endl; cout<<"3"<<s1.pop()<<endl; cout<<"4"<<s1.pop()<<endl; } catch(stack::range) { cout<<"stack full or empty"<<endl; } cout<<"Arrive here after catch"<<endl; }

Sequence of Events

1. Code is executing normally outside a try block.

2. Control enters the try block.

3. A statement in the try block causes an error in a member function.

4. The member function throws an exception.

Page 228: C++ infosystems 1

Introduction to OOP unit1

5. Control transfers to the exception handler ( catch block ) following the try

block.

4.18 EXERCISE

1. Write a program that copies the contents of a character file to another

file. Invoke the program with two command line arguments - the source

file and the destination file.

2. Create a student class which reads and display the roll number, name and

marks in 3 subject of the student. Store the details in student data file.

3. Modify the above problem to read the data from data file and display the total

marks, average and grade (i.e., average < 50 fail otherwise pass) on the

screen.

4.19 SUMMARY

In this unit, you have seen the hierarchy of stream classes, you have also seen

how to perform disk I/O in different ways. Files in C++ are objects of various

classes, ofstream for output, istream for input, ifstream for input and output.

Member function of these or base classes are used to perform I/O operation.

Functions such as put () and write () are used for output, while get () and read ()

are used for input.

The read() and write () functions work in binary mode, so that entire objects can

be saved to disk no matter what sort of data they contain.

A check for error conditions should be made after each file operation. The object

itself takes on a value of 0 if an error occurred or nonzero otherwise. Several

member functions can be used to determine specific kinds of errors.

Redirection provides an approach to file I/O, using input and output to cin and

cout. Sending output to the printer involves outputting to a file usually called

PRN. The extraction operator >> and the insertion operator << can be

overloaded so that they work with programmed – defined data types.

Page 229: C++ infosystems 1

Introduction to OOP unit1

Virtual functions provide a way for a program to decide, when it is running, what

function to call. Ordinarily such decisions are made at compile time. Virtual

functions make possible greater flexibility in performing the same kind of action

on different kinds of objects. In particular, they allow the use of functions called

from an array of type pointer– to–base that actually holds a variety of derived

types. Typically a function is declared virtual in the base class and other

functions with the same name are declared in derived class. A pure virtual

function has no body in the base class.

A friend function can access a class’s private data, even though it is not a

member function of the class. This is useful when one function must have

access to two or more unrelated classes and when overloading operator must

use, on its left side, a value of a class other than the one of which it is a member.

Friends are also used to facilitate functional notation.

ANSWERS TO EXERCISE 4.19

1. #include<fstream.h> #include<process.h> void main(int argc,char * argv[]) { if (argc!=3) { cerr<<"\n syntax : fcopy sourcefile destination file";exit(-1);} char ch; ifstream infile; infile.open(argv[1]); if (!infile) { cerr<<"\n cannot open"<<argv[1]; exit(-1); } ofstream outfile; outfile.open (argv[2],ios ::noreplace); if (!outfile) { cerr<<"\n cannot open"<<argv[2];

Page 230: C++ infosystems 1

Introduction to OOP unit1

exit(-1); } while(infile) { infile.get(ch); outfile.put(ch); } }

2. # include <fstream.h> class student { private : int rno; char name[20]; int marks[3]; public : void getdata() { cout << "Enter Roll No"; cin>>rno;cin.get(); cout << "Enter Name "; cin.getline(name,'\n'); cout << "Enter Marks"; for (int i=0;i<3;i++) cin>>marks[i]; } void dispdata() { cout <<"Roll Number :"<<rno<<endl; cout <<"Name :"<<name<<endl; for (int i=0;i<3;i++) cout<<endl<<marks[i]; } };

void main() { student s1; fstream stdfile;

Page 231: C++ infosystems 1

Introduction to OOP unit1

stdfile.open("std.dat",ios::out|ios::binary); char wish; do { s1.getdata(); s1.dispdata(); stdfile.write((char *)&s1,sizeof(student)); cout <<"Continue (Y/N)?"; cin>>wish; } while (wish=='y'|| wish=='Y'); stdfile.close(); }

3. # include <fstream.h> class student { private : int rno; char name[20]; int marks[3]; public : void getdata() { cout << "Enter Roll No"; cin>>rno;cin.get(); cout << "Enter Name "; cin.getline(name,'\n'); cout << "Enter Marks"; for (int i=0;i<3;i++) cin>>marks[i]; } void dispdata() { int tot = 0; cout <<"Roll Number :"<<rno<<endl; cout <<"Name :"<<name<<endl; for (int i=0;i<3;i++) { cout<<marks[i]<<endl; tot += marks[i];

Page 232: C++ infosystems 1

Introduction to OOP unit1

} float avg=tot/3.0; if (avg<50) cout<<"Grade : Fail"<<endl; else cout<<"Grade : Pass"<<endl; } };

void main() { student s1; fstream stdfile; stdfile.open("std.dat",ios::in|ios::binary); stdfile.read((char *)&s1,sizeof(student)); while(stdfile) { s1.dispdata(); stdfile.read((char *)&s1,sizeof(student)); } stdfile.close(); }