C++ Book

553
LESSON PLAN nit Title: Object Oriented rogramming [C++] aculty: Vandana Babrekar (Pune) Unit Code 3B-503 Unit Level Unit Value:1 Daily Lecture Schedule with dates Name of the topic as given in RU Syllabus Lear ning Outc ome s Assig nmen t no., if any Number of Hours L* T* P* To tal 1 Lecture 1 Object oriented Programming Concepts 1 1 2 Lecture 2 Class & Object 1 1 3 Lecture 3 C++ Getting Started 1 1 4 Lecture 4 Functions in C++ 1 1 5 Lecture 5 Control Structures 1 1 6 Lecture 6 Representation of Abstract Data Types & scope of Attributes 1 1 7 Lecture 7 GROUP DISCUSSION 1 1 8 Lecture 8 Constructor 9 Lecture 9 Constructor [Contd.] 1 1 10 Lecture 10 Overloading 1 1 11 Lecture 11 Overloading [Contd.] 1 1 12 Lecture 12 Arrays 13 Lecture Pointers in C++ 1 1

Transcript of C++ Book

Page 1: C++ Book

LESSON PLAN

Unit Title: Object Oriented Programming [C++]Faculty: Vandana Babrekar (Pune)

Unit Code3B-503 Unit Level Unit Value:1

Daily Lecture Schedule

with dates

Name of the topic as given in RU SyllabusLearn

ing Outcomes

Assignment no., if any

Number of HoursL* T* P* Tot

al

1 Lecture 1 Object oriented Programming Concepts 1 12 Lecture 2 Class & Object 1 13 Lecture 3 C++ Getting Started 1 14 Lecture 4 Functions in C++ 1 15 Lecture 5 Control Structures 1 16 Lecture 6 Representation of Abstract Data Types &

scope of Attributes 1 1

7 Lecture 7 GROUP DISCUSSION 1 18 Lecture 8 Constructor

9 Lecture 9 Constructor [Contd.] 1 110 Lecture 10 Overloading 1 111 Lecture 11 Overloading [Contd.] 1 112 Lecture 12 Arrays13 Lecture 13 Pointers in C++ 1 114 Lecture 14 Inheritance 1 115 Lecture 15 Inheritance [Contd.] 1 116 Lecture 16 Inheritance [Contd.] 1 1 217 Lecture 17 TUTORIAL 1 118 Lecture 18 Virtual Functions 1 119 Lecture 19 Polymorphism 1 120 Lecture 20 Virtual Base Classes, Nesting Of Class 1 1 221 Lecture 21 Streams 1 122 Lecture 22 Streams [Contd.] 1 123 Lecture 23 TUTORIAL 1 1 124 Lecture 24 Working with Files25 Lecture 25 Working with Files [Contd.] 1 126 Lecture 26 Working with Files [Contd.] 1 1 227 Lecture 27 Templates 1 128 Lecture 28 Templates [Contd.] 1 129 Lecture 29 Templates [Contd.] 1 1 230 Lecture 30 Exception Handling 1 131 Lecture 31 Exception Handling [Contd.] 1 132 Lecture 32 GROUP DISCUSSION33 Lecture 33 Implementation 1 134 Lecture 34 Implementation 1 235 Lecture 35 Data Driven 1 1

Page 2: C++ Book

36 Lecture 36 Omt 1 137 Lecture 37 CRC 1 138 Lecture 38 Design Refinement 1 139 Lecture 39 Standard Template Library 1 140 Lecture 40 Standard Template Library[Contd.] 1 141 Lecture 41 UML 1 142 Lecture 42 UML [contd.] 1 143 Lecture 43 GROUP DISCUSSION 1 1

Page 3: C++ Book

UNIT I

Lesson 1

OBJECT ORIENTED PROGRAMMING

Objectives

Introduction to object oriented programming

Features of OOPS

Benefits of OOPS

Applications of OOPS

Basic Concept

Today in this introductory lecture , I will brief you some of the new concept of object oriented

programming . we are aware of modular/structured programming, unstructured programming which

are the traditional methods of writing a program. We also saw how the ‘main program’ is linked to

‘subprogram’ or ‘subroutine’ through ‘procedure calls [example of swapping between two telephone

calls received’]. And the trend of ‘object oriented programming’ was discussed in brief. Now lets

understand ‘object oriented programming through its programming tool…. C++ ” Fundamental

change in (object oriented programming )OOP is that a program is designed around data being

operated upon rather than upon the operations themselves. C++ is an example of Object Oriented

Programming . It is expanded version of C .The limitations of C language are evident when a

software project is too large to be handled. In some circumstances, error occur at some place and

some patch up programs are added to rectify that error.These programs introduce an unexpected

error at some other location and this process continues.

In 1980 Bjarne Stroustrup addressed this problem by adding several extensions to C language. The

most important addition was the concept of CLASS . The addition made were mainly aimed at

extending the language in such a way that it supports object-oriented programming.

OBJECT ORIENTED PROGRAMMING PATTERN

Inspiring factor in the invention of object-oriented approach is to remove some of the flaws

encountered in the procedural approach. OOP treats data as a critical element in the program

development and does not allow it to flow freely around the system. It ties data more closely to the

Page 4: C++ Book

functions that operate on it, and protects it from accidental modification from outside functions.

OOP allows decomposition of a problem into a number of entities called objects and then builds data

and functions around these objects.

Following fig shows the organization of data and functions in object-oriented programs .

The data of an object can be accessed only by the functions associated with that object. However,

functions of one object can access the functions of other objects.

Object A Object B

Communication

Object C

Organization of data and functions in OOP

CHARACTERISTICS OF C++:

Emphasis is on data rather than procedure.

Programs are divided into what are known as objects.

Data structures are designed such that they characterize the objects.

Functions that operate on the data of an object are tied together in the data structure.

DATA

FUNCTION

DATA

FUNCTION

DATA

FUNCTION

Page 5: C++ Book

Data is hidden and cannot be accessed by external functions.

Objects may communicate with each other through functions.

New data and functions can be easily added whenever necessary.

Follows bottom-up approach in program design.

Definition: “Object-oriented programming as an approach that provides a way of modularizing

programs by creating partitioned memory area for both data and functions that can be used as

templates for creating copies of such modules on demand.”

Thus, an object is considered to be partitioned area of computer memory that stores data and set of

operations that can access that data. Since the memory partitions are independent, the objects can

be used in a variety of different programs without modifications.

BASIC CONCEPTS OF OBJECT-ORIENTED PROGRAMMING.

It is necessary to understand some of the concepts used extensively in object-oriented

Programming.

They are:

Objects

Classes

Data abstraction and encapsulation

Inheritance

Polymorphism

Dynamic binding

Message passing

OBJECTS:

Objects are the basic run-time entities in an object-oriented system. They may represent a

person, a place, a bank account, a table of data or any item that the program has to handle. They may

also represent user-defined data such as vectors, time and lists.

Objects take up space in the memory and have an associated address like a record in Pascal,

or a structure in C.

When a program is executed, the objects interact by sending messages to one another. For

example, if "customer" and "account" are two objects in a program, then the customer object may

Page 6: C++ Book

send a message to the account object requesting for the bank balance. Each object contains data, and

code to manipulate the data. Objects can interact without having to know details of each other's data

or code. It is sufficient to know the type of message accepted, and the type of response returned by

the objects. Although different authors represent them differently.

Fig. Shows two notations that are popularly used in object-oriented analysis and design.

Object: STUDENT

DATA

Name

Date-f-birth

Marks

FUNCTIONS

Total

Average

Display

Two ways of representing an object

Classes:

Objects contain data, and code to manipulate that data. The entire set of data and code of an

object can be made a user-defined data type with the help of a class. In fact, objects are variables of

the type class. Once a class has been defined, we can create any number of objects belonging to that

class. Each object is associated with the data of type class with which they are created.

Definition : A class is a collection of objects of similar type.

STUDENTTotal

Average

Display

Page 7: C++ Book

For e.g., mango, apple and orange are members of the class fruit. Classes are user-defined data types

and behave like the built-in types of a programming language. The syntax used to create an object is

no different than the syntax used to create an integer object in C. If fruit has been defined as a class,

then the statement

Fruit mango;

will create an object mango belonging to the class fruit.

Data Abstraction and Encapsulation:

The wrapping up of data and functions into a single unit (called class) is known as encapsulation.

Data encapsulation is the most striking feature of a class. The data is not accessible to the outside

world, and only those functions, which are wrapped in the class, can access it. These functions

provide the interface between the object's data and the program. This insulation of the data from

direct access by the program is called data hiding or information hiding.

Abstraction refers to the act of representing essential features without including the background

details or explanations.

Classes use the concept of abstraction and are defined as a list of abstract attributes such as size,

weight and cost, and functions to operate on these attributes. They encapsulate all the essential

properties of the objects that are to be created. The attributes are sometimes called data members

because they hold information. The functions that operate on these data are sometimes called

methods or member functions.

Since the classes use the concept of data abstraction, they are known as Abstract Data Types (ADT)

Inheritance:

Inheritance is the process by which objects of one class acquire the properties of objects of another

class. For example, the bird 'robin' is a part of the class “flying bird' which is again a part of the class

'bird'. The principle behind this sort of division is that each derived class shares common

characteristics with the class from which it is derived as illustrated in Fig.

Page 8: C++ Book

Concept of inheritance provides the idea of reusability. This means that we can add additional

features to an existing class without modifying it. This is possible by deriving a new class from the

existing one. The new class will have the combined features of both the classes. The real appeal and

power of the inheritance mechanism is that it allows the programmer to reuse a class that is almost,

but not exactly, what he wants, and to tailor the class in such a way that it does not introduce any

undesirable side-effects into the rest of the classes.

Note that each sub-class defines only those features that are unique to it. Without the use of

classification, each class would have to explicitly include all of its features.

Fig. Property inheritance

Polymorphism

Polymorphism, means the ability to take more than one form.

An operation may exhibit different behaviors in different instances. The behavior depends

upon the types of data used in the operation.

Bird

AttributesFeathersLay eggs

Flying Bird Attributes----------------

Non-Flying Bird Attributes----------------

Robin Attributes-------------

SwallowAttributes-------------

Penguin Attributes-------------

Kiwi Attributes-------------

Page 9: C++ Book

For e.g., consider the operation of addition of two numbers, the operation will generate a

sum. If the operands are strings, then the operation would produce a third string by concatenation.

The process of making an operator to exhibit different behaviors in different instances is

known as operator overloading.

Figure below illustrates that a single function name can be used to handle different number and

different types of arguments. This is something similar to a particular word having several different

meanings depending on the context. Using a single function name to perform different types of tasks

is known as function overloading.

Polymorphism plays an important role in allowing objects having different internal structures to

share the same external interface. This means that a general class of operations may be accessed in

the same manner even though specific actions associated with each operation may differ.

Polymorphism is extensively used in implementing inheritance.

Fig. Polymorphism

Dynamic Binding

Binding refers to the linking of a procedure call to the code to be executed in response to the call.

Dynamic binding (also known as late binding) means that the code associated with a given procedure

call is not known until the time of the call at run-time. It is associated with polymorphism and

inheritance. A function call associated with a polymorphism reference depends on the dynamic type

of that reference.

ShapeDraw ()

Circle objectDraw (circle)

Box objectDraw (box)

Triangle objectDraw (triangle)

Page 10: C++ Book

E.g. Consider the procedure "draw" in Fig. By inheritance, every object will have this procedure. Its

algorithm is, however, unique to each object and so the draw procedure will be redefined in each

class that defines the object. At run-time, the code matching the object under current reference will

be caned.

Message Passing

An object-oriented program consists of a set of objects that communicate with each other. The

process of programming in an object-oriented language, therefore, involves the following basic

steps:

1. Creating classes that define objects and their behavior,

2. Creating objects from class definitions, and

3. Establishing communication among objects.

Objects communicate with one another by sending and receiving information much the same way as

people pass messages to one another. The concept of message passing makes it easier to talk about

building systems that directly model or simulate their real-world counterparts.

A message for an object is a request for execution of a procedure, and therefore will invoke a

function (procedure) in the receiving object that generates the desired result. Message passing

involves specifying the name of the object, the name of the function (message) and the information

to be sent.

Objects have a life cycle. They can be created and destroyed. Communication with an object is

feasible as long as it is a'1ive.

BENEFITS OF OOP

OOP offers several benefits to both the program designer and the user. Object-orientation

contributes to the solution of many problems associated with the development and quality of

software products. The new technology promises greater programmer productivity, better quality

of software and lesser maintenance cost. The principal advantages are:

Through inheritance, we can eliminate redundant code and extend the use of existing

classes.

Page 11: C++ Book

We can build programs from the standard working modules that communicate with one

another, rather than having to start writing the code from scratch. This leads to saving of

development time and higher productivity.

The principle of data hiding helps the programmer to build secure programs that cannot be

invaded by code in other parts of the program.

It is possible to have multiple instances of an object to co-exist without any interference.

It is possible to map objects in the problem domain to those in the program.

It is easy to partition the work in a, project based on objects.

The data-centered design approach enables us to capture more details of a model in

implementable form.

Object-oriented systems can be easily upgraded from small to large systems.

Message passing techniques for communication between objects makes the interface

descriptions with external systems much simpler.

Software complexity can be easily managed.

While it is possible to incorporate all these features in an object-oriented system, their importance

depends on the type of the project and the preference of the programmer. There are a number of

issues that need to be tackled to reap some of the benefits stated above. For instance, object libraries

must be available for reuse. The technology is still developing and, current products may be

superseded quickly. Strict controls and protocols. need to be developed if reuse is not to be

compromised.

Developing software that is easy to use makes it hard to build. It is hoped that the object. oriented

programming tools would help manage this problem.

OBJECT ORIENTED LANGUAGES

Object-oriented programming is not the right of any particular language. Like structured.

programming, OOP concepts can be implemented using languages such as C and Pascal. However,

programming becomes clumsy and may generate confusion when the programs grow large. A

language that is specially designed to support the OOP concepts makes it easier to implement them.

The languages should support several of the OOP concepts to claim that they are object., oriented.

Depending upon the features they support, they can be classified into the following two categories:

1. Object-based programming languages, and

Page 12: C++ Book

2. Object-oriented programming languages.

Object-based programming is the style of programming that primarily supports encapsulation and

object identity. Major features that are required for object-based programming are:

Data encapsulation

Data hiding and access mechanisms

Automatic initialization and clear-up of objects

Operator overloading

Languages that support programming with objects are said to be object-based programming

languages. They do not support inheritance and dynamic binding. Ada is a typical object-based

programming language.

Object-oriented programming incorporates all of object-based programming features along with two

additional features, namely, inheritance and dynamic binding. Object-oriented programming can

therefore be characterized by the following statement:

Object-based features + inheritance + dynamic binding

Languages that support these features include C++, Smalltalk, Object Pascal and Java. There are a

large number of object-based and object-oriented programming languages.

APPLICATIONS OF OOP

Applications of OOP are beginning to gain importance in many areas. The most popular application

of object-oriented programming, up to now, has been in the area of user interface design such as

windows. Hundreds of windowing systems have been developed, using the OOP techniques.

Real-business systems are often much more complex and contain many more objects with

complicated attributes and methods. OOP is useful in these types of applications because it can

simplify a complex problem. The promising areas for application of OOP include:

Real-time systems

Simulation and modeling

Object-oriented databases

Page 13: C++ Book

Hypertext, hypermedia and expertext

AI and expert systems

Neural networks and Parallel programming Decision support and office automation systems

CIM/CAM/CAD systems

Object-oriented technology is certainly going to change the way the software engineers think,

analyze, design and implement future systems.

WHAT IS C++?

C++ is an object-oriented programming language. It was developed by Bjarne Stroustrup at AT&T

Bell Laboratories in Murray Hill, New Jersey, USA, in the early 1980's.

Therefore, C++ is an extension of C with a major addition of the class construct feature of Simula67.

Since the class was a major addition to the original C language,

During the early 1990's the language underwent a number of improvements and changes. In

November 1997, the ANSI/ISO standards committee standardized these changes and added several

new features to the language specifications.

C++ is a superset of C. Most of what we already know about C applies to C++ also. Therefore,

almost all C programs are also C++ programs. However, there are a few minor differences that will

prevent a C program to run under C++ compiler. We shall see these differences later and when they

are encountered.

The most important facilities that C++ adds on to C are

Classes,

Inheritance,

Function overloading, and

Operator overloading.

APPLICATIONS OF C++

Page 14: C++ Book

C++ is a versatile language for handling very large programs. It is suitable for virtually any

programming task including development of editors, compilers, databases, communication systems

and any complex real-life application systems.

.

Since C++ allows us to create hierarchy-related objects, we can build special object oriented libraries

which can be used later by many programmers.

While C++ is able to map the real-world problem properly, the C part of C++ give the language the

ability to get close to the machine-level details.

C++ programs are easily maintainable and expandable. When a new feature need to be implemented,

it is very easy to add to the existing structure of an object. It is expected that C++ will replace C as a

general-purpose language in the near future

A SIMPLE C++ PROGRAM

Let us begin with a simple example of a C++ program that prints a string on the screen.

This simple program demonstrates several C++ features.

# include<iostream> // include header file

using namespace std;

int main()

{

cout<< “ C++ is better than C \n” // C++ statement

return();

} // end of example

Namespace

Namespace is a new concept introduced by the ANSI C++ standards committee. This define

a scope for the identifiers that are used in a program. For using the identifiers defined in the name

space scope we must include the using directive, like using namespace std. Here, std is the name

space where ANSI C++ standard class libraries are defined. All ANSI C++ programs must include

Page 15: C++ Book

this directive. This will bring all the identifiers defined in std u the current global scope. using and

namespace are the new keywords of C++.

Return Type of main( )

In C++, main() returns an integer type value to the operating system. Therefore, every main in C++

should end with a return( 0) statement; otherwise a warning or an error might occur Since main()

returns an integer type value, return type for main() is explicitly specified as int Note that the

default return type for all functions in C++ is int.

An Example With Class :

One of the major features of C++ is classes. They provide a method of binding together data and

functions which operate on them. Like structures in C, classes are user-defined data types shows the

use of class in a C++ program.

#include<iostream>

using namespace std;

class person()

{

char name[30];

int age;

public:

void getdata(void);

void display(void);

}

void person:: getdata(void)

{

cout « "\n Enter Name: ";

cin>> name;

cout « "\n Enter Age”;

cin >> age;

}

Page 16: C++ Book

void person :: display(void)

{

cout<<”\n Name :”<<name;

cout <<”\n age :”<<age;

}

int main()

{

person p;

p.getdata();

p.display();

return 0;

}

The output of Program is:

Enter Name: Ajay

Enter Age: 30

Name: Ajay

Age: 30

The above program defines person as a new data of type class. The class person includes two basic

data type items and two functions to operate on that data. These functions are called I member

functions. The main program uses person to declare variables of its type. Class variables are known

as objects. Here, p is an object of type person.

Class objects are used to invoke the functions defined in that class.

STRUCTURE OF C++ PROGRAM

As it can be seen from the above Program a typical C++ program would contain four sections as

shown in following Fig. These sections may be placed in separate code files and then compiled

independently or jointly.

Include files

Class Declaration

Member Function Definition

Main Function program

Page 17: C++ Book

Structure of a C++ program

It is a common practice to organize a program into three separate files. The class declarations are

placed in a header file and the definitions of member functions go into another file. This approach

enables the programmer to separate the abstract specification of the interface (class definition) from

the implementation details (member functions definition). Finally, the main program that uses the

class is placed in a third file which "includes" the previous two files as well as any other files

required.

Summary

Object-oriented programming as an approach that provides a way of modularizing programs

by creating partitioned memory area for both data and functions that can be used as

tempalates for creating copies of such modules on demand.”

A class is a collection of objects of similar type

Inheritance is the process by which objects of one class acquire the properties of objects of

another class.

Polymorphism, means the ability to take more than one form.

Dynamic binding (also known as late binding) means that the code associated with a given

procedure call is not known until the time of the call at run-time

Object-orientation contributes to the solution of many problems associated with the

development and quality of software products

Page 18: C++ Book

Object-oriented programming incorporates all of object-based programming features along

with two additional features, namely, inheritance and dynamic binding

The most popular application of object-oriented programming, up to now, has been in the

area of user interface design such as windows

Questions:

1. Discuss features of OOPS

2. What do you mean by Dynamic Binding? How it is useful in OOPS

3. What are the Applications of OOPS

4. State characteristics of C++

Page 19: C++ Book

UNIT I

Lesson 2

CLASS & OBJECT

Objective:

Class

Object

Now you have an idea what object oriented programming is. Here in this second lecture of OOP we

will go through some of the important terminologies used in OOP like class and object.

CLASS

A class is a logical method to organize data and functions in the same structure. They are declared

using keyword class, whose functionality is similar to that of the C keyword struct, but with the

possibility of including functions as members, instead of only data.

Its form is:

class class_name {

permission_label_1:

member1;

permission_label_2:

member2;

...

} object_name;

where class_name is a name for the class (user defined type) and the optional field object_name is

one, or several, valid object identifiers. The body of the declaration can contain members, that can

be either data or function declarations, and optionally permission labels, that can be any of these

three keywords: private:, public: or protected:. They make reference to the permission which the

following members acquire:

private members of a class are accessible only from other members of their same class or from their

"friend" classes.

protected members are accessible from members of their same class and friend classes, and also

from members of their derived classes.

Page 20: C++ Book

Finally, public members are accessible from anywhere the class is visible.

If we declare members of a class before including any permission label, the members are considered

private, since it is the default permission that the members of a class declared with the class

keyword acquire.

For example:

class CRectangle {

int x, y;

public:

void set_values (int,int);

int area (void);

} rect;

Declares class CRectangle and an object called rect of this class (type). This class contains four

members: two variables of type int (x and y) in the private section (because private is the default

permission) and two functions in the public section: set_values() and area(), of which we have only

included the prototype.

Notice the difference between class name and object name: In the previous example, CRectangle

was the class name (i.e., the user-defined type), whereas rect was an object of type CRectangle. Is

the same difference that int and a have in the following declaration:

int a;

int is the class name (type) and a is the object name (variable).

On successive instructions in the body of the program we can refer to any of the public members of

the object rect as if they were normal functions or variables, just by putting the object's name

followed by a point and then the class member (like we did with C structs).

For example:

rect.set_value (3,4);

myarea = rect.area();

Page 21: C++ Book

but we will not be able to refer to x or y since they are private members of the class and they could

only be referred from other members of that same class. Confused? Here is the complete example of

class CRectangle:

// classes example

#include <iostream.h>

class CRectangle {

int x, y;

public:

void set_values (int,int);

int area (void) {return (x*y);}

};

void CRectangle::set_values (int a, int b) {

x = a;

y = b;

}

int main () {

CRectangle rect;

rect.set_values (3,4);

cout << "area: " << rect.area();

}

Output :

area: 12

The new thing in this code is the operator :: of scope included in the definition of set_values(). It is

used to declare a member of a class outside it. Notice that we have defined the behavior of function

area() within the definition of the CRectangle class - given its extreme simplicity. Whereas

set_values() has only its prototype declared within the class but its definition is outside. In this

outside declaration we must use the operator of scope ::.

Page 22: C++ Book

The scope operator (::) specifies the class to which the member being declared belongs, granting

exactly the same scope properties as if it was directly defined within the class. For example, in the

function set_values() of the previous code, we have referred to the variables x and y, that are

members of class CRectangle and that are only visible inside it and its members (since they are

private).

The only difference between defining a class member function completely within its class and to

include only the prototype, is that in the first case the function will automatically be considered

inline by the compiler, while in the second it will be a normal (not-inline) class member function.

The reason why we have made x and y private members (remember that if nothing else is said all

members of a class defined with keyword class have private access) it is because we have already

defined a function to introduce those values in the object (set_values()) and therefore the rest of the

program does not have a way to directly access them. Perhaps in a so simple example as this you do

not see a great utility protecting those two variables, but in greater projects it may be very important

that values cannot be modified in an unexpected way (unexpected from the point of view of the

object).

One of the greater advantages of a class is that we can declare several different objects from it. For

example, following with the previous example of class CRectangle, we could have declared the

object rectb in addition to the object rect :

// class example

#include <iostream.h>

class CRectangle {

int x, y;

public:

void set_values (int,int);

int area (void) {return (x*y);}

};

void CRectangle::set_values (int a, int b) {

x = a;

y = b;

}

Page 23: C++ Book

int main () {

CRectangle rect, rectb;

rect.set_values (3,4);

rectb.set_values (5,6);

cout << "rect area: " << rect.area() << endl;

cout << "rectb area: " << rectb.area() << endl;

}

Output

rect area: 12

rectb area: 30

Notice that the call to rect.area() does not give the same result as the call to rectb.area(). This is

because each object of class CRectangle has its own variables x and y, and its own functions

set_value() and area().

On that is based the concept of object and object-oriented programming. In that data and functions

are properties of the object, instead of the usual view of objects as function parameters in structured

programming. In this and the following sections we will discuss advantages of this methodology.

In this concrete case, the class (type of object) to which we were talking about is CRectangle, of

which there are two instances, or objects: rect and rectb, each one with its own member variables

and member functions.

Object

Definition (Object) An object is an instance of a class. It can be uniquely identified by its name and

it defines a state which is represented by the values of its attributes at a particular time.

The state of the object changes according to the methods which are applied to it. We refer to these

possible sequence of state changes as the behaviour of the object:

Definition (Behaviour) The behaviour of an object is defined by the set of methods which can be

applied on it.

Page 24: C++ Book

We now have two main concepts of object-orientation introduced, class and object. Object-oriented

programming is therefore the implementation of abstract data types or, in more simple words, the

writing of classes. At runtime instances of these classes, the objects, achieve the goal of the program

by changing their states. Consequently, you can think of your running program as a collection of

objects.

MEMORY ALLOCATION FOR OBJECTS

We have stated that the memory space for objects is allocated when they are declared and not when

the class is specified. This statement is only partly true. Actually, the member functions are created

and placed in the memory space only once when they are defined as a part of a class specification.

Since all the objects belonging to that class use the same member functions, no separate space is

allocated for member functions when the objects are created. Only space for member variables is

allocated separately for each object. Separate memory locations for objects are essential, because the

member variables will hold different data values for different objects.

Common for all objects Member Function 1

Member Function 2

memory created when Function defined

Member Function 1 Member Function 1 Member Function 1

Member Function 2 Member Function 2 Member Function 2

Object 1 Object 2 Object 3Memory created

when Objects defined.

Page 25: C++ Book

OBJECTS AS FUNCTION ARGUMENTS

Like any other data type, an object may be used as a function argument. This can be done in two

ways:

A copy of the entire object is passed to the function.

Only the address of the object is transferred to the function.

The first method is called pass-by-value. Since a copy of the object is passed to the function, any

changes made to the object inside the function do not affect the object used to call the function. The

second method is called pass-by-reference. When an address of the object is passed the called

function works directly on the actual object used in the call. This means that any changes made to

the object inside the function will reflect in the actual object. The pass-by reference method is more

efficient since it requires to pass only the address of the object and not the entire object.

Program illustrates the use of objects as function arguments. It performs the addition of time in the

hour and minutes format.

Example: Object as argument

#include<iostream.h>

class time

{

int hours;

int minutes;

public:

void gettime(int h, int m)

{

hours = h; minutes = m;

}

void puttime(void)

{

cout<<hours<<” hours and”;

cout<<minutes<<”minutes”<<”\n”;

Page 26: C++ Book

}

void sum(time , time ); /declaration with objects as arguments

};

void time:: sum(time t1, time t2); //t1 & t2 are objects

{

minutes = t1.minutes + t2.minutes;

hours = minutes/60

minutes = minutes%60;

hours = hours + t1.hours + t2.hours;

}

int main()

{

time T1,T2,T3;

T1.gettime(2,45); //get T1

T2.gettime(3,30); //get T2

T3.sum(T1,T2); //T3=T1+T2

Cout<< “T1= “;T1.puttime(); //display T1

Cout<< “T2= “;T2.puttime(); //display T2

Cout<< “T3= “;T3.puttime(); //display T3

Return 0;

}

Output

T1 = 2 hours and 45 minutes

T2 = 3 hours and 30 minutes

T3 = 6 hours and 15 minutes

Since the member function sum( ) is invoked by the object T3, with the objects Tl and T2 as

arguments, it can directly access the hours and minutes variables ofT3. But, the members of Tl and

T2 can be accessed only by using the dot operator (like Tl.hours and T1.minutes). Therefore, inside

Page 27: C++ Book

the function sum() the variables hours and minutes refer to T3, T1.hours and T1.minutes refer to Tl,

and T2.hours and T2.minutes refer to T2.

An object can also be passed. as an argument to a non-member function. However, such functions

can have access to the public member functions only through the objects passed as arguments to it.

These functions cannot have access to the private data members

Attribute

Definition( Attribute) A property of object. It cannot exist independently of the object. Attribute

may take other objects as values. It has a type. It describes the range of values that that property may

hold.

Method

Definition (Method) A method is associated with a class. An object invokes a method as a reaction

to receipt of a message.

A Method is a service that can be requested from any object of the Class to affect behavior. A

Method (Operation) can either be a command or a question. A question should never change the

state of the object only a command can. The outcome of the Operation depends on the current state

of the object.

Summary

A class is a logical method to organize data and functions in the same structure. They are

declared using keyword class

private members of a class are accessible only from other members of their same class or

from their "friend" classes.

protected members are accessible from members of their same class and friend classes, and

also from members of their derived classes.

public members are accessible from anywhere the class is visible.

Page 28: C++ Book

An object is an instance of a class. It can be uniquely identified by its name and it defines a

state which is represented by the values of its attributes at a particular time.

The behaviour of an object is defined by the set of methods which can be applied on it.

Attribute: A property of object. It cannot exist independently of the object.

A method is associated with a class. An object invokes a method as a reaction to receipt of a

message.

Questions

1. Distinguish between Class and Object

2. Define

a) Method

b) Attribute.

Page 29: C++ Book

UNIT I

Lesson 3

C++ GETTING STARTED

Objective

Token

Datatype

Header files

Operators

As you know that C++ is extension of C , most of its features, data types , operator set are very

much similar to C in syntax and constructs. Here in this lecture we will discuss differences in them

TOKENS

The smallest unit in a program is known as a token. C++ has the following tokens .

Keywords

Identifiers

Constants Strings

Operators

KEYWORDS

Keywords are reserved words that cannot be useds as names for the program variables or other user

defined program entities. Compared to C, C++ has more keywords as specified below

asm Double new switch

auto Else operator template

break Enum private this

case Extern protected throw

catch Float public try

char For register typedef

class Friend return union

const Goto short unsigned

continue If signed virtual

default Inline sizeof void

delete Int static volatile

Page 30: C++ Book

do Long struct while

IDENTIFIERS

Identifier is the name given to variables, functions, arrays, classes, user defined types etc. The

naming convention in C++ is similar to C language. The rules are described below

. The name starts with an alphabetic character and not with a digit.

. A name can contain alphabets, digits and underscore characters.

. Names are case sensitive that is uppercase and lowercase letters are different.

. A keyword cannot be used as a name for a variable.

DATA TYPES

The basic data type in C language is supported in C++. C++ has four basic built-in data types. They

are char, int, float and double. Char is for storing a single character and is usually one byte in size.

Int stores an integral value u two bytes long. Float and double store floating point numbers. Float is

for single precision numbers and double is for double precision floating points. Signed and unsigned

are modifiers that can be used with any integral type. Th type is signed by default.

C++ recognizes the data type shown in the table below.

Type Name Bytes Range of Valueschar 1 -128 to 127

unsigned char 1 0 to 255

Signed char 1 -128 to 127

int 2 -32768 to 32767

unsigned int 2 0 to 65535

signed int 2 -32768 to 32767

short int 2 -32768 to 32767

Unsigned short int 2 0 to 65535

Signed short int 2 -32768 to 32767

Long int 4 -2147483648 to 2147483647

signed long int 4 -2147483648 to 2147483647

Unsigned long i.nt 4 0 to 4294967295

float 4 3.4E-38 to 1.7E+38

Page 31: C++ Book

double 8 1.7E-308 to 1.7E+308

long double 10 3.4E-4932 to 1.1 E+4932

SPECIFIERS

Specifiers modify the meaning of the basic built-in types. They effectively provide a larger set of

built in types. T specifiers, or qualifiers, are short, long, signed, and unsigned. The long and short

specifiers set the range that tt type will hold. Short int, int, and long int are in ascending order of

range size. The actual values vary from mac machine. Similarly, float; double, and long double are

in order of increasing capacity. There is no long float and n float or double. The signed and unsigned

specifiers indicate whether the first bit of the data type is to be used a~ indicator or not. Except for

charthe default is signed. Char mayor may not be signed by default. The following pi shows the

bytes used by the different data types along with the specifiers:

#include <iostream.h> II Header required for cout.

void main()

int i;

unsigned int ui;

short si; // int is understood

long i; //ditto

unsigned short usi; //ditto

unsigned long uli; //ditto

char c;

unsigned char uc;

float f;

double d;

long double Id;

//cout is Console out similar to printf

cout<<”\nSize of int = “<<sizeof(i);

cout<<”\nSize of unsigned int = "<<sizeof(ui);

cout«"\nSize of short int = "<<sizeof(si);

cout<<"\nSize of long int = "<<sizeof(li);

cout<<”\nSize of unsigned short int = "<<sizeof(usi);

Page 32: C++ Book

cout<<”\nSize of unsigned long int = "<<sizeof(uli)<<"\n";

cout<<"\nSize of char = "<<sizeof(c);

cout<<"\nSize of unsigned char = "<<sizeof(uc)<<"\n";

cout<<"\nSize of float = "<<sizeof(f);

cout<<"\nSize of double = "<<sizeof(d); cout<<''\nSize of long double = "<<sizeof(ld)<<''\n'';

ESCAPE SEQUENCES

The escape sequences allow you to use a sequence of characters to represent special characters.

Escape sequences are listed below. These escape sequences are used in I/O statements like

printf(), scanf(), cout etc.

Sequence Name

\a Alert (bell)

\f Formfeed

\r Carriaqe return

\v Vertical tab

\' Sinqle quotation mark

\\ Backslash

\b Backspace

\n Newline

\t Horizontal tab

\? Literal quotation mark

HEADER FILES

All the header files available in C are used in C++, alongwith other header files of C++. A few of

them are in the table.

FileName Major Contents

ASSERT.H Assert debugging macro

BIOS.H IOS service functions

CDERR.H Common dialog error return codes

COLORDLG.H Common dialog color dialog's control id numbers

COMMDLG.H Common dialog functions, types, and definitions

Page 33: C++ Book

CONIO.H Console and port I/O routines

CPL.H Control panel extension DLL definitions

CTYPE.H Character classification

CUSTCNTL.H Custom Control Library header file

DDE.H Dynamic Data Exchange structures and definitions

DDEML.H DDEML API header file

DIRECT.H Directory control

DOS.H MS-DOS interface functions

ERRNO.H errno variable definitions

FSTREAM.H Functions used by the filebuf and fstream classes

GRAPH.H Low-level graphics and font routines

IO.H File-handling and low-level I/O

IOMAINP.H definitions / declarations for iostream's parameterized

manipulators

IOS.H Functions used by the ios class

IOSTREAM.H Functions used by the iostream classes

ISTREAM,H Functions used by the istream class

MALLOC.H Memory-allocation functions

MATH.H Floating-point-math routines

MEMORY.H Buffer-manipulation routines

MMSYSTEM.H I NEW.H Include file for Multimedia APls.

OLE.H OLE functions, types, and definitions

NEW.H Declarations and definitions for C++ memory allocation

functions.

OSTREAM.H Functions used by the ostream class

PENWIN.H Pen Windows functions, types, and definitions

PENWOEM.H Pen Windows APls into recognizer layer

PGCHART.H Presentation graphics

PRINT.H Printing helper functions, types, and definitions

PROCESS.H Process-control routines

SCRNSAVE.H Win3.1 screensaver defines and definitions

SSEARCH.H Searching & sorting functions

SETJMP.H Setjmp and longjmp functions

Page 34: C++ Book

SHARE.H Flags used in _sopen

SHELLAPI.H SHELL.DLL functions, types, and definitions

SIGNAL.H Constants used by signal function

STDARG.H Macros for variable-length argument-list functions

STDDEF.H Commonly used data types and values

STDIO.H Standard I/O header file

STDIOSTR.H Functions used by the stdiostream and stdiobuf classes

STDLlB.H Commonly used library functions

STREAMB.H Functions used by the streambuf class

STRESS.H Stress functions definitions

STRING.H string manipulation function

STRSTREA.H Functions used by strstream classes

TIME.H General time functions

VER.H Version mngt. functions, types and definitions

VMEMORY.H Virtual memory functions

WFEXT.H Windows File Manager Extensions definitions

PREPROCESSOR DIRECTIVES

The table below lists the directives to the preprocessor. Their usage and the meaning in C++ is the

same as in any details regarding usage, please refer to any C reference material..

#define

#error

#include

#else

#ifdef

#elif

#pragma

#if

#Iine

#endif

#ifndef

#undef

Page 35: C++ Book

FILE EXTENSIONS

In C++. all the programs carry ".CPP" extensions as compared to ".C" extensions in C. Anyway,

even if you al working with a C++ compiler and give" .C" extension, C compiler takes over to

compile that program.

C++ COMMENTS

1. /* *1 comment is used to apply mutiline comment, where' 1*' begins a comment and' *1 . ends it.

2. Double-slash (II) sequence is used to comment single line completely.

OPERATORS:

The table below lists C and C++ operators by category.

C++ introduced many operators compared to C. This is described below

Scope resolution operator:

As C language does not allow the global variable value to be accessed from the inner block having

the same variable name as the global variable in order to solve this conflict the scope resolution

operator is used. The example presented below

#include <iostream.h>

int gl =10; // global variable gl

main()

int gl = 20; // gl redeclared again, local to main

int k = gl;

int gl = 30; // gl declared again in inner block

cout << "\n we are in inner block: \n";

cout << "k = " << k << "\n"; cout << "gl = " << gl << ''\n'';

cout << ":: gl = " << ::gl << ''\n'';

cout<< "\n We are in outer block: \n";

cout << "gl = " << gl << ''\n''; cout<< "::gl = " << ::gl << ''\n'';

Page 36: C++ Book

The output is

we are in inner block:

k=20

g1=30

::gl=10

we are in outer block

gl=20

::gl =10

In the program above gl variable is declared three times with different scope and uses the :: scope

resolution operator to access the global version as shown in the output.

MEMBER DEREFERENCING OPERATOR

The types of member referencing operators are described below

::* Pointer to member declerator

->* Pointer to member operator

.* Pointer to member operator

This operator is used in context with pointer to object member.

MEMORY MANAGEMENT OPERATOR

In c++ two important memory management operators are described below

delete Memory release operator

new Memory allocation operator

The general format of usage is

Pointer-variable = new data-type

Where Pointer-variable is used to hold the address of variable of data-type; Data-type is used to

specify any valid data. The new operator is used to allocate sufficient memory to hold a data object

Page 37: C++ Book

of type data-type and returns the address of the object to pointer variable. Few examples are given

below

int *ptr ;.

ptr = new int;

Other formats are

Pointer-variable = new data-type(value)

Where value is the initial value assigned to Pointer-variable. Few examples are given below

int *ptr = new int(25);

assign value 25 to ptr variable

You can create an array using the new operator as specified in the general format below

Pointer-variable = new data-type[size];

Where size is the required size of the memory to be allocated. Examples are given below

int * Arrptr = new int[3][4];

To release the memory allocated using the new operator, delete operator is used. To delete memory

allocated us the pointer holding the address of the allocated memory. Examples are given below

delete p; // to delete the memory area pointed by p.

delete [4] q; // deletes 4 elements from the array

delete [ ] p; // deletes the entire array

You can delete number of element from the array which is specified in the square bracket as

specified in the second example above.

MANIPULATORS

It is an operator used to format the presentation of data. This means that you can arrange the data on

the screen in a desired format. The most common manipulators are

endl Line Feed operator equivalent to special character' \n '

setw Field Width operator used to specify the display width of data on the screen.

Page 38: C++ Book

TYPE CAST OPERATOR

The type cast operator has similar functionality to C language. The syntax has changed as explained

in the example below

In C languageAverage = sum /(float)i;

In C++ language

Average = sum / float (i);

Arithmetic

+ Addition

- Subtraction

* Multiplication

/ Division

% Modulus

Relation

< Less than

<= Less than or equal to

> Greater than

>= Greater than or equal to

-- Equal

!= Not equal

Assignment

= Assignment

+= Addition

- Subtraction

/= Division

<<= Left shift

Page 39: C++ Book

assignment

&= Bitwise AND

|= Bitwise OR

Bitwise Logical

& Bitwise AND

&& Logical AND

|| Logical OR

/\ Bitwise-exclusive- OR

! Logical NOT

| Bitwise OR

<< Left shift

>> Right shift

~ One's complement Pointer Conditional

& Address of ? : Ternary

* Indirection

Miscellaneous: C++ Only

( ) Function call

:: Scope resolution

[ ] Array element & Reference

-> Pointer to structure member

.* Pointer to member

->* Pointer to member

. (type) Type cast sizeof() Size in bytes

The mathematical operators +, -, *, /, = all work in the same way, in mathematics and in C. Some

are evaluated I others in an expression, and are said to have higher precedence than the latter. The

unary operators are the ++ a - operators. They can be used before or after a variable and are

accordingly called pre or post increment or pre ( decrement operators. When used before a variable

the operation is first performed on the variable and then it i: in the expression. Conversely, when

used after a variable, the variable is first used in the expression and the incremented. For example

look at run the following program.

Page 40: C++ Book

Program:

#include <iostream.h>

void main()

int i=10;

cout<<''\n post-increment i = "«i++;

cout<<''\n pre-increment i = "<<++i;

cout<<''\npost-decrement i = "<<i--;

cout<<''\npre-decrement i = "<<--i;

Output:

post-increment i = 10

pre-increment i = 12

post-decrement i = 12

pre-decrement i = 10

CONSTANTS

The const keyword specifies that a variable's value is constant and tells the compiler to prevent the

programmer from modifying it.

Example:

const int i = 5;

i = 10; // Error

i++; // Error

You can define constant using the #define, but the constant defined using const keyword is typed

check where as #define constant has no type information.

C++ uses const keyword to declare a constant pointer of two types

Constant pointer

char. const ptr1 = "GOOD"; II constant pointer

which means you cannot modify the address that ptr1 is initialized to

Pointer to a constant

int const .ptr2 = &m; // pointer to a constant

Page 41: C++ Book

Which means that you cannot change the value at the address ptr2.

You can also declare both the pointer and the variable as constants in the following way

const char.const cp = "xyz";

ENUMERATED DATA TYPE

An enumerated data type is a user defined data type which provides a way to attach names to a

number which helps you to remember the number.

The syntax is similar to struct in C. For examples

enum shape{ circle,square,triangle};

Here shape is a user defined type which is used to declare a variable of type shape which can take

only the value

specified in the curly braces. The names in the curly braces represent the number 0 as circle,

1 as square, 2 as triangle automatically. ThedefauJt numbering starts from 0.

To declare variable conics of type shape

shape conics;

You can assign values in conics in following ways

conics = circle; // to assign 0 to conics

conics = 0; //it is not allowed and Error in C++

conics= (shape) 0; // correct way to assign using cast operator. '

int a = circle; // it is allowed.

STRUCT AND UNION

You can use struct and union to define user-defined type similar to C language along with function

prototype in the structure.

DECLARATION OF VARIABLES

Unlike C language you can declare variable at any position inside the function but before using the

variable. n program below demonstrates this feature.

Page 42: C++ Book

#include <iostream.h>

void main()

float x; //declaration

float sum;

for(int count = 1; count < 10;count++)

cin>> x;

sum = sum + x;

float average; //declaration

average = sum / count; //declaration

cout« average;

}

The above program declares the variables and total at the beginning of the program and the variable

average i: declared in ttie middle of the program. Such a creation helps to declare a variable with

dynamic initialization; shown in the program above. The average variable is initialized with'

sum/count '.

Summary

The smallest unit in a program is known as a token. C++ has the following tokens .

KeywordsIdentifiers

Constants Strings

Operators

Keywords are reserved words that cannot be useds as names for the program variables or other

user defined program entities

Identifier is the name given to variables, functions, arrays, classes, user defined types etc.

The basic data type in C language is supported in C++. C++ has four basic built-in data types.

They are char, int, float and double

Float and double store floating point numbers

Specifiers modify the meaning of the basic built-in types. They effectively provide a larger set of

built in types.

The escape sequences allow you to use a sequence of characters to represent special characters.

In C++. all the programs carry ".CPP" extensions as compared to ".C" extensions in C

Page 43: C++ Book

As C language does not allow the global variable value to be accessed from the inner block

having the same variable name as the global variable in order to solve this conflict the scope

resolution operator is used

To release the memory allocated using the new operator, delete operator is used.

The mathematical operators +, -, *, /, = all work in the same way, in mathematics and in C.

The const keyword specifies that a variable's value is constant and tells the compiler to prevent

the programmer from modifying it.

An enumerated data type is a user defined data type which provides a way to attach names to a

number which helps you to remember the number.

Question

What is token? Explain.

Explain the term Datatype, scope Resolution Operator, Enumerated Data Type

Give various types of operator set in C++

Page 44: C++ Book

UNIT I

LESSON 4

FUNCTIONS IN C++

Objective

In this lesson You will get acquainted with an important concept of OOPS i.e.

Functions,

Call by value,

Call by reference,

Friend function .

“In the previous section we have seen how a class is implemented along with the usage of objects and its subsequent components. Now comes the most important building block of the program…. Function. You will understand how important role a Function plays in program through the sessions below. ”

FUNCTION IN C++

Using functions you can structure your programs in a more modular way, accessing all the potential

that structured programming in C++ can offer us.

A function is a block of instructions that is executed when it is called from some other point of the

program. The following is its format:

type name ( argument1, argument2, ...) statement

where:

  · type is the type of data returned by the function.

  · name is the name by which it will be possible to call the function.

  · arguments (as many as wanted can be specified). Each argument consists of a type of data

followed by its identifier, like in a variable declaration (for example, int x) and which acts within

the function like any other variable. They allow passing parameters to the function when it is called.

The different parameters are separated by commas.

Page 45: C++ Book

  · statement is the function's body. It can be a single instruction or a block of instructions.

In the latter case it must be delimited by curly brackets {}.

function example:

// function example

#include <iostream.h>

int addition (int a, int b)

{

int r;

r=a+b;

return (r);

}

int main ()

{

int z;

z = addition (5,3);

cout << "The result is " << z;

return 0;

}

output

The result is 8

Function addition declares a new variable (int r;), and by means of the expression r=a+b;, it

assigns to r the result of a plus b. Because the passed parameters for a and b are 5 and 3

respectively, the result is 8.

The following line of code:

return (r);

finalizes function addition, and returns the control back to the function that called it (main)

following the program from the same point at which it was interrupted by the call to addition. But

Page 46: C++ Book

additionally, return was called with the content of variable r (return (r);), which at that moment

was 8, so this value is said to be returned by the function.

And here is another example about functions:

// function example

#include <iostream.h>

int subtraction (int a, int b)

{

int r;

r=a-b;

return (r);

}

int main ()

{

int x=5, y=3, z;

z = subtraction (7,2);

cout << "The first result is " << z << '\n';

cout << "The second result is " << subtraction (7,2) << '\n';

cout << "The third result is " << subtraction (x,y) << '\n';

z= 4 + subtraction (x,y);

cout << "The fourth result is " << z << '\n';

return 0;

}

The first result is 5The second result is 5The third result is 2The fourth result is 6

Arguments passed by value and by reference..

Page 47: C++ Book

Until now, in all the functions we have seen, the parameters passed to the functions have been

passed by value. This means that when calling a function with parameters, what we have passed to

the function were values but never the specified variables themselves. For example, suppose that we

called our first function addition using the following code :

int x=5, y=3, z;

z = addition ( x , y );

What we did in this case was to call function addition passing the values of x and y, that means 5

and 3 respectively, not the variables themselves.

This way, when function addition is being called the value of its variables a and b become 5 and 3

respectively, but any modification of a or b within the function addition will not affect the values

of x and y outside it, because variables x and y were not passed themselves to the the function, only

their values.

But there might be some cases where you need to manipulate from inside a function the value of an

external variable. For that purpose we have to use arguments passed by reference, as in the function

duplicate of the following example:

// passing parameters by reference

#include <iostream.h>

void duplicate (int& a, int& b, int& c)

{

a*=2;

b*=2;

c*=2;

}

int main ()

{

int x=1, y=3, z=7;

duplicate (x, y, z);

cout << "x=" << x << ", y=" << y << ", z=" << z;

Page 48: C++ Book

return 0;

}

output

x=2, y=6, z=14

The first thing that should call your attention is that in the declaration of duplicate the type of each

argument was followed by an ampersand sign (&), that serves to specify that the variable has to be

passed by reference instead of by value, as usual.

When passing a variable by reference we are passing the variable itself and any modification that we

do to that parameter within the function will have effect in the passed variable outside it.

To express it another way, we have associated a, b and c with the parameters used when calling the

function (x, y and z) and any change that we do on a within the function will affect the value of x

outside. Any change that we do on b will affect y, and the same with c and z.

That is why our program's output, that shows the values stored in x, y and z after the call to

duplicate, shows the values of the three variables of main doubled.

If when declaring the following function:

void duplicate (int& a, int& b, int& c)

we had declared it thus:

void duplicate (int a, int b, int c)

that is, without the ampersand (&) signs, we would have not passed the variables by reference, but

their values, and therefore, the output on screen for our program would have been the values of x, y

and z without having been modified.

Passing by reference is an effective way to allow a function to return more than one single value. For

example, here is a function that returns the previous and next numbers of the first parameter passed.

FRIENDLY FUNCTIONS

Page 49: C++ Book

I

We have been emphasizing throughout this chapter that the private members cannot accessed from

outside the class. That is, a non-member function cannot have an access to private data of a class.

However, there could be a situation where we would like two classes to share a particular function.

For example, consider a case where two classes, manager if scientist, have been defined. We would

like to use a function income_tax( ) to operate the objects of both these classes. In such situations,

C++ allows the common function made friendly with both the classes, thereby allowing the function

to have access to private data of these classes. Such a function need not be a member of any of these

classes.

To make an outside function “friendly” to a class, we have to simply declare this function as a friend

of the class as shown below

Class ABC

{

……..

……..

public:

……..

……..

friend void xyz(void); //declaration

};

The function declaration should be preceded by the keyword friend. The function is defined Else

here in the program like a normal C++ function. The function definition does not "either the

keyword friend or the scope operator ::. The functions that are declared with thekeyword friend are

known as friend functions. A function can be declared as a friend in anynumber of classes. A friend

function, although not a member function has full access rights to the private members of the class.

Certain special characteristics of friend function :

It is not in the scope of the class to which it has been declared as friend.

Page 50: C++ Book

Since it is not in the scope of the class, it cannot be called using the object of that class.

It can be invoked like a normal function without the help of any object.

Unlike member functions, it cannot access the member names directly and has to object

name and dot membership operator with each member name.( e.g. A.x).

It can be declared either in the public or the private part of a class without affecting its

meaning.

Usually, it has the objects as arguments.

Example : Friend Function

#include <iostream>

using namespace std;

class sample

{

int a;

int b;

public :

void setvalue( )

{

a=25; b= 40;

}

friend float mean(sample s);

} ;

float mean(samp1e s)

{

return f1oat(s.a + s.b)/2.0;

int main( )

{

sample x; // object X

x.setva1ue( );

cout <<” Mean value = “ << mean (x) « “\n”;

Page 51: C++ Book

return 0;

The output of Program

Mean value = 32.5

The friend function accesses the class variables a and b by using the dot operator and the object

passed to it. The function call mean(x) passes the object x by value to the friend function.

Member functions of one class can be friend functions of another class. In such cases, they are

defined using the scope resolution operator, which is shown as follows:

c1ass x

{

………

………

int fun1( ); // member function of X

………

};

class Y

{

……..

………

friend int X :: funl( ); // funl () of X

…….. // is friend of y

};

The function funl( ) is a member of class X and a friend of class Y.

Page 52: C++ Book

We can also declare all the member functions of one class as the mend functions of anotlt class. In

such cases, the class is called a friend class. This can be specified as follows:

class Z

{

……….

friend class X; // all member functions of X are

//friends to Z

};

program demonstrates how mend functions work as a bridge between the classes.

#include <iostream>

using namespace std;

class ABC; //forward declaration

class XYZ

{

int x;

public :

void setvalue(int i)

{

x = i;

}

friend void max(XYZ, ABC);

};

class ABC

{

Page 53: C++ Book

int a;

public :

void setvalue(int i)

{

x = i;

}

friend void max(XYZ, ABC);

};

void max(XYZ m, ABC n) //definition of friend

{

if(m.x >= n.a)

cout<<m.x;

else

cout<<n.a;

}

int main( )

{

ABC abc;

Abc.setvalue(10);

XYZ xyz;

xyz.setvalue(20);

max(xyz, abc);

return 0;

}

output

20

The function max( ) has arguments from both XYZ and ABC. When the function max( ) is declared

as a friend in XYZ for the first time, the compiler will not acknowledge the presence of ABC unless

its name is declared in the beginning as

Page 54: C++ Book

class ABC;

This is known as 'forward' declaration.

As pointed out earlier, a friend function can be called by reference. In this case, local copies of the

objects are not made. Instead, a pointer to the address of the object is passed and the called function

directly works on the actual object used in the call.

This Method can be used to alter the values of the private member of a class. Remember, altering

the values of private members is against the basic principles of data hiding. It should be used only

when absolutely necessary.

Summary

A function is a block of instructions that is executed when it is called from some other point

of the program.

Passing by reference is an effective way to allow a function to return more than one single

value.

C++ allows the common function made friendly with both the classes, thereby allowing the

function to have access to private data of these classes. Such a function need not be a

member of any of these classes.

Questions

1.What is friend function? Explain it’s characteristic

2.state the merits and demerits of friend function

3..How member function of a class is defined?

3. point ot errors in the following program if any

void main()

Page 55: C++ Book

{

int a=30;

f();

}

void f()

{

int b=20;

}

Page 56: C++ Book

UNIT I

Lesson 5

CONTROL STRUCTURES :

Objective

After getting an idea what function is, today we will discuss commonly used control structures of

programming language such as

if and else

The while loop.

The do-while loop.

The for loop.

The break instruction.

The selective Structure: switch.

A program is usually not limited to a linear sequence of instructions. During its process it may

bifurcate, repeat code or take decisions. For that purpose, C++ provides control structures that serve

to specify what has to be done to perform our program.

With the introduction of control sequences you are going to have an introduction to a new concept:

the block of instructions. A block of instructions is a group of instructions separated by semicolons

(;) but grouped in a block delimited by curly bracket signs: { and }.

Most of the control structures that you will see in this section allow a generic statement as a

parameter, this refers to either a single instruction or a block of instructions, as we want. If we want

the statement to be a single instruction we do not need to enclose it between curly-brackets ({}). If

you want the statement to be more than a single instruction you must enclose them between curly

brackets ({}) forming a block of instructions.

Page 57: C++ Book

Conditional structure: if and else

It is used to execute an instruction or block of instructions only if a condition is fulfilled. Its form is:

if (condition) statement

where condition is the expression that is being evaluated. If this condition is true, statement is

executed. If it is false, statement is ignored (not executed) and the program continues on the next

instruction after the conditional structure.

For example, the following code fragment prints out x is 100 only if the value stored in variable x

is indeed 100:

if (x == 100)

  cout << "x is 100";

If we want more than a single instruction to be executed in case that condition is true we can

specify a block of instructions using curly brackets { }:

if (x == 100)

 {

  cout << "x is ";

  cout << x;

 }

We can additionally specify what we want that happens if the condition is not fulfilled by using the

keyword else. Its form used in conjunction with if is:

if (condition) statement1 else statement2

For example:

if (x == 100)

  cout << "x is 100";

else

  cout << "x is not 100";

prints out on the screen x is 100 if indeed x is worth 100, but if it is not -and only if not- it prints

out x is not 100.

The if + else structures can be concatenated with the intention of verifying a range of values. The

following example shows its use telling if the present value stored in x is positive, negative or none

of the previous, that is to say, equal to zero.

Page 58: C++ Book

if (x > 0)

  cout << "x is positive";

else if (x < 0)

  cout << "x is negative";

else

  cout << "x is 0";

Remember that in case we want more than a single instruction to be executed, we must group them

in a block of instructions by using curly brackets { }.

Repetitive structures or loops

Loops have as objective to repeat a statement a certain number of times or while a condition is

fulfilled.

The while loop.

Its format is:

while (expression) statement

and its function is simply to repeat statement while expression is true.

For example, we are going to make a program to count down using a while loop:

// custom countdown using while

#include <iostream.h>

int main ()

{

int n;

cout << "Enter the starting number > ";

cin >> n;

while (n>0) {

cout << n << ", ";

--n;

}

cout << "FIRE!";

return 0;

}

Page 59: C++ Book

output

Enter the starting number > 88, 7, 6, 5, 4, 3, 2, 1, FIRE!

When the program starts the user is prompted to insert a starting number for the countdown.

Then the while loop begins, if the value entered by the user fulfills the condition n>0 (that n

be greater than 0 ), the block of instructions that follows will execute an indefinite number of

times while the condition (n>0) remains true.

All the process in the program above can be interpreted according to the following script:

beginning in main:

1. User assigns a value to n.

2. The while instruction checks if (n>0). At this point there are two possibilities:

o true: execute statement (step 3,)

o false: jump statement. The program follows in step 5..

3. Execute statement:cout << n << ", ";

--n;

(prints out n on screen and decreases n by 1).

4. End of block. Return Automatically to step 2.

5. Continue the program after the block: print out FIRE! and end of program.

We must consider that the loop has to end at some point, therefore, within the block of

instructions (loop's statement) we must provide some method that forces condition to

become false at some moment, otherwise the loop will continue looping forever. In this case

we have included --n; that causes the condition to become false after some loop

repetitions: when n becomes 0, that is where our countdown ends.

Page 60: C++ Book

Of course this is such a simple action for our computer that the whole countdown is

performed instantly without practical delay between numbers.

The do-while loop.

Format:

do statement while (condition);

Its functionality is exactly the same as the while loop except that condition in the do-while

is evaluated after the execution of statement instead of before, granting at least one

execution of statement even if condition is never fulfilled. For example, the following

program echoes any number you enter until you enter 0.

// number echoer

#include <iostream.h>

int main ()

{

unsigned long n;

do {

cout << "Enter number (0 to end): ";

cin >> n;

cout << "You entered: " << n << "\n";

} while (n != 0);

return 0;

}

output

Enternumber(0toend):12345Youentered:12345Enternumber(0toend):160277Youentered:160277Enternumber(0toend):0You entered:0

Page 61: C++ Book

The do-while loop is usually used when the condition that has to determine its end is

determined within the loop statement, like in the previous case, where the user input within

the block of intructions is what determines the end of the loop. If you never enter the 0 value

in the previous example the loop will never end.

The for loop.

Its format is:

for (initialization; condition; increase) statement;

and its main function is to repeat statement while condition remains true, like the while

loop. But in addition, for provides places to specify an initialization instruction and an

increase instruction. So this loop is specially designed to perform a repetitive action with a

counter.

It works the following way:

1, initialization is executed. Generally it is an initial value setting for a

counter varible. This is executed only once.

2, condition is checked, if it is true the loop continues, otherwise the loop

finishes and statement is skipped.

3, statement is executed. As usual, it can be either a single instruction or a

block of instructions enclosed within curly brackets { }.

4, finally, whatever is specified in the increase field is executed and the loop

gets back to step 2.

Here is an example of countdown using a for loop.

// countdown using a for loop

#include <iostream.h>

int main ()

{

for (int n=10; n>0; n--) {

cout << n << ", ";

}

cout << "FIRE!";

return 0;

}

Page 62: C++ Book

output 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

The initialization and increase fields are optional. They can be avoided but not the

semicolon signs among them. For example we could write: for (;n<10;) if we want to

specify no initialization and no increase; or for (;n<10;n++) if we want to include

an increase field but not an initialization.

Optionally, using the comma operator (,) we can specify more than one instruction in any of

the fields included in a for loop, like in initialization, for example. The comma operator

(,) is an instruction separator, it serves to separate more than one instruction where only one

instruction is generally expected. For example, suppose that we wanted to intialize more than

one variable in our loop:

for ( n=0, i=100 ; n!=i ; n++, i-- )

{

// whatever here...

}

This loop will execute 50 times if neither n nor i are modified within the loop:

n starts with 0 and i with 100, the condition is (n!=i) (that n be not equal to i). Beacuse n is

increased by one and i decreased by one, the loop's condition will become false after the

50th loop, when both n and i will be equal to 50.

Bifurcation of control and jumps.

The break instruction.

Page 63: C++ Book

Using break we can leave a loop even if the condition for its end is not fulfilled. It can be

used to end an infinite loop, or to force it to end before its natural end. For example, we are

going to stop the count down before it naturally finishes (an engine failure maybe):

// break loop example

#include <iostream.h>

int main ()

{

int n;

for (n=10; n>0; n--) {

cout << n << ", ";

if (n==3)

{

cout << "countdown aborted!";

break;

}

}

return 0;

}

output

10, 9, 8, 7, 6, 5, 4, 3, countdown aborted

The continue instruction.

The continue instruction causes the program to skip the rest of the loop in the present

iteration as if the end of the statement block would have been reached, causing it to jump to

the following iteration. For example, we are going to skip the number 5 in our countdown:

// break loop example

#include <iostream.h>

int main ()

{

for (int n=10; n>0; n--) {

if (n==5) continue;

Page 64: C++ Book

cout << n << ", ";

}

cout << "FIRE!";

return 0;

}10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE!

The goto instruction.

It allows making an absolute jump to another point in the program. You should use this

feature carefully since its execution ignores any type of nesting limitation.

The destination point is identified by a label, which is then used as an argument for the goto

instruction. A label is made of a valid identifier followed by a colon (:).

This instruction does not have a concrete utility in structured or object oriented programming

aside from those that low-level programming fans may find for it. For example, here is our

countdown loop using goto:

// goto loop example

#include <iostream.h>

int main ()

{

int n=10;

loop:

cout << n << ", ";

n--;

if (n>0) goto loop;

cout << "FIRE!";

return 0;

}

Output

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE

The exit function.

exit is a function defined in cstdlib (stdlib.h) library.

Page 65: C++ Book

The purpose of exit is to terminate the running program with an specific exit code. Its

prototype is:

void exit (int exit code);

The exit code is used by some operating systems and may be used by calling programs. By

convention, an exit code of 0 means that the program finished normally and any other

value means an error happened.

The selective Structure: switch.

The syntax of the switch instruction is a bit peculiar. Its objective is to check several possible

constant values for an expression, something similar to what we did at the beginning of this section

with the linking of several if and else if sentences. Its form is the following:

switch (expression) {  case constant1:    block of instructions 1

    break;  case constant2:    block of instructions 2

    break;  .  .  .  default:    default block of instructions

  }

It works in the following way: switch evaluates expression and checks if it is equivalent to

constant1, if it is, it executes block of instructions 1 until it finds the break keyword, then

the program will jump to the end of the switch selective structure.

If expression was not equal to constant1 it will check if expression is equivalent to constant2.

If it is, it will execute block of instructions 2 until it finds the break keyword.

Finally, if the value of expression has not matched any of the previously specified constants (you

Page 66: C++ Book

may specify as many case sentences as values you want to check), the program will execute the

instructions included in the default: section, if this one exists, since it is optional.

Both of the following code fragments are equivalent:

switch example

switch (x) {

case 1:

cout << "x is 1";

break;

case 2:

cout << "x is 2";

break;

default:

cout << "value of x unknown";

}

if-else equivalent

if (x == 1) {

cout << "x is 1";

}

else if (x == 2) {

cout << "x is 2";

}

else {

cout << "value of x unknown";

}

We have mentioned before that the syntax of the switch instruction is a bit peculiar. Notice the

inclusion of the break instructions at the end of each block. This is necessary because if, for

example, we did not include it after block of instructions 1 the program would not jump to the

end of the switch selective block (}) and it would continue executing the rest of the blocks of

instructions until the first appearance of the break instruction or the end of the switch selective

block. This makes it unnecessary to include curly brackets { } in each of the cases, and it can also

be useful to execute the same block of instructions for different possible values for the expression

evaluated. For example:

Page 67: C++ Book

switch (x)

{

case 1:

case 2:

case 3:

cout << "x is 1, 2 or 3";

break;

default:

cout << "x is not 1, 2 nor 3";

}

Notice that switch can only be used to compare an expression with different constants. Therefore

we cannot put variables (case (n*2):) or ranges (case (1..3):) because they are not valid

constants.

If you need to check ranges or values that are not constants use a concatenation of if and else if

sentences.

Summary

C++ provides control structures that serve to specify what has to be done to perform our

program.

If & else is used to execute an instruction or block of instructions only if a condition is

fulfilled

The if + else structures can be concatenated with the intention of verifying a range of values

Loops have as objective to repeat a statement a certain number of times or while a condition

is fulfilled.

The do-while loop is usually used when the condition that has to determine its end is

determined within the loop statement, like in the previous case, where the user input within

the block of instructions is what determines the end of the loop

Using break we can leave a loop even if the condition for its end is not fulfilled

Page 68: C++ Book

The continue instruction causes the program to skip the rest of the loop in the present

iteration as if the end of the statement block would have been reached, causing it to jump to

the following iteration

Switch objective is to check several possible constant values for an expression, something

similar to what we did at the beginning of this section with the linking of several if and else if

sentences

Questions

1.Discus various control structure available in C++

2.Explain implementation of switch statement with syntax and example

write a program to print following using for loop

1

22

333

444

5555

Page 69: C++ Book

UNIT I

Lesson 6

REPRESENTATION OF ABSTRACT DATA TYPES & SCOPE OF ATTRIBUTES

Objective

Concept of abstraction

Abstract Data type.

Designing an Abstract type

Choice of representation

Uptil now you have learned some basic concepts like operator set, control structure etc. now lets

have a look to the advanced feature of object oriented programming. One of them is abstract data

tpye. Here in this chapter I will explain its concept along with examples.

The Concept of Abstraction

The concept of abstraction is fundamental in programming

Two kinds of abstraction: process abstraction and data abstraction

Nearly all programming languages support process abstraction with subprograms

Nearly all programming languages designed since 1980 have supported data abstraction with

some kind of module

Introduction to Data Abstraction

Abstract data type: an encapsulation that includes only the data representation of one

specific data type and the subprograms that provide the operations for that type.

Built-in types are abstract data types Example: floating-point types

Actual format of the data value is hidden (users cannot directly manipulate actual

representation)

The only operations available are those provided by the language (users cannot create new

operations)

User-defined abstract data types must have the same characteristics as built-in abstract data

types

Page 70: C++ Book

An Example

ADT for a stack

Abstract operations

Queue ADT

create(stack) /* create (allocate storage) and possible initialize */

destroy(stack) /* dealloacte storage */

empty(stack) /* predicate */

push(stack, element) /* push element */

pop(stack) /* remove top element */

top(stack) /* returns a copy of top element */

Implementation of stack can be changed (e.g., from array to linked list) without

changing the client code.

Abstract Data Types in C++

Since it is based on object-oriented programming, it supports ADTs by classes.

ADTs allows the creation of instances with well-defined properties and behaviour. In object-

orientation ADTs are referred to as classes. Therefore a class defines properties of objects which

are the instances in an object-oriented environment.

ADTs define functionality by putting main emphasis on the involved data, their structure,

operations as well as axioms and preconditions. Consequently, object-oriented programming is

``programming with ADTs'': combining functionality of different ADTs to solve a problem.

Therefore instances (objects) of ADTs (classes) are dynamically created, destroyed and used.

Encapsulation

o Data members and member functions

o Class instances (or objects) can be stack dynamic or heap dynamic

o Stack-dynamic instances are referenced directly with variables

Page 71: C++ Book

o Heap-dynamic instances are referenced through pointers

o A stack-dynamic instance may have heap-dynamic data members

Information Hiding

o A class can have both hidden and visible entities

o Private for hidden entities

o Public for interface entities

o Protected for inheritance

Constructors:

o Functions to initialize the data members of instances

o May also allocate storage if part of the object is heap-dynamic

o Can include parameters to provide parameterization of the objects

o Implicitly called when an instance is created

o Can be explicitly called

o Can be more than one constructor

o Name is the same as the class name

Destructors

o Functions to cleanup after an instance is destroyed; usually just to reclaim

heap storage

o Implicitly called when the object’s lifetime ends

o Can be explicitly called

o Name is the class name, preceded by a tilde (~)

o All heap-dynamic objects must be explicitly deallocated by delete

C++ Example

#include <iostream.h>

class stack

{

private:

Page 72: C++ Book

int *stackPtr;

int maxLen;

int topPtr;

public:

stack()

{

stackPtr = new int [100];

maxLen 99;

topPtr = -1;

} // stack

~stack()

{

delete [] stackPtr;

}

void push (int number)

{

if (topPtr == maxLen)

cerr << “error in push – stack is full\n”;

else stackPtr[++topPtr] = number;

}

void pop()

{

if (topPtr = = -1)

cerr << “error in pop – stack is empty\n”;

else topPtr--;

}

int top()

{

return (stackPtr[topPtr]);

}

int empty()

Page 73: C++ Book

{

return (topPtr == -1);

}

} // stack

void main()

{

int topOne;

stack stk;

stk.push(42);

stk.push(17);

topOne = stk.top();

stk.pop();

}

Designing an Abstract Type

Designing an abstract type involves choosing good operations and determining how they should

behave. A few rules of thumb

o It’s better to have a few, simple operations that can be combined in powerful ways than lots

of complex operations.

o Each operation should have a well-defined purpose, and should have a coherent behavior

rather than a panoply of special cases.

o The set of operations should be adequate; there must be enough to do the kinds of

computations clients are likely to want to do. A good test is to check that every property of

an object of the type can be extracted. For example, if there were no get operation, we would

not be able to find out what the elements of the list are. Basic information should not be

inordinately difficult to obtain. The size method is not strictly necessary, because we could

apply get on increasing indices, but this is inefficient and inconvenient.

Page 74: C++ Book

o The type may be generic: a list or a set, or a graph, for example. Or it may be domain-

specific: a street map, an employee database, a phone book, etc. But it should not mix generic

and domain-specific features.

Choice of Representations

So far, we have focused on the characterization of abstract types by their operations. In the code a

class that implements an abstract type provides a representation: the actual data structure that

supports the operations.

The implementation of an ADT provides a representation of the type and implementations of the

functions. It is written in the programming language that you are using, such as C/C++.

Linked lists are a common representation of lists, for example. The following object model shows

a linked list implementation similar (but not identical to) the Linked List class in the standard

library.

header

next prev

element

The list object has a field header that references an Entry object. An Entry object is arecord with

three fields: next and prev which may hold references to other Entry objects(or be null), and element,

which holds a reference to an element object. The next and prevfields are links that point forwards

and backwards along the list. In the middle of the list,following next and then prev will bring you

back to the object you started with. Let’s assume that the linked list does not store null references as

elements. There is always a dummy Entry at the beginning of the list whose element field is null, but

this is not interpreted as an element.

Summary

List

Entry

Object

Page 75: C++ Book

The implementation of an ADT provides a representation of the type and implementations of

the functions. It is written in the programming language that you are using, such as C/C++.

ADTs allows the creation of instances with well-defined properties and behaviour

In object-orientation ADTs are referred to as classes. Therefore a class defines properties of

objects which are the instances in an object-oriented environment.

Questions

1. State the concept of abstract data type along with its types

Page 76: C++ Book

Lesson 7

GROUP DISCUSSION ON

Basic concept of OOPS

Classe s and objects

Features of C++

Page 77: C++ Book

UNIT I

LESSON 8

CONSTRUCTOR

Objectives

Concept of constructor

Parameterized constructor

Multiple constructors in a class

We will now discuss about ‘special member functions’ of a ‘class’ called ‘Constructors’

Constructors

Each time when you write a program you create a function, which is responsible for initializing the

variable, and before the end of the program you call a function to destroy the allocated variables. To

automate this feature C++ provides a concept of constructors and destructors.

C++ provides a constructor is a 'special' member function whose task is to initialize the objects of its

class. It is special because its name is the same as the class name. The constructor is invoked

whenever an object of its associated class is created. It is called constructor because it constructs the

values of data members of the class.

A constructor is declared and defined as follows:

/ / class with a constructor

class integer

{

int m, n;

public:

integer(void); / / constructor declared

……….

……….

Page 78: C++ Book

} ;

integer:: integer(void) / / constructor defined

{

m = 0; n = 0;

}

When a class contains a constructor like the one defined above, it is guaranteed that an object created

by the class will be initialized automatically. For example, the declaration

integer int1 ; / / object int1 created

not only creates the object int1 of type integer but also initializes its data members m and n to zero.

There is no need to write an Y, statement to invoke the constructor function (as we do with the

normal member functions): If a 'normal' member function is defined for zero initialization, we would

need to invoke this function for each of the objects separately. This would be very inconvenient, if

there are a large number of objects.

A constructor that accepts no parameters is called the default constructor. The default constructor for

class A is A::AO. If no such constructor is defined, then the compiler supplies a default constructor.

Therefore a statement such as

A a;

invokes the default constructor of the compiler to create the object a.

Special characteristics of constructor functions :

They should be declared in the public section.

They are invoked automatically when the objects are created.

They do not have return types, not even void and therefore, and they cannot return values.

Page 79: C++ Book

They cannot be inherited, though a derived class can call the base class constructor. . Like

other C++ functions, they can have default arguments.

Constructors cannot be virtual. (Meaning of virtual will be discussed later in Chapter 9.)

We cannot refer to their addresses.

An object with a constructor (or destructor) cannot be used as a member of a union. . They

make 'implicit calls' to the operators new and delete when memory allocation is required.

Remember, when a constructor is declared for a class, initialization of the class objects becomes

mandatory.

Parameterized Constructors

Constructor integer(), which we defined above, initializes the data members of all the objects to

zero. However, in practice it may be necessary to initialize the various data elements of different

objects with different values when they are created. C++ permits us to achieve this objective by

passing arguments to the constructor function when the objects are created. The constructors that can

take arguments are called parameterized constructors.

Constructor integer() may be modified to take arguments as shown below:

class integer {

int m, n;

public:

integer(int x, int y); / / parameterized constructor

};

integer :: integer(int x, int y)

{

m = x; n = y ;

}

When a constructor has been parameterized, the object declaration statement such as

integer intl ;

Page 80: C++ Book

may not work. We must pass the initial values as arguments to the constructor function when an

object is declared. This can be done in two ways:

By calling the constructor explicitly.

By calling the constructor implicitly.

The following declaration illustrates the first method:

integer intl = integer(0,l00); / / explicit call

This statement creates an integer object int1 and passes the values 0 and 100 to it. The second is

implemented as follows:

integer intl(0,l00); / / implicit call

This method, sometimes called the shorthand method, is used very often as it is shorter, looks better

and is easy to implement.

Remember, when the constructor is parameterized, we must provide appropriate arguments for the

constructor. Program demonstrates the passing of arguments to the constructor functions.

Ex. Of parameterized constructor

# include<iostream>

using namespace std;

class integer

{

int m, n;

public:

integer(int, int); // constructor declared

void display(void)

{

cout «”m=” « m<<"\n";

Page 81: C++ Book

cout «”n=" «n «”\n";

}

};

integer :: integer(int x. int y) // constructor defined

{

m = x;

n= y;

}

int main()

{

integer int1(O.l00); // constructor called implicitly

integer int2 = integer(25,75); // constructor called explicitly

cout « “ \nOBJECTl " «"\n";

int1.dtsplay();

cout « "\nOBJECT2" « '"\n";

int2.display();

return 0;

}

Program output:

OBJECT l

m =0

n = 100

Page 82: C++ Book

OBJ ECT2

m = 25

n = 75

The constructor functions can also be defined as inline functions. Example:

class integer

{

int m, n;

public:

integer(int x, int y) // Inline constructor

{

m = x; Y = n;

}

………….

………….

};

The parameters of a constructor can be of any type except that of the class to which it belongs. For

example,

class A

public:

A(A);

} ;

is illegal.

However, a constructor can accept a reference to its own class as a parameter. Thus, the statement

Class A {

public:

A(A&);

} ;

is valid. In such cases, the constructor is called the copy constructor.

Page 83: C++ Book

MULTIPLE CONSTRUCTORS IN A CLASS

So far we have used two kinds of constructors. They are:

integer () ; // No arguments

jnteger(int, int); // Two arguments

In tbe first case, the constructor itself supplies the data values and no values are passed by

the calling program. In the second case, the function call passes the appropriate values fromMain().

C++ permits us to use both these constructors in the same class. For example, wecould define a

class as follows:

class integer

{

int m, n;

public :

integer() // constructor 1

{

m=0; n=0;

}

integer(int a, int b) // constructor 2

{

m=a;n=b;

}

integer (integer & i) // constructor 3

{

m = i.m;

n = i.n;

}

This declares three constructors for an integer object. The first constructor receives no Inguments,

the second receives two integer arguments and the third receives one integer ~Ject as an argument.

Page 84: C++ Book

For example, the declaration

integer I1;

would automatically invoke the first constructor and set both m and n of I1 to zero. The statement

integer I2(20,40);

would call the second constructor which will initialize the data members m and n of I2 to 20 and 40

respectively. Finally, the statement

integer I3(12);

would invoke the third constructor which copies the values of I2 into I3. In other words, it sets the

value of every data element of I3 to the value of the corresponding data element of I2.

As mentioned earlier, such a constructor is called the copy constructor. We learned in Chapter 4 that

the process of sharing the same name by two or more functions is referred to as function

overloading. Similarly, when more than one constructor function is defined in aclass, we say that the

constructor is overloaded.

I

#include<iostream>

using namespace std;

class complex

{

float x ,y;

public :

complex() // constructor no arg

{

}

complex(float a) // constructor – one argument

Page 85: C++ Book

{ x = y = a;

}

complex( float real, float imag) // constructor – two arg

{

x = real;

y = imag;

}

friend complex sum(complex ,complex);

friend void show(complex);

};

complex sum(complex c1,complex c2) // friend

{

complex c3;

c3.x=c1.x+c2.x;

c3.y=c1.y+c2.y;

return(c3);

}

void show(complex c) // friend

{

cout <<c.x<<”+j”<<c.y<<”\n”;

}

int main()

{

complex A(2.7,3.5); //define & initialize

complex B(1.6); //define and initialize

complex C; //define

C=sum(A,B);

Page 86: C++ Book

Cout << “A=”; show(A); //sum() is a friend

Cout << “B=”; show(B); //sum() is a friend

cout << “C=”; show(C); //sum() is a friend

//another way to give initial values (second method)

complex P,Q,R; // define P, Q ,R

p= complex(2.5,3.9); // initialize P

Q= complex(1.6,2.5); // initialize Q

R= sum(P,Q);

Cout <<”\n”;

Cout <<”P = “; show(P);

Cout <<”Q = “; show(Q);

Cout <<”R = “; show(R);

Return 0;

}

output will be

A=2.7+J3.5

B=1.6+J1.6

C=4.3+J5.1

P=2.5+J3.9

Q=1.6+J2.5

R=4.1+J6.4

Page 87: C++ Book

There are three constructors in the class complex. The first constructor, which takes no arguments, is

used to create objects which are not initialized; the second, which takes one argument, is used to

create objects and initialize them; and the third, which takes two arguments, is also used to create

objects and initialize them to specific values. Note that the second method

Summary

C++ provides a constructor is a 'special' member function whose task is to initialize the

objects of its class. It is special because its name is the same as the class name.

The constructor is invoked whenever an object of its associated class is created. It is call

constructor because it constructs the values of data members of the class.

A constructor that accepts no parameters is called the default constructor. The default

constructor for class A is A::AO.

Questions

1 . Deifne constructor concept along with example

2 What is parameterised constructor ? explain with example.

Page 88: C++ Book

UNIT I

Lesson 9

CONSTRUCTOR II

Objectives

Constructor with default arguments

Copy constructor

Destructor

CONSTRUCTORS WITH DEFAULT ARGUMENTS

It is possible to define constructors with default arguments. For example, the constructor complexO

can be declared as follows:

complex(float real, float imag=0);

The default value of the argument imag is zero. Then, the statement

complex C(5.0);

I

assigns the value 5.0 to the real variable and 0.0 to imag (by default). However, the statement

complex C(2.0,3.0);

assigns 2.0 to real and 3.0 to imag. The actual parameter, when specified, Overrides the default

value. As pointed out earlier, the missing arguments must be the trailing ones. .

COPY CONSTRUCTOR

A copy constructor is used to declare and initialize an object from another

object. For example, the statement

integer 12(11);

Page 89: C++ Book

would define the object 12 and at the same time initialize it to the values of Il. Another form of this

statement is

integer I2 = 11;

The process of initializing through a copy constructor is known as copy initialization. Remember,

the statement

I2 = 11;

will not invoke the copy constructor. However, if Il and I2 are objects, this statement is legal and

simply assigns the values of I1 to I2, member-by-member. This is the task of the overloaded

assignment operator(=). We shall see more about this later.

A copy constructor takes a reference to an object of the same class as itself as an argument. Let us

consider a simple example of constructing and using a copy constructor

# include<iostream>

using namespace std;

class code

{

int id;

public:

code() // constructor

{

}

code(int a) // constructor

{

id = a;

}

code( code & x) // copy constructor

{

id=x.id; // copy in the value

}

Page 90: C++ Book

void display (void)

{

cout <<id;

}

};

int main()

{

code A(100); // object A is created and initialized

code B(A); // copy constructor called

code C=A; // copy constructor called again

code D; // D is created not initialized

D=A; // copy constructor not called

Cout <<”\n id of A:”; A.display();

Cout <<”\n id of B:”; B.display();

Cout <<”\n id of C:”; C.display();

Cout <<”\n id of D:”; D.display();

Return 0;

}

Page 91: C++ Book

DESTRUCTORS

A destructor, as the name implies, is used to destroy the objects that have been created by a

constructor. Like a constructor, the destructor is a member function whose name is the same as the

class name but is preceded by a tilde. For example, the destructor for the class integer

can be defined as shown below:

~integer( )

{

}

A destructor never takes any argument nor does it return any value. It will be invoked implicitly by

the compiler upon exit from the program (or block or function as the case may be) to clean up

storage that is no longer accessible. It is a good practice to declare destructors in a program since it

releases memory space for future use.

Whenever new is used to allocate memory in the constructors, we should use delete to

free that memory. For example, the destructor for the matrix class discussed above may be

defined as follows:

matrix :: ~matrix()

{

for (int I=0;I<d1;I++)

delete p[I];

delete p;

}

This is required because when the pointers to objects go out of scope, a destructor is not called

implicitly.

The example below illustrates that the destructor has been invoked implicitly by the compiler.

Implementation of destructor

Page 92: C++ Book

#include <iostream>

using namespace std;

int count = 0;

class alpha

{

public:

{ \

cout++;

cout « "\nNo.of object created" « count .

-alpha()

{

cout « "\nNo,of object destroyed" « count;

cout--;

}

};

int main()

{

alpha A1, A2, A3, A4;

{

cout « "\n\nENTERBLOCK1\n".

alpha A5;

}

{

cout « "\n\nENTER BLOCK2\n";

alpha A6;

}

cout « "\n\nRE-ENTER MAIN\n";

return 0;

}

output of the program is

Page 93: C++ Book

ENTER MA I N

No.of object created 1

No.of object created 2

No.of object created 3

No.of object created 4

ENTER BLOCKl

No.of object created 5

No.of object destroyed 5

ENTER BLOCK2

No.of object created 5

No.of object destroyed 5

RE-ENTER MAIN

No.of object destroyed 4

No.of object destroyed 3

No of object destroyed 2

No.of object destroyed 1

As the objects are created and destroyed. they increase and decrease the count. Notice that after the

first group of objects is created, A5 is created, and then destroyed, A6 is created, and then destroyed.

Finally, the rest of the objects are also destroyed. When the closing brace of a scope is encountered,

the destructors for each object in the scope are called. Note that the objects are destroyed in the

reverse order of creation.

Page 94: C++ Book

Summary

It is possible to define constructors with default arguments. For example, the constructor complexO

can be declared as follows:

complex(float real, float imag=0);

A copy constructor is used to declare and initialize an object from another object.

A destructor, as the name implies, is used to destroy the objects that

have been created by a constructor.

Questions

what is Destructor? Why it is necessary to define destructor in a program

explain copy constructor with suitable example?

Page 95: C++ Book

UNIT I

Lesson 10

OVERLOADING

Objective

Constructor Overloading

Operator Overloading

Overloading Unary Operators

Overloading Binary Operators“By now you all must have got a fair idea of how a function and its subsequent components viz.,

arguments/parameters play an important part when used in a C++ program. We also discussed about

function returning value by referring ‘directly to the variable’ called as ‘By Val’ and returning value

by referring ‘through the address of the variable’ called as ‘By Ref’. The topic, which we are

covering, now, is an important and unique feature of object-oriented programming. Lets explore it

now….”

OVERLOADED CONSTRUCTORS IN A CLASS

when more than one constructor function is defined in a class, we say that the constructor is

overloaded. Overloaded constructor are also known as multiple constructor in a class

we have used two kinds of constructors. They are:

integer () ; // No arguments

jnteger(int, int); // Two arguments

In the first case, the constructor itself supplies the data values and no values are passed by

The calling program. In the second case, the function call passes the appropriate values from Main().

C++ permits us to use both these constructors in the same class. For example, we

could define a class as follows:

Page 96: C++ Book

class integer

{

int m, n;

public :

integer() // constructor 1

{

m=0; n=0;

}

integer(int a, int b) // constructor 2

{

m=a;n=b;

}

integer (integer & i) // constructor 3

{

m = i.m;

n = i.n;

}

This declares three constructors for an integer object. The first constructor receives no arguments,

the second receives two integer arguments and the third receives one integer object as an argument.

For example, the declaration

integer I1;

would automatically invoke the first constructor and set both m and n of I1 to zero. The statement

integer I2(20,40);

would call the second constructor which will initialize the data members m and n of I2 to 20 and 40

respectively. Finally, the statement

integer I3(12);

would invoke the third constructor which copies the values of I2 into I3. In other words, it sets the

value of every data element of I3 to the value of the corresponding data element of I2. As mentioned

Page 97: C++ Book

earlier, such a constructor is called the copy constructor. We learned that that the process of sharing

the same name by two or more functions is referred to as function overloading. Similarly, when

more than one constructor function is defined in a class, we say that the constructor is overloaded.

#include<iostream>

class complex

{

float x ,y;

public :

complex() // constructor no arg

{

}

complex(float a) // constructor – one argument

{

x = y = a;

}

complex( float real, float imag) // constructor – two arg

{

x=real;

y=imag;

}

friend complex sum(complex ,complex);

friend void show(complex);

};

complex sum(complex c1,complex c2) // friend

{

complex c3;

c3.x=c1.x+c2.x;

c3.y=c1.y+c2.y;

Page 98: C++ Book

return(c3);

}

void show(complex c) // friend

{

cout <<c.x<<”+j”<<c.y<<”\n”;

}

int main()

{

complex A(2.7,3.5); //define & initialize

complex B(1.6); //define and initialize

complex C; //define

C=sum(A,B);

Cout << “A=”; show(A); //sum() is a friend

Cout << “B=”; show(B); //sum() is a friend

cout << “C=”; show(C); //sum() is a friend

//another way to give initial values (second method)

complex P,Q,R; // define P, Q ,R

p= complex(2.5,3.9); // initialize P

Q= complex(1.6,2.5); // initialize Q

R= sum(P,Q);

Cout <<”\n”;

Cout <<”P = “; show(P);

Cout <<”Q = “; show(Q);

Cout <<”R = “; show(R);

Page 99: C++ Book

Return 0;

}

output will be

A=2.7+J3.5

B=1.6+J1.6

C=4.3+J5.1

P=2.5+J3.9

Q=1.6+J2.5

R=4.1+J6.4

There are three constructors in the class complex. The first constructor, which takes no arguments, is

used to create objects which are not initialized; the second, which takes one argument, is used to

create objects and initialize them; and the third, which takes two arguments, is also used to create

objects and initialize them to specific values.

Operator Overloading

Operator overloading is one of the many exciting features of C++ language. It is an

importanttechnique that has enhanced the power of extensibility of C++. We have stated more once

that C++ tries to make the user-defined data types behave in much the same way as built-in types.

For instance, C++ permits us to add two variables of user-defined types!

the same syntax that is applied to the basic types. This means that C++ has the ability to provide the

operators with a special meaning for a data type. The mechanism of giving such special Meanings to

an operator is known as operator overloading.

Operator overloading provides a flexible option for the creation of new definitions for of the

C++ operators. We can almost create a new language of our own by the creative use the function and

operator overloading techniques. We can overload (give additional meaning to) all the C++

operators except the following:

Class member access operators (., . *).

Page 100: C++ Book

Scope resolution operator (::).

Size operator (sizeof).

Conditional operator (?:).

The excluded operators are very few when compared to the large number of operators, which qualify

for the operator overloading definition.

Although the semantics of an operator can be extended, we cannot change its syntax, the

grammatical rules that govern its use such as the number of operands, precedence and associativity.

For example, the multiplication operator will enjoy higher precedence than the addition operator.

Remember, when an operator is overloaded, its original meaning is not lost.

For instance, the operator +, which has been overloaded to add two vectors, can still be used to aid

two integers.

DEFINING OPERATOR OVERLOADING

To define additional task to an operator, we must specify what it means in relation to the class to

which the operator is applied. This is done with the help of a special function, called Operator

function, which describes the task. The general form of an operator function is:

return type classname :: operator (op-arg1ist)

{

Function body II task defined

}

where return type is the type of value returned by the specified operation and op is the operator

being overloaded. The op is preceded by the keyword operator. operator op is the function name.

Operator functions must be either member functions (non-static) or friend functions. A basic

difference between them is that a friend function will have only one argument for unary operators

and two for binary operators, while a member function has no arguments for unary operators and

only one for binary operators. This is because the object used to invoke the member function is

Page 101: C++ Book

passed implicitly and therefore is available for the member function. This is not the case with friend

functions. Arguments may be passed either by value or by reference. Operator functions are declared

in the class using prototypes as follows:

vector operator+(vector); I I vector addition

vector operator-(); I I unary minus

friend vector operator+(vector, vector) ; I I vector addition

friend vector operator-(vector); I I unary minus

vector operator-(vector &a); I I subtraction

int operator= =(vector); II comparison

friend int operator.== (vector , vector) I I comparison

vector is a data type of class and may represent both magnitude and direction (as in ph' and

engineering) or a series of points called elements (as in mathematics).

The process of overloading involves the following steps:

a. Create a class that defines the data type that is to be used in the overloading operation

b. Declare the operator function operator op() in the public part of the class. It may be either a

member function or a friend function.

c. Define the operator function to implement the required operations

Overloaded operator functions can be invoked by expressions such as

op x or x op

for unary operators and

x op Y

for binary operators. op x (or x op) would be interpreted as

operator op (x)

Page 102: C++ Book

for friend functions. Similarly, the expression x op y would be interpreted as either

x.operator op (y)

in case of member , or

operator op (x, y)

in case of friend functions. When both the forms are declared, standard argument matching is

applied to resolve any ambiguity.

OVERLOADING UNARY OPERATORS

Let us consider the unary minus operator. A minus operator when used as a unary, takes just one

operand. We know that this operator changes the sign of an operand when applied to a basic data

item. We will see here how to overload this operator so that it can be applied to an object in much

the same way as is applied to an int or float variable. The unary minus when applied to an object

should change the sign of each of its data items.

Program shows how the unary minus operator is overloaded.

OVERLOADING UNIARY MINUS

# incl,ude <iostream>

using namespace std;

class space

{

int x;

int y;

int z;

public:

void getdata(int a, int b, int c);

Page 103: C++ Book

void display(void);

void operator -(); //overload unary minus

};

void space::getdata(int a, int b, int c)

{

x = a;

y = b;

z = c;

}

void space :: display(void)

{

cout<< x<< “ “;

cout<< y <<” “ ;

cout<<z <<”\n “;

}

void space::operator-()

{

x = -x;

y = -y;

z = -z;

}

int main()

{

space S;

S.getdata(10, -20, 30);

Cout<< “S : “;

S.display();

-S; //activates operator-() function

cout<< “S :”;

S.display();

return 0;

Page 104: C++ Book

}

The Program produces the following output:

S : 10 -20 30

S : -10 20 –30

Remember:

The function operator- ( ) takes no argument. Then, what does this operator function do? It

changes the sign of data members of the object S. Since this function is a member function of the

same class, it can directly access the members of the object which activated it.

Remember, a statement like

S2 = -S1;

will not work because, the function operator-() does not return any value. It can work if the function

is modified to return an object.

It is possible to overload a unary minus operator using a friend function as follows:

friend void operator-(space &s); //dec1a ration

void operator- (space &s) // definition

{

s . x = -s. x ;

s . y = -s. y ;

s . z = -s. z;

}

Note that the argument is passed by reference. It Will not work if we pass argument by value

because only a copy of the object that activated the call is passed to operator-(). Therefore, the

changes made inside the operator function will not reflect in the called object.

OVERLOADING BINARY OPERATORS

Page 105: C++ Book

We have just seen how to overload a unary operator. The same mechanism can be used to overload a

binary operator. Here, we illustrated, how to add two complex numbers using a friend function. A

statement like

C = sum(A, B); // functional notation.

was used. The functional notation can be replaced by a natural looking expression

C = A + B; // arithmetic notation

by overloading the + operator using an operator+()function. The Program illustrates how

this is accomplished.

Overloading + operator

include <iostream>

using namespace std;

class complex

{

float x; / / real part

float y; 1/ imaginary part

publ ic:

complex() { } / / constructor 1

complex(float real ,float imag) { x = real; y =imag; } / / constructor 2

complex operator+(complex);

void display(void);

}

complex complex:: operator+(complex c)

{

complex temp; //temporary

temp. x = x + c.x; //these are

temp.y = y + c.y; //float additions

Page 106: C++ Book

return (temp);

}

void complex :: display(void)

{

cout << x <<"+ j << y <<"\n ";

}

int main()

{

complex Cl, C2, C3; // invokes constructor 1

Cl = complex(2.5, 3.5); // invokes constructor 2

C2 =complex(1.6, 2.7);

C3 = Cl + C2;

cout << "Cl = "; Cl.display();

cout << "C2 = "; C2.display();

cout << "C3 = “; C3.display();

return 0;

}

The output of Program would be:

C1 = 2.5 + j3.5

C2 = 1. 6 + j 2.7

C3 = 4.1 + j 6.2

Let us have a close look at the function operator+( ) and see how the operator overloading is

implemented.

complex complex :: operator+(complex c)

{

complex temp;

temp.x = x + c.x;

temp.y = y + c.y;

Page 107: C++ Book

return(temp);

}

We should note the following features of this function:

1. It receives only one complex type argument explicitly.

2. It returns a complex type value.

3. It is a member function of complex.

The function is expected to add two complex values and return a complex value as I result but

receives only one value as argument. Where does the other value come from?.

Now let us look at the statement that invokes this function:

C3 = C1 + C2; / / invokes operator+() function

We know that a member function can be invoked only by an object of the same class. Here the

object Cl takes the responsibility of invoking the function and C2 plays the role of: argument that is

passed to the function. The above invocation statement is equivalent to

C3 = C1.operator+(C2); / / usual function call syntax

Therefore, in the operator+() function, the data members of Cl are accessed directly the data

members of C2 (that is passed as an argument) are accessed using the dot operator

Thus, both the objects are available for the function. For example, in the statement

temp.x = x + c.x;

c.x refers to the object C2 and x refers to the object Cl.temp.x is the real part of temp has been

created specially to hold the results of addition of C land C2. The function return the complex temp

to be assigned to C3.

As a rule, in overloading of binary operators, the left-hand operand is used to invoke operator

function and the right- hand operand is passed as an argument.

Page 108: C++ Book

Summary

when more than one constructor function is defined in a class, we say that the constructor is

overloaded.

The process of overloading involves the following steps:

a. Create a class that defines the data type that is to be used in the overloading operation

b. Declare the operator function operator op() in the public part of the class. It may be either a

member function or a friend function.

c. Define the operator function to implement the required operations

Questions

Explain concept of Constructor Overloading

Explain concept of Operator Overloading

Explain concept of Unary and Binary Operator Overloading

Page 109: C++ Book

UNIT I

LESSON 11

OVERLOADING II

Objective

Concept of function overloading

In the previous lecture of ovrloading we have got concept of constructor and operator oveloading.

Here in this second part we will discuss most powerful application of OOP viz. Function

Oveloading, by which we can do variety of tasks . Let’s go through it.

FUNCTION OVERLOADING

Overloading refers to the use of the same thing for different purposes. C++ also permits overloading

of functions. This means that we can use the same function name to create functions that perform a

variety of different tasks. This is known as function polymorphism in OOP. The ability to have

various functions with the same name in the same program is called function overloading. The most

important rule about function overloading is to make sure that each one of these functions has a

different number or different type(s) of arguments.

Using the concept of function overloading; we can design a family of functions with one function

name but with different argument lists. The function would perform different, operations depending

on the argument list in the function call. The correct function to invoked is determined by checking

the number and type of the arguments but not on the function type. For example, an overloaded

add() function handles different types of data shown below:

/ / Declarations

int add(int a, int b); / / prototype 1

int add(int a, intb, int c); / / prototype 2

double add (double x, double y); / / prototype 3

double add(int p, double q); / / prototype 4

double add(double p, int q); / / prototype 5

/ / Function calls

cout « add(5, 10); / / uses prototype 1

cout « add(15, 10.0); / / uses prototype 2

Page 110: C++ Book

cout « add(12.5, 7.5); / / uses prototype 3

cout « add(5, 10. 15); / / uses prototype 4

cout « add(0.75, 5); / / uses prototype 5

A function call first matches the prototype having the same number and type of argument and then

calls the appropriate function for execution. A best match must be unique. The function

Selection involves following steps

1. The complier first tries to find an exact match in which the types of actual argument

are the same, and use that function.

2. If an exact match is not found, the compiler uses the integral promotions to the actual

argument, such as,

char to int

Float t to double

d. When either of them fails, the compiler tries to use the built-in conversions(the implicit

assignment. conversion) to the actual arguments and then uses function whose match is unique.

If the conversion is possible to have multimatches, then the compiler will generate an error

message.

e. Suppose we use following two functions:

long square(long n)

double square (double x)

A function call such as

square(10)

will cause an error because int argument can be converted to either long or double, thereby

creating an ambiguous situation as to which version of square() should be used.

Page 111: C++ Book

4. If all of the steps fail, then the compiler will try the user-defined conversions in combination

with integral promotions and built-in conversions to find a unique match. User-defined

conversions are often used in handling class objects.

Program illustrates function overloading.

// Function volume() is overloaded three times I

#include <iostream>

using namespace std;

// Declaration (prototypes)

int volume(int);

double volume( double, int) ;

long volume (long, int , int);

int main()

(

cout « volume(10) « "\n";

cout « volume(2.5,8) « "\n";

cout « volume(100L,75,15) « "\n";

return 0;

}

/ / Function definitions

int volume(int s) // cube

(

return(s*s*s);

}

Page 112: C++ Book

double volume(double r. int h) //cylinder

{

return (3 .14519,*r*r*h) ;

}

1ong volume (long l, int b, int h) //rectangular box

{

return (l*b*h);

}

The output of program:

1000

157.26

112500

Overloading of function should be done with caution. We should not overload unrelated functions

and should reserve function overloading for function that performs closely related tasks. Sometime,

the default arguments may be used instead of overloading. This may reduce the number of functions

to be defined.

Summary

The ability to have various functions with the same name in the same program is called

function overloading. The most important rule about function overloading is to make sure

that each one of these functions has a different number or different type(s) of arguments.

Overloading of function should be done with caution. We should not overload unrelated

functions and should reserve function overloading for function that performs closely related

tasks.

Questions

Explain the concept of Function Overloading with example

Page 113: C++ Book

UNIT I

LESSON 12

ARRAYS

Objectives.

Concept of Arrays

Multidimensional Arrays

Strings of Characters

Arrays are a series of elements (variables) of the same type placed consecutively in memory that can

be individually referenced by adding an index to a unique name.

For example, an array to contain 5 integer values of type int called billy could be represented this

way:

where each blank panel represents an element of the array, that in this case are integer values of type

int. These are numbered from 0 to 4 since in arrays the first index is always 0, independently of its

length .

Like any other variable, an array must be declared before it is used. A typical declaration for an array

in C++ is:

type name [elements];

where type is a valid object type (int, float...), name is a valid variable identifier and the elements

field, that is enclosed within brackets [], specifies how many of these elements the array contains.

Therefore, to declare billy as shown above it is as simple as the following sentence:

int billy [5];

Page 114: C++ Book

NOTE: The elements field within brackets [] when declaring an array must be a constant

value, since arrays are blocks of static memory of a given size and the compiler must be able

to determine exactly how much memory it must assign to the array before any instruction is

considered.

Initializing arrays.

When declaring an array of local scope (within a function), if we do not specify otherwise, it will not

be initialized, so its content is undetermined until we store some values in it.

If we declare a global array (outside any function) its content will be initialized with all its elements

filled with zeros. Thus, if in the global scope we declare:

int billy [5];

every element of billy will be set initialy to 0:

But additionally, when we declare an Array, we have the possibility to assign initial values to each

one of its elements using curly brackets { }. For example:

int billy [5] = { 16, 2, 77, 40, 12071 };

this declaration would have created an array like the following one:

The number of elements in the array that we initialized within curly brackets { } must match the

length in elements that we declared for the array enclosed within square brackets [ ]. For example,

in the example of the billy array we have declared that it had 5 elements and in the list of initial

values within curly brackets { } we have set 5 different values, one for each element.

Because this can be considered useless repetition, C++ includes the possibility of leaving the

brackets empty [ ] and the size of the Array will be defined by the number of values included

between curly brackets { }:

int billy [] = { 16, 2, 77, 40, 12071 };

Page 115: C++ Book

Access to the values of an Array.

In any point of the program in which the array is visible we can access individually anyone of its

values for reading or modifying as if it was a normal variable. The format is the following:

name[index]

Following the previous examples in which billy had 5 elements and each of those elements was of

type int, the name which we can use to refer to each element is the following:

For example, to store the value 75 in the third element of billy a suitable sentence would be:

billy[2] = 75;

and, for example, to pass the value of the third element of billy to the variable a, we could write:

a = billy[2];

Therefore, for all purposes, the expression billy[2] is like any other variable of type int.

Notice that the third element of billy is specified billy[2], since first is billy[0], the second is

billy[1], and therefore, third is billy[2]. By this same reason, its last element is billy[4]. Since

if we wrote billy[5], we would be acceding to the sixth element of billy and therefore exceeding

the size of the array.

In C++ it is perfectly valid to exceed the valid range of indices for an Array, which can create

problems since they do not cause compilation errors but they can cause unexpected results or serious

errors during execution. The reason why this is allowed will be seen farther ahead when we begin to

use pointers.

At this point it is important to be able to clearly distinguish between the two uses that brackets [ ]

have related to arrays. They perform two differt tasks: one is to set the size of arrays when declaring

them; and second is to specify indices for a concrete array element when referring to it. We must

simply take care not to confuse these two possible uses of brackets [ ] with arrays:

Page 116: C++ Book

int billy[5]; // declaration of a new Array (begins with a

type name)

billy[2] = 75; // access to an element of the Array.

Other valid operations with arrays:

billy[0] = a;

billy[a] = 75;

b = billy [a+2];

billy[billy[a]] = billy[2] + 5;

// arrays example

#include <iostream.h>

int billy [] = {16, 2, 77, 40, 12071};

int n, result=0;

int main ()

{

for ( n=0 ; n<5 ; n++ )

{

result += billy[n];

}

cout << result;

return 0;

}

output

12206

Multidimensional Arrays

Multidimensional arrays can be described as arrays of arrays. For example, a bidimensional array

can be imagined as a bidimensional table of a uniform concrete data type.

Page 117: C++ Book

jimmy represents a bidimensional array of 3 per 5 values of type int. The way to declare this array

would be:

int jimmy [3][5];

and, for example, the way to reference the second element vertically and fourth horizontally in an

expression would be:

jimmy[1][3]

(remember that array indices always begin by 0).

Multidimensional arrays are not limited to two indices (two dimensions). They can contain as many

indices as needed, although it is rare to have to represent more than 3 dimensions. Just consider the

amount of memory that an array with many indices may need. For example:

char century [100][365][24][60][60];

assigns a char for each second contained in a century, that is more than 3 billion chars! This would

consume about 3000 megabytes of RAM memory if we could declare it.

Multidimensional arrays are nothing more than an abstraction, since we can obtain the same results

with a simple array just by putting a factor between its indices:

int jimmy [3][5];   is equivalent to

int jimmy [15];   (3 * 5 = 15)

with the only difference that the compiler remembers for us the depth of each imaginary dimension.

Serve as example these two pieces of code, with exactly the same result, one using bidimensional

arrays and the other using only simple arrays:

Page 118: C++ Book

// multidimensional array

#include <iostream.h>

#define WIDTH 5

#define HEIGHT 3

int jimmy [HEIGHT][WIDTH];

int n,m;

int main ()

{

for (n=0;n<HEIGHT;n++)

for (m=0;m<WIDTH;m++)

{

jimmy[n][m]=(n+1)*(m+1);

}

return 0;

}

program above do not produce any output on the screen, but both assign values to the memory block

called jimmy in the following way:

We have used defined constants (#define) to simplify possible future modifications of the program,

for example, in case that we decided to enlarge the array to a height of 4 instead of 3 it could be done

by changing the line:

#define HEIGHT 3

to

#define HEIGHT 4

with no need to make any other modifications to the program.

Page 119: C++ Book

Arrays as parameters

At some moment we may need to pass an array to a function as a parameter. In C++ is not possible

to pass by value a complete block of memory as a parameter to a function, even if it is ordered as an

array, but it is allowed to pass its address. This has almost the same practical effect and it is a much

faster and more efficient operation.

In order to admit arrays as parameters the only thing that we must do when declaring the function is

to specify in the argument the base type for the array, an identifier and a pair of void brackets [].

For example, the following function:

void procedure (int arg[])

admits a parameter of type "Array of int" called arg. In order to pass to this function an array

declared as:

int myarray [40];

it would be enough to write a call like this:

procedure (myarray);

Here you have a complete example:

// arrays as parameters

#include <iostream.h>

void printarray (int arg[], int length) {

for (int n=0; n<length; n++)

cout << arg[n] << " ";

cout << "\n";

}

int main ()

{

int firstarray[] = {5, 10, 15};

int secondarray[] = {2, 4, 6, 8, 10};

printarray (firstarray,3);

printarray (secondarray,5);

return 0;

Page 120: C++ Book

}

output

5 10 152 4 6 8 10

As you can see, the first argument (int arg[]) admits any array of type int, whatever its length is.

For that reason we have included a second parameter that tells the function the length of each array

that we pass to it as the first parameter. This allows the for loop that prints out the array to know the

range to check in the passed array.

In a function declaration is also possible to include multidimensional arrays. The format for a

tridimensional array is:

base_type[][depth][depth]

for example, a function with a multidimensional array as argument could be:

void procedure (int myarray[][3][4])

notice that the first brackets [] are void and the following ones are not. This must always be thus

because the compiler must be able to determine within the function which is the depth of each

additional dimension.

Arrays, both simple or multidimensional, passed as function parameters are a quite common source

of errors for less experienced programmers.

Strings of Characters

In all programs seen until now, we have used only numerical variables, used to express numbers

exclusively. But in addition to numerical variables there also exist strings of characters, that allow us

to represent successions of characters, like words, sentences, names, texts, et cetera. Until now we

have only used them as constants, but we have never considered variables able to contain them.

In C++ there is no specific elemental variable type to store strings of characters. In order to fulfill

this feature we can use arrays of type char, which are successions of char elements. Remember that

this data type (char) is the one used to store a single character, for that reason arrays of them are

generally used to make strings of single characters.

Page 121: C++ Book

For example, the following array (or string of characters):

char jenny [20];

can store a string up to 20 characters long. You may imagine it thus:

This maximum size of 20 characters is not required to always be fully used. For example, jenny

could store at some moment in a program either the string of characters "Hello" or the string

"Merry christmas". Therefore, since the array of characters can store shorter strings than its total

length, a convention has been reached to end the valid content of a string with a null character,

whose constant can be written 0 or '\0'.

We could represent jenny (an array of 20 elements of type char) storing the strings of characters

"Hello" and "Merry Christmas" in the following way:

Notice how after the valid content a null character ('\0') it is included in order to indicate the end of

the string. The panels in gray color represent indeterminate values.

Initialization of strings

Because strings of characters are ordinary arrays they fulfill all their same rules. For example, if we

want to initialize a string of characters with predetermined values we can do it just like any other

array:

char mystring[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

In this case we would have declared a string of characters (array) of 6 elements of type char

initialized with the characters that compose Hello plus a null character '\0'.

Nevertheless, strings of characters have an additional way to initialize their values: using constant

strings.

In the expressions we have used in examples in previous chapters constants that represented entire

strings of characters have already appeared several times. These are specified enclosed between

double quotes ("), for example:

Page 122: C++ Book

"the result is: "

is a constant string that we have probably used on some occasion.

Unlike single quotes (') which specify single character constants, double quotes (") are constants

that specify a succession of characters. Strings enclosed between double quotes always have a null

character ('\0') automatically appended at the end.

Therefore we could initialize the string mystring with values by either of these two ways:

char mystring [] = { 'H', 'e', 'l', 'l', 'o', '\0' };

char mystring [] = "Hello";

In both cases the array or string of characters mystring is declared with a size of 6 characters

(elements of type char): the 5 characters that compose Hello plus a final null character ('\0')

which specifies the end of the string and that, in the second case, when using double quotes (") it is

automatically appended.

Before going further, notice that the assignation of multiple constants like double-quoted constants

(") to arrays are only valid when initializing the array, that is, at the moment when declared.

Expressions within the code like:

mystring = "Hello";

mystring[] = "Hello";

are not valid for arrays, like neither would be:

mystring = { 'H', 'e', 'l', 'l', 'o', '\0' };

So remember: We can "assign" a multiple constant to an Array only at the moment of initializing it.

The reason will be more comprehensible when you know a bit more about pointers, since then it will

be clarified that an array is simply a constant pointer pointing to an allocated block of memory. And

because of this constantnes, the array itself can not be assigned any value, but we can assing values

to each of the elements of the array.

The moment of initializing an Array it is a special case, since it is not an assignation, although the

same equal sign (=) is used. Anyway, always have the rule previously underlined present.

Assigning values to strings

Since the lvalue of an assignation can only be an element of an array and not the entire array, it

would be valid to assign a string of characters to an array of char using a method like this:

Page 123: C++ Book

mystring[0] = 'H';mystring[1] = 'e';mystring[2] = 'l';mystring[3] = 'l';mystring[4] = 'o';mystring[5] = '\0';

But as you may think, this does not seem to be a very practical method. Generally for assigning

values to an array, and more specifically to a string of characters, a series of functions like strcpy

are used. strcpy (string copy) is defined in the cstring (string.h) library and can be called the

following way:

strcpy (string1, string2);

This does copy the content of string2 into string1. string2 can be either an array, a pointer, or a

constant string, so the following line would be a valid way to assign the constant string "Hello" to

mystring:

strcpy (mystring, "Hello");

For example:

// setting value to string

#include <iostream.h>

#include <string.h>

int main ()

{

char szMyName [20];

strcpy (szMyName,"J. Soulie");

cout << szMyName;

return 0;

}output

J. Soulie

Notice that we needed to include <string.h> header in order to be able to use function strcpy.

Page 124: C++ Book

Although we can always write a simple function like the following setstring with the same

operation as cstring's strcpy:

// setting value to string

#include <iostream.h>

void setstring (char szOut [], char szIn [])

{

int n=0;

do {

szOut[n] = szIn[n];

} while (szIn[n++] != '\0');

}

int main ()

{

char szMyName [20];

setstring (szMyName,"J. Soulie");

cout << szMyName;

return 0;

}

output

J. Soulie

Summary

Arrays are a series of elements (variables) of the same type placed consecutively in memory

that can be individually referenced by adding an index to a unique name.

since arrays are blocks of static memory of a given size and the compiler must be able to

determine exactly how is considered.

Multidimensional arrays can be described as arrays of arrays. For example, a bidimensional

array can be imagined as a bidimensional table of a uniform concrete data type.

Questions

1. Explain Array with example

Page 125: C++ Book

2. What is multidiamentional array concept Explain with suitable

example.

3. Find errors in each of the following

a) Assume that

Char str[5];

Cin >>str; // User types hello

b) assume that

int a[3];

cout <<a[1]<<” “ <<a[2]<< “ “a[3]<< endl;

Page 126: C++ Book

UNIT ILesson 13

Pointers In C++

“ In the last lecture you learnt what is the concept of ‘Arrays’ Now we shift our focus to the most important topic from a programmers point of view, its about memory management. What do you percieve when we are talking about memory management? Is it related to managing storage spaces in the memory? To answer these questions, you will have to nose-dive into the memory block.”

Objective Introduction to the concept of Pointer

Introduction to Pointers

An Overview of Pointers

When writing a program, you declare the necessary variables that you will need in order to

accomplish your work. When declaring variables, you are simply asking the computer to reserve a

set amount of space in its memory for a particular object you want to use.  When you declare a

variable, the computer reserves an amount of space for that variable, and uses the variable's name to

refer to that memory space. This will allow you to store something, namely the value of that

variable, in that space. Indeed, the computer refers to that space using an address. Therefore,

everything you declare has an address, just like the address of your house. You can find out what

address a particular variable is using.

Here are a few things you know already about writing a program:

To use a variable, you declare it first to tell the compiler what kind of variable you are planning to

use and what its name is . Once you declare a variable, the compiler reserves and assigns it a portion

of space in memory and locates it there so that whenever you need that variable, you just call it and

then use it.

To use a function, you have to define it, tell the compiler what the function is supposed to do, and

whether the function is supposed to give back a result or not, after it has performed its assignment.

Page 127: C++ Book

To see a variable's address, you can use the & operator followed by the name of the variable. For

example, after declaring an integer as

int NumberOfStudents;

you can find the address where the NumberOfStudents variable is located by using:

cout << &NumberOfStudents;

This program would give you the address of the declared variable:

#include <iostream.h> int main( ){ int Value; cout << "Value lives at " << &Value; cout << "\n\n"; return 0;}After executing the program, you could get: 

Value lives at:

Press any key to continueDefinition

Unfortunately, I will explain later on "WHY" use pointers. This is because we first need to know

WHAT a pointer is, HOW to declare it inside of a function, and HOW to use it. Pointers are not

particularly useful when declared and used inside of one function. They show their capabilities when

different functions (and/or objects) exchange data stored in those pointers.

As you can see from the execution of the program above, the address of a variable is very difficult to

read and interpret. Fortunately, we don't need to know that address and we don't need to know what

it means or where the variable is located. C++ provides an alternative to this problem.

Instead of referring to a variable's address directly, you are allowed to declare another variable, and

Page 128: C++ Book

then use that new variable to refer to the address of the variable you are interested in. A pointer is a

variable that refers to another variable's address.

Just like any variable in C++, you should declare and initialize a pointer variable before using it. To

declare a pointer variable, use an identifier, followed by an asterisk (*), followed by the name of the

pointer, and a semi-colon. Here is the formula:

DateType * PointerName;

The identifier should be one of those we have learned already. This means it could be an int, a char,

a double, etc. The identifier should be the same type of identifier the pointer variable will point to.

Therefore, if you are declaring a pointer that will point to an integer variable, the pointer identifier

should be an integer.

The asterisk (*) lets the compiler know that the variable that follows is a pointer. There are three

ways you can type the asterisk. These are

DateType* PointerName;

DateType * PointerName;

DateType *PointerName;

By default, it does not matter how you append the *, the compiler will know that the thing that

follows is a variable.

Be careful when declaring various pointers. If you declare a few of them on the same line, like this:

DateType* Pointer1, Pointer2;

Only the first variable is a pointer, the second is a regular variable. If you want to declare different variables, you use:

DateType* Pointer1, *Pointer2;

Or

DateType* Pointer1;DateType* Pointer2;

Page 129: C++ Book

Since the name of the pointer is indeed the name of a variable, you will follow the naming rules that govern every C++ variable.

#include <iostream.h>

int main( ){ int Value; int *Pointer; cout << "Value lives at " << &Value << "\n"; cout << "Pointer lives at " << &Pointer; cout << "\n\n"; return 0;}

After executing the program, you might get:

Value lives at: Pointer lives at:

Press any key to continue

Initializing a Pointer

The reason you are using a pointer is to find an alternative to knowing the address of a variable.

Therefore, from now on, we are not interested in a variable's real address. Instead, we will use a

pointer to point to that variable.

As we have learned already, a variable should be initialized before being used. This allows the

compiler to put something into the memory space allocated for that variable.

To use a pointer P effectively, for its intended purpose, you need to tell the compiler that: pointer P

will be used to point to the address of variable V. You do this by initializing the pointer. A pointer is

initialized (almost) like any other variable, using the assignment operator (=).

There are two main ways you can initialize a pointer. When declaring a pointer like this:

Page 130: C++ Book

int* Pointer;

initialize it by following the assignment operator with & operator and the name of the variable, like

this

int* Pointer = &Variable;

You can also initialize a pointer on a different line, after declaring it. This time, you should not use

the asterisk on the Pointer, but the compiler should know that the pointer will point to a variable's

address; therefore, the name of the variable will still use the &.

#include <iostream.h>

int main( ){

int Value = 12;int *Pointer = &Value;

cout << "Value lives at: " << Value << "\n";cout << "Pointer lives at: " << *Pointer;cout << "\n\n";return 0;

}

The program would produce:

Value lives at: 12Pointer lives at: 12

Press any key to continue This program could also have the pointer initialized as:

#include <iostream.h>

int main( ){

int Value = 12;int *Pointer;

cout << "Value lives at: " << Value << "\n";

Pointer = &Value;cout << "Pointer lives at: " << *Pointer;cout << "\n\n";return 0;

Page 131: C++ Book

}

And it would produce the same result. As another of the program, you can first declare both variables, then initialize them later on, when needed:

#include <iostream.h>

int main( ){

int Value;int *Pointer;

Pointer = &Value;Value = 26;cout << "Value = " << Value << "\n";cout << "*Pointer = " << *Pointer << "\n";

cout << "\n";return 0;

}

Once you have declare a variable and assign it to a pointer, during the course of your program, the value of a variable is likely to change, you can therefore assign it a different value:

#include <iostream.h>

int main( ){ int Value; int *Pointer; Pointer = &Value; Value = 26; cout << "Value = " << Value << "\n"; cout << "*Pointer = " << *Pointer << "\n"; Value = 35; cout << "Value = " << Value << "\n"; cout << "*Pointer = " << *Pointer << "\n"; cout << "\n"; return 0;}

As you know now, both *Pointer and Value have the same value. This allows you to change the

value of the pointer directly and affect the main variable meanwhile. Therefore, you can safely

change the value of the pointer and it will be assigned accordingly.

To see an example, make the following change to the file:

Page 132: C++ Book

#include <iostream.h>

int main( ){

int Value;int *Pointer;

Pointer = &Value;Value = 26;cout << "Value = " << Value << "\n";cout << "*Pointer = " << *Pointer << "\n";

Value = 35;cout << "Value = " << Value << "\n";cout << "*Pointer = " << *Pointer << "\n";

*Pointer = 144;cout << "Value = " << Value << "\n";cout << "*Pointer = " << *Pointer << "\n";

cout << "\n";return 0;

}This would produce: Value = 26*Pointer = 26Value = 35*Pointer = 35Value = 144*Pointer = 144

Operations on Pointers

Consider that, added just a few rules, a pointer is a variable like any other: it can get its value from

the user (indirectly), you can apply any of the algebraic operations we have learned, it can be

incremented, it can be applied on a function, etc.

A variable is a value that is supposed to change some time to time. Since a pointer is a variable

whose value points to another variable, the value of a pointer is affected by the variable it points to.

You can use this indirection to change the value of a pointer when changing its main variable.

Page 133: C++ Book

To get a value from the user, we have already learned that you can use the cin operator. When using

a pointer to get a value from the user, don't forget the * operator, otherwise, the compiler would get

confused.

We have already learned how to request and display the value of a regular variable from the user:

#include <iostream.h>

int main( ){

int Students;

cout << "Number of students: ";cin >> Students;

cout << "\nNumber of students: " << Students;

cout << "\n\n";return 0;

}

Once you have gotten a value and store it in a variable, it is available:

#include <iostream.h>

int main( ){

int Students;int *ptrStudents;

ptrStudents = &Students;cout << "Number of students: ";cin >> Students;cout << "\nNumber of students: " << Students << "\nThat is: " << *ptrStudents << " students.";cout << "\n\n";return 0;

}

This could produce: 

Page 134: C++ Book

Number of students: 24

Number of students: 24That is: 24 students

Press any key to continue In the same way, you can request a value from the user and store it in the pointer. To see an example, make the following change to the file:<

#include <iostream.h>

int main( ){

int Students;int *ptrStudents;

ptrStudents = &Students;cout << "Number of students: ";cin >> *ptrStudents;

cout << "\nNumber of students: " << Students << "\nThat is: " << *ptrStudents << " students.";

cout << "\n\n";return 0;

}

Of course, you can use various pointers on the same program. Apply an example by making the following changes:

#include <iostream.h>

int main( ){

int Boys;int Girls;int *ptrBoys;int *ptrGirls;

ptrBoys = &Boys;ptrGirls = &Girls;

cout << "Number of male students: ";cin >> *ptrBoys;

cout << "Number of female students: ";cin >> *ptrGirls;cout << "\nNumber of students:";

Page 135: C++ Book

cout << "\nBoys:" << "\t" << Boys << "\nThat is: " << *ptrBoys << " students.";cout << "\nGirls:" << "\t" << Girls << "\nThat is: " << *ptrGirls << " students.";

cout << "\n\n";return 0;

}

We have learned how to perform algebraic calculations and expressions in C++. When performing

these operations on pointers, remember to use the * for each pointer involved. The calculation

should be as smooth:

#include <iostream.h>

int main( ){

int Boys;int Girls;int Total;int *ptrBoys;int *ptrGirls;int *ptrTotal;

ptrBoys = &Boys;ptrGirls = &Girls;ptrTotal = &Total;

cout << "Number of male students: ";cin >> *ptrBoys;cout << "Number of female students: ";cin >> *ptrGirls;

cout << "\nNumber of students:";cout << "\nBoys:" << "\t" << Boys << "\nThat is: " << *ptrBoys << " students.";cout << "\nGirls:" << "\t" << Girls << "\nThat is: " << *ptrGirls << " students.";

Total = Boys + Girls;

*ptrTotal = *ptrBoys + *ptrGirls;

cout << "\n\nTotal number of students: " << Total;cout << "\nThere are " << *ptrTotal << " students";

cout << "\n\n";return 0;

Page 136: C++ Book

}

This would produce:

Number of male students: 26Number of female students: 24

Boys: 26That is: 26 studentsGirls: 24That is: 24 students

Total number of students: 50There are 50 students

Why Use Pointers?

Every time you declare a variable, the compiler puts it somewhere, which you can now refer to as an

address. Once you know that address, you can use it.

Like a reference, when you pass an argument to a function, the argument is passed using its address.

This allows the calling function to dig into the address of the variable (the argument) and use the

value directly. This transaction, like that of passing an argument by reference, allows the calling

function to alter the real value of the argument. Using this ability, a pointer can allow you to return

many values from a function; as opposed to a regular argument passing where the data, although

changed inside of the calling function, will regain its previous value once the calling function is

exited. Therefore, passing arguments as pointers allows a function to return many values, even if a

function is declared as void.

When you declare an array, you must specify the dimension of the array. That's already a problem:

what if you don't know and don't want to know the dimension of the array? Pointers provide an

ability that regular arrays do not have. Since pointers have a different and better system of managing

memory, a pointer can store an array of almost any size; this is tremendous when dealing with arrays

of characters or a whole text. Using this feature, when declaring a pointer in replacement of an array,

you do not have to worry about the size of the array, the compiler will take care of that. Again, this

feature allows you to pass pointers to a function (just like arrays) and return a value that has been

altered even if the function is declared as void. This is even more dynamic with multidimensional

arrays.

Page 137: C++ Book

Passing Pointers to Functions

We know that a function uses arguments in order to carry its assignment. The arguments are usually

provided to the function. When necessary, a function also declares its own variable to get the desired

return value. Like other variables, pointers can be provided to a function, with just a few rules.

When declaring a function that takes a pointer as an argument, make sure you use the asterisk for the

argument or for each argument. When calling the function, use the references to the variables. The

function will perform its assignment on the referenced variable(s). After the function has performed

its assignment, the changed value(s) of the argument(s) will be preserved and given to the calling

function.

Here is a starting file from what we have learned so far:

#include <iostream.h>

int main( ){

int Shirts = 12;int Pants = 5;

cout << "Shirts = " << Shirts << endl;cout << "Pants = " << Pants << endl;

cout << endl;return 0;

}

This would produce:

Shirts = 12Pants = 5

Press any key to continue

To pass arguments to a function, you can make the following changes:

#include <iostream.h>

int main( ){

int Shirts = 3;int Pants = 5;void Deposit(int s, int p);

cout << "When starting, within main( ):\n";

Page 138: C++ Book

cout << "\tShirts = " << Shirts << endl;cout << "\tPants = " << Pants << endl;

Deposit(Shirts, Pants);

cout << "\n\nAfter calling Deposit( ), within main( ):\n";cout << "\tShirts = " << Shirts << endl;

cout << "\tPants = " << Pants << endl;cout << endl;return 0;

}

void Deposit(int s, int p){

s = 8;p = 12;

cout << "Within Deposit( )" << "\n\tShirts = " << s << "\n\tPants = " << p;

}

After executing, the program would produce:

When starting, within main( ): Shirts = 3 Pants = 5Within Deposit( ) Shirts = 8 Pants = 12After calling Deposit( ), Within main( ): Shirts = 3 Pants = 5

Press any key to continue

To pass pointer arguments, use the asterisks when declaring the function, and use the ampersand & when calling the function. Here is an example:

#include <iostream.h>

int main( ){

int Shirts = 12;int Pants = 5;void Deposit(int s, int p);void Pickup(int *sht, int *pt);

cout << "When starting, within main( ):\n";

Page 139: C++ Book

cout << "\tShirts = " << Shirts << endl;cout << "\tPants = " << Pants << endl;

Deposit(Shirts, Pants);cout << "\n\nAfter calling Deposit( ), within main( ):\n";cout << "\tShirts = " << Shirts << endl;cout << "\tPants = " << Pants << endl;

Pickup(&Shirts, &Pants);cout << "\n\nAfter calling Pickup( ), within main( ):\n";cout << "\tShirts = " << Shirts << endl;cout << "\tPants = " << Pants << endl;

cout << endl;return 0;

}

void Deposit(int s, int p){ s = 8; p = 5; cout << "\nWithin Deposit( )" << "\n\tShirts = " << s << "\n\tPants = " << p;}

void Pickup(int *sht, int *pt){ *sht = 26; *pt = 17; cout << "\nWithin Pickup( )" << "\n\tShirts = " << *sht << "\n\tPants = " << *pt;}

The result of executing the program is:

When starting, within main( ): Shirts = 12 Pants = 5

Within Deposit( ) Shirts = 8 Pants = 5

After calling Deposit( ), within main( ): Shirts = 12 Pants = 5

Page 140: C++ Book

Within Pickup( ) Shirts = 26 Pants = 17

After calling Pickup( ), within main( ): Shirts = 26 Pants = 17

Summary

A pointer is a variable that refers to another variable's address.

Just like any variable in C++, you should declare and initialize a pointer variable before using it.

To declare a pointer variable, use an identifier, followed by an asterisk (*), followed by the name

of the pointer, and a semi-colon.

passing arguments as pointers allows a function to return many values, even if a function is

declared as void.

Pointers provide an ability that regular arrays do not have. Since pointers have a different and

better system of managing memory, a pointer can store an array of almost any size; this is

tremendous when dealing with arrays of characters or a whole text.

Page 141: C++ Book

Questions

4. Explain the concept of Pointer5. Predict the output of the following program.

Class test{private:int m;public:void getdata(){cout<<”Enter number:”;cin>>m;}

void display(){cout << m;}};

main(){test T;T->getdata();T->display();Test *p;P=new test;p.getdata();(*p).display();}

Page 142: C++ Book

UNIT I

Lesson 14

INHERITANCE

Objective

Concept of Inheritance

Types of Inheritance

“Now we take on from all the previous topics in C++ to the most inquisitive and exiting topic in C+

+ which is students favorite topics…. ‘Inheritance’.”

“What do you recollect when you talk about inheritance? Doesn’t it immediately relate to

imbibing/inheriting certain characteristics from our parents? Absolutely we are talking about

‘taking over’ certain characteristics from the ‘parent body’ to the ‘child body’. Lets explore this

phenomenon of ‘Inheritance’ in C++ now….”

INTRODUCTION

Reusability is yet another important feature of OOP. It is always nice if we could reuse something

that already exists rather than trying to create the same all over again. It, saves time and money but

also increase reliability. For instance the reuse of a class that has already been tested, debugged and

used many times can the effort of developing and testing the same again.

Fortunately, C++ strongly supports the concept of reusability. The C++ classes reused in several

ways. Once a class has been written and tested, it can be adapted by other programmers to suit their

requirements. This is basically done by creating new reusing the properties of the existing ones

The mechanism of deriving a new class from an old one is called inheritance (or derivation). The

old class is referred to as the base class and the new one is called the derived class or subclass.

The derived class inherits some or all of the traits from the base class. A class can also inherit

properties from more than one class or from more than one level. A derived class with one base

class, is called single inheritance and one with several base classes is called multiple

Page 143: C++ Book

inheritance. On the other hand, the traits of one class may be inherited by more than one

class . This process is known as hierarchical inheritance. The mechanism of deriving from another

'derived class' is known as multilevel inheritance. Fig . shows forms of inheritance that could be

used for writing extensible programs. The direction , indicates the direction of inheritance. (Some

authors show the arrow in opposite

Authors show the arrow in opposite direction meaning "inherited from".)

b) multiple inheritance (a) single inheritance (c) Hirarchical inheritance

(d) Multilevel inheritance (e) Hybrid inheritance

fig. Forms of inheritance

A

B

D

CB

AA

B

C

A B

C

A

DCB

Page 144: C++ Book

DEFINING DERIVED CLASSES

. Derived class can be defined by specifying its relationship with the base class in addition own

details. The general form of defining a derived class is:

c1ass der ved class-name : visibility-mode base-c1ass-name

{

…………………//

…………………// members of derived class

…………………//

};

The colon indicates that the derived-class-name is derived from the base-class-nam, visibility-mode

is optional and, if present, may be either private or public. The default visibility, mode is private.

Visibility mode specifies whether the features of the base class are privately derived or publicly

derived.

Examples:

class ABC: private XYZ // private derivation

{

members of ABC

} ;

class ABC: public XYZ // public derivation

{

members of ABC

} ;

class ABC: XYZ // private derivation by default

{

members of ABC

};

Page 145: C++ Book

When a base class is privately inherited by a derived class, 'public members' of the class become

'private members' of the derived class and therefore the public members of base class can only be

accessed by the member functions of the derived class. They are inaccessible to the objects of the

derived class. Remember, a public member of a class can accessed by its own objects using the dot

operator. The result is that no member of the class is accessible to the objects of the derived class.

SINGLE INHERITANCE

Let us consider a simple example to illustrate inheritance. Program shows a base class B and

derived class D. The class B contains one private data member, one public data member and three

public member functions. The class D contains one private data member and two public member

functions.

#include <iostream>

using namespace std;

class B

{

int a; //private ; not inheritable

public:

int b; //public; ready for inheritance

void get_ab();

int get_a(void);

void show_a(void);

};

class D : public B // public derivation

{

Page 146: C++ Book

int c;

public :

void mul(void);

void display(void);

};

void B :: get_ab(void)

{

a=5;b=10;

}

int b :: get_a()

{

return a;

}

void B :: show_a()

{

cout <<”a=” <<a<<”\n”;

}

void D :: mul()

{

c=b*get_a();

}

void D :: display()

{

cout <<”a=”<<get_a()<<”\n”;

cout <<”b=”<<b <<”\n”;

cout <<”c=”<<c <<”\n \n ”;

}

Page 147: C++ Book

int main()

{

D d;

d.get_ab();

d.mul();

d.show_a();

d.display();

d.b=20;

d.mul();

d.display();

return 0;

}

Given below is the output of above Program :

a = 5

a = 5

b = 10

c = 50

a = 5

b = 20

c = 100

The class D is a public derivation of the base class B. Therefore, D inherits all the public members of

B and retains their visibility. Thus a public member of the base class B is also a public member of

the derived class D. The private members of B cannot be inherited by D.

Questions

1. Discuss overview of the Inheritance

Page 148: C++ Book

UNIT I

LESSON 15

INHERITANCE II

Objective

Types of inheritance

MULTILEVEL INHERITANCE

It is not uncommon that a class is derived from another derived class as shown in Fig. The class A

serves as a base class for the derived class B, which in turn serves as a base class for the derived

class C. The class B is known as intermediate base class since it provides a link for the inheritance

between A and C. The chain ABC is known as inheritance path.

A derived class with multilevel inheritance is declared as follows:

class A{ }; // Base class

class B: public A { }; // B derived from A

class C: public B { }; // C derived from B

This process can be extended to any number of levels.

Base class Grandfather

Intermediate base class Father

Derived class Child

Multilevel inheritance

Let us consider a simple example. Assume that the test results of a batch of students are stored in

three different classes. Class student stores the roll-number, class test stores the marks obtained in

A

B

C

Page 149: C++ Book

two subjects and class result contains the total marks obtained in the test. The class result can

inherit the details of the marks obtained in the test and the roll number of students through multilevel

inheritance. Example:

class student

{

protected:

int roll_number;

public:

void get number(int);

void put_number{void);

};

void student :: get_number(int a)

{

roll_number = a;

}

void student :: put_numberO

{

cout << "Roll Number: " << roll number << "\n";

}

class test : public student // First level derivation

{

protected:

float subl;

float sub2;

public:

void get_marks(float, float);

void put_marks(void);

};

void test :: get_marks(float x, float y)

{

subl = X;

sub2 = y;

Page 150: C++ Book

}

void test :: put marks 0

{

cout << "Marks in SUBl = " << subl << "\n";

cout << "Marks in SUB2 = " << sub2 <<"\n";

}

class result : public test // Second level derivation

{

float total; // private by default

public:

void display(void);

};

The class result, after inheritance from 'grandfather' through 'father', would contain

following members:

private:

float tota1; // own member

protected:

int roll_number; // inherited from student via test

float subl; // inherited from test

float sub2; // inherited from test

public:

void get_number(int); // from student via test

void put_number(void); // from student via test

void get marks(float, float); // from test

void put-marks(void); // from test

void display(void); // own member

The inherited functions put_number() and put_marks() can be used in the definition of

display() function:

void result :: display(void)

{

Page 151: C++ Book

total = subl + sub2;

put_number();

put_marks();

cout <<"Total = " << total << "\n";

}

Here is a simple main() program:

int main()

{

result student1; / / student1 created

studentl.get_number(111);

studentl.get_marks(75.0, 59.5);

studentl.display();

return 0;

}

This will display the result of student1. The complete program is shown below

MULTILEVEL INHERITANCE

# include <iostream>

using namespace std;

class student

{

protected:

int roll_number;

public:

void get_number(int);

void put_number(void);

Page 152: C++ Book

};

void student :: get_number(int a)

{

roll_number = a;

}

void student :: put_number(int a)

{

cout << “Roll number: “ << roll_number << “\n”;

}

class test : public student // First level derivation

{

protected:

float sub1;

float sub2;

public:

void get_marks(float, float);

void put_marks(void);

};

void test :: get_marks(float x, float y)

{

sub1 = x;

sub2 = y;

}

void test :: put_marks()

{

cout << “Marks in SUB1 = “ << sub1 << “\n”;

cout << “Marks in SUB2 = “ << sub2 << “\n”;

}

class result : public test // Second level derivation

Page 153: C++ Book

{

float total; // private by default

public:

void display(void);

};

void result :: display(void)

{

total = sub1 + sub2;

put_number();

put_marks();

cout << “Total = “ << total << “\n”;

}

int main()

{

result student1; // student1 created

student1.get_number(111);

student1.get_marks(75.0, 59.5);

student1.display();

return 0;

}

Program displays the following output:

Roll Number: 111

Marks in SUB1 = 75

Marks in SUB2 = 59.5

Total = 134.5

Page 154: C++ Book

MULTIPLE INHERITANCE

A class can inherit the attributes of two or more classes as shown in Fig.This is known as multiple

inheritance. Multiple inheritance allows us to combine the features of several existing classes as a

starting point for defining new classes. It is like a child inheriting the physical features of one parent

and the intelligence of another.

Multiple inheritance

The syntax of a derived class with multiple base classes is as follows:

where, visibility may be either public or private. The base classes are separated by commas.

Example:

class P : public M, public N

{

B-2 B-nB1

D

Class D visibility B-1, visibility B-2……….{……………………(body of D)…………};

Page 155: C++ Book

public:

void display(void);

};

Classes M and N have been specified as follows:

class M

{

protected:

int m;

public:

void get_m(int);

};

void M :: get_m(int x)

{

m = x;

}

class N

{

protected:

int n;

public:

void get_n(int);

};

void N :: get_n(int y)

{

n = y;

}

The derived class P, as declared above, would, in effect, contain all the members of M and N

in addition to its own members as shown below:

class P

Page 156: C++ Book

{

protected:

// from M

// from M

public:

// from M

// from N

// own member

};

The member function display() can be defined as follows:

void P :: display(void)

{

cout << "m = " << m <<"\n";

cout << "n = " << n << "\n";

cout << "m*n =" << m*n << "\n";

};

The main() function which provides the user-interface may be written as follows:

main ()

{

P p;

p.get_m(l0) ;

p.get_n(20) ;

p.display () ;

}

int m;int n;

void get_m(int); void get_n(int); void display(void);

Page 157: C++ Book

summary

A class can inherit the attributes of two or more classes .This is known as multiple

inheritance.

Multiple inheritance allows us to combine the features of several existing classes as a starting

point for defining new classes. It is like a child inheriting the physical features of one parent

and the intelligence of another.

A class can inherit the attributes of two or more classes.This is known as multiple

inheritance.

Questions

1.What is Inheritance? Explain its types in brief

2.what is multiple inheritance? Explain

Page 158: C++ Book

UNIT I

LESSON 16

INHERITANCE III

Objective

Hierarchical Inheritance

Hybrid Inheritance

Constructors In Derived Classes

HIERARCHICAL INHERITANCE

We have discussed so far how inheritance can be used to modify a class when it did not satisfy the

requirements of a particular problem on hand. Additional members are added through inheritance to

extend the capabilities of a class. Another interesting application of inheritance is to use it as a

support to the hierarchical design of a program. Many programming problem can be cast into a

hierarchy where certain features of one level are shared by many others below that level.

As an example, following Fig. shows a hierarchical classification of students in a university

Hierarchical classification of students

Another example could be the classification of accounts in a commercial bank.

MedicalEngineeringArts

Students

Mech. Elec. Civil

Page 159: C++ Book

Classification of bank accounts

All the students have certain things in common and, similarly, all the account possess certain

common features.

In C++, such problems can be easily converted into class hierarchies. The base class will

include all the features that are common to the subclasses. A subclass can be constructed by

inheriting the properties of the base class. A subclass can serve as a base class for the lower level

classes and so on.

HYBRID INHERITANCE

There could be situations where we need to apply two or more types of inheritance to design

a program. For instance, consider the case of processing the student results. Assume that we have to

give weightage for sports before finalising the results. The weightage for sports is stored in a

separate class called sports. The new inheritance relationship between the various classes would be

as shown.

Multilevel. multiple inheritance

Student

Test

Result

Student

Short Term Medium Term Long Term

Current AccountFixed Deposit Account

Savings Account

Account

Page 160: C++ Book

The sports class might look like:

class sports

{

protected:

float score;

public:

void get_score(f1oat);

void put_score(void);

};

The result will have both the multilevel and multiple inheritances and its declaration would

be as follows:

class sports: public test, public sports

{

… …

… …

} ;

Where test itself is a derived class from student. That is

class test : pub1ic student

{

… …

… …

};

Program illustrates the implementation of both multilevel and multiple inheritance.

#include <iostream>

Page 161: C++ Book

using namespace std;

class student

{

protected:

int roll_number;

public:

void get_number(int a)

{

roll_number = a;

}

void put_number(void)

{

cout << “Roll No: “ << roll_number << “\n”;

}

};

class test : public student

{

protected:

f1oat part1, part2;

public:

void get marks (float x, float y)

{

partl = x;

part2 = y;

}

void put marks(void)

{

cout << "Marks obtained: " << "\n"

<< “Part1 = “ << part1 << "\n"

<< “Part2 = “ << part2 << "\n";

}

Page 162: C++ Book

};

class sports : public virtual student

{

protected:

float score;

public:

void get_score (float s)

{

score = s;

}

void put score(void)

{

cout << "Sports wt: " << score << "\n\n";

}

};

class result : public test, public sports

{

float tota1;

public:

void display(void);

};

void result :: display(void)

{

total = part1 + part2 + score;

put_number();

put_marks();

put_score();

cout << "Total Score: " << total << "\n”;

}

Page 163: C++ Book

int main()

{

resu1t student _1 ;

student_l.get score(7.0);

student_1.display();

return 0;

}

CONSTRUCTORS IN DERIVED CLASSES

As we know, the constructors play an important role in initializing objects. We did not use them

earlier in the derived classes for the sake of simplicity. One important thing to note here is that, as

long as no base class constructor takes any arguments, the derived class need not have a constructor

function. However, if any base class contains a constructor with one or more arguments, then it is

mandatory for the derived class to have a constructor and pass the arguments to the base class

constructors. Remember, while applying inheritance we usually create objects using the derived

class. Thus, it makes sense for the derived class to pass arguments to the base class constructor.

When both the derived and base classes contain constructors, the base constructor is executed first

and then the constructor in the derived class is executed. .

Incase of multiple inheritance, the base classes are constructed in the order in which they

appear in the declaration of the derived class. Similarly, in a multilevel inheritance, the constructors

will be executed in the order of inheritance

Since the derived class takes the responsibility of supplying initial values to its base classes,

we supply the initial values that are required by all the classes together, when a derived class is

declared. How are they passed to the base class constructors so that they can do their job? C++

supports a special argument passing mechanism for such situations.

The constructor of the derived class receives the entire list of values as its arguments and

passes them on to the base constructors in the order in which they are declared in the derived class.

The base constructors are called and executed before executing the statements in the body of the

derived constructor.

Page 164: C++ Book

The general form of defining a derived constructor is:

The header line of derived-constructor function contains two parts separated by a colon(;),

The first part provides the declaration of the arguments that are passed to the derived, constructor

and the second part lists the function calls to the base constructors.

basel(arglistl), base2(arglist2)... are function calls to base constructors basel(),base2(), ... and

therefore arglistl, arglist2, ... etc. represent the actual parameters that are passed to the base

constructors. Arglistl through ArglistN are the argument declarations for base constructors base1

through baseN. ArglistD provides the parameters that are necessary to initialize the members of the

derived class.

Example:

D(int a1, int a2, float bl, float b2, int d1):

A(al, a2), /* call to constructor A */

B(bl, b2) /* call to constructor B */

{

d = d1; // executes its own body

}

A(al, a2) invokes the base constructor A() and B(bl, b2) invokes another base constructor

B(). The constructor D() supplies the values for these four arguments. In addition, it has one

Derived-constructor (Arglist1, Arglist2, …… ArglistN, Arglist(D)

base1(arglist1),base1(arglist1),……………… arguments for base(N)baseN(arglistN),{Body of derived constructor}

Page 165: C++ Book

argument of its own. The constructor D() has a total of five arguments. D() may be invoked as

follows:

……

D obj D (5, 12, 2.5, 7.54, 30);

……

These values are assigned to various parameters by the constructor D() as follows:

5 a1

12 a2

2.5 b1

7.54 b2

30 d1

The constructors for virtual base classes are invoked before any non-virtual base classes. If

Ther are multiple virtual base classes, they are invoked in the order in which they are declared. Any

non-virtua1 bases are then constructed before the derived class constructor is executed. See Table

below:

Method of inheritance Order of execution

Class B: public A

{

};

A() ; base constructor

B() ; derived constructor

Class A : public B, public C

{

};

B() : base(first)

C() : basae (second)

A() :derived

Class A : public B, virtual public C

{

};

C() : virtual base

B() : ordinary base

A() : derived

CONSTRUCTORS IN DERIVED CLASS

Program below illustrates how constructors are implemented when the classes are inherited.

Page 166: C++ Book

#inc1ude <iostream>

using namespace std;

class alpha

{

int x;

pub1ic :

a1pha(int i)

{

x = I;

cout << "alpha initialized \n";

}

void show x(void)

{ cout << "x = " << x << "\n"; }

};

c1ass beta

{

float y;

public:

beta(float j)

{

y = j;

cout << "beta initialized \n";

}

void show_y(void)

{ cout << "y = " << y << "\n"; }

};

class gamma: public beta, public alpha

{

int m, n;

Page 167: C++ Book

public:

gamma(int a, float b, int c, int d):

alpha(a), beta(b)

{

m = c;

n = d;

cout << “m = “ << m << “\n”

<< “n = “ << n << “\n”;

}

};

int main()

{

gamma g(5, 10.75, 20, 30):

cout << “\n”;

g.show_x();

g.show_y();

g.show_mn();

return 0;

}

The output of the program would be:

beta initialized

alpha initialized

gamma initialized

x = 5

y = 10.75

m = 20

n = 30

Page 168: C++ Book

Summary

Application of inheritance is to use it as a support to the hierarchical design of a

program. Many programming problem can be cast into a hierarchy where certain

features of one level are shared by many others below that level.

Incase of multiple inheritance, the base classes are constructed in the order in which

they appear in the declaration of the derived class. Similarly, in a multilevel

inheritance, the constructors will be executed in the order of inheritance

Questions

1. Explain hybrid inheritance with example

2. What is hierarchical inheritance?

3. Explain Constructors In Derived Classes

4. Briefly define each of the following terminologies

i. Inheritance

ii. Multiple Inheritance

iii. Base class

iv. Derived Class

5 Distinguish between Single Inheritance and Multiple Inheritance

Page 169: C++ Book

UNIT I

Lesson 17

Tutorial based on the concept of Constructor and Inheritance

Page 170: C++ Book

UNIT I

LESSON 18

VIRTUAL FUNCTIONS

Objective

Concept of virtual functions

Rules of virtual functions

Pure virtual functions

The concept of polymorphism in C++ is the capability to create member functions with identical

names that perform slightly different operations. This is achieved by using virtual functions. A

virtual function can only be defined in a parent class. When a parent class declares a virtual

function, it is enabling any derived classes of the parent class the capability to create a different

function with the same name as the virtual function. If a derived class does not declare a new

function, the parent class function is used just like any other non-virtual function would be.

In essence, a virtual function allows a derived classes the option of overriding a parent class

function. Virtual functions must be called in a slightly different fashion than non-virtual functions.

VIRTUAL FUNCTIONS

An essential requirement of polymorphism is therefore the ability to refer to objects without any

regard to their classes. This necessitates the use of a single pointer variable to refer to the objects of

different classes. Here, we use the pointer to base class to refer to all the derived objects. But, we

just discovered that a base pointer, even when it is made to contain the address of derived class,

always executes the function in the base class. The compiler simply ignores the contents of the

pointer and chooses the member function that matches the type of the pointer.

How do we then achieve polymorphism? It is achieved using what is known as 'virtual' functions.

When we use the same function name in both the base and derived classes, the function in base class

is declared as virtual using the keyword virtual preceding its normal declaration. When a function is

made virtual, C++ determines which function to use at run time based on the type of object pointed

to by the base pointer, rather than the type of the pointer. Thus, by making the base pointer to point

Page 171: C++ Book

to different objects, we can execute different versions of the virtual function. Program illustrates this

point.

#include<iostream.h>

class Base

{

void display() {cout<<” \n display Base “;}

void show() {cout << “\n show Base";}

}

class derived : public Base

{

public :

void display() {cout<<” \n display Derived “;}

void show() {cout << “\n show Derived";}

};

int Main()

{

Base B;

Derived D;

Base *bptr;

cout <<” \n bptr points toBase\n”;

bptr =&B;

bptr -> display(); //calls Base version

bptr -> show(); //calls Base version

cout « "\n\n bptr poini:s Derived\n";

bptr = &D;

bptr -> display(); // calls Base version

bptr -> show(); // calls Derived version

return 0;

Page 172: C++ Book

}

The output of Program would be:

bptr points to Base

Display base

Show base

bptr points to Derived

Display base

Show derived

Note that When bptr is made to point to the object D, the statement

bptr -> display();

calls only the function associated with the Base (i.e. Base :: display( )), whereas the statement

bptr -> show();

calls the Derived version pf show(). This is because the function display () has not been made virtual

in the Base class.

One important point to remember is that, we must access virtual functions through the use of a

pointer declared as a pointer to the base class. Why can't we use the object name (with the dot

operator) the same way as any other member function to call the virtual functions? We can, but

remember, run time polymorphism is achieved only when a virtual function is accessed through a

pointer to the base class.

Let us take an example where virtual functions are implemented in practice. Consider a book shop

which sells both books and video-tapes. We can create a class known as media that stores the title

and price of a publication. We can then create two derived classes, one for storing the number of

pages in a book and another for storing the playing time of a tape.

Page 173: C++ Book

Figure shows the class hierarchy for the book shop.

The class hierarchy for the book shop

The classes are implemented in Program. A function display() is used in all the classes to display the

class contents. Notice that the function display() has been declared virtual in media, the base class.

In the main program we create a heterogeneous list of pointers of type media as shown below:

media *list[2]; = { &book1; [1], &tape1};

The base pointers list[0] and list[1] are initialized with the addresses of objects bookl and tapel

respectively.

#include <iostream>

#include <cstring>

class media

{

protected :

char title [501;

float price;

public :

media (char *s, float a )

{

strcpy(title, s);

price = a;

}

media

book tape

Page 174: C++ Book

virtual void display() { } / / empty virtual function

};

class book: public media

{

int pages;

public:

book(char *s, float a. int p) :media(s, a)

{

pages = p;

}

void display().;

};

class tape :public media

{

float time;

public:

tape(char * s, float a, float t):media(s, a)

{

time = t;

}

void display();

};

void book:: display()

{

cout << "\n Title: " << title;

cout << "\n Pages: " << pages;

cout<< “\n Price: "<< price;

}

void tape::display

Page 175: C++ Book

{

cout <<” \n Title: "<< title;

cout <<”\n play time: " << time « "mins";

cout<< “\n Price: "<< price;

}

int main()

{

char *title = new char[30];

float price, time

int pages;

// Book details

cout <<”\n Enter Book Details \n”;

cout <<”\n Titles: “; cin >>title;

cout <<”\n Price : “; cin >>Price;

cout<< “\n pages: “ ; cin>> pages

book book1(title, price, pages)

// Tape details

cout <<”\n Enter Tape Details \n”;

cout <<”\n Titles: “; cin >>title;

cout <<”\n Price : “; cin >>Price;

cout<< “Play time (mins): “ ; cin>> time;

tape tape1(title, price, time);

media* list[2];

list[0] = &book1;

list[1] = &tape1;

cout<<”\n MEDIA DETALS”;

Page 176: C++ Book

cout<<”\n ……BOOK…………”;

list[0]->display(); // display book details

cout<<”\n ……TAPE…………”;

list[0]->display(); // display Tape details

result 0;

}

The output of program

ENTER BOOK DETAILS

Title: Programming in ANSI C

Price: 88

Pages: 400

ENTER TAPE DETAILS

Title: Computing_Concepts

Price: 90

Play time (mi ns): 55

MEDIA DETAILS

…....BOOK...….

Title: Programming in ANSI C

Pages: 400

Price: 88

…….TAPE...….

Title: Computing_Concepts

Play time: 55mins

Page 177: C++ Book

Price: 90

Rules for Virtual Functions

When virtual functions are created for implementing late binding, we should observe some basic

rules that satisfy the compiler requirements:

1. The virtual functions must be members of some class.

2. They cannot be static members.

3. They are accessed by using object pointers.

4. A virtual function can be a friend of another class.

5. A virtual function in a base class must be defined, even though it may not be used.

6. The prototypes of the base class version of a virtual function and all the derived class versions

must be identical. If two functions with the same name have different

prototypes, C++

considers them as overloaded functions, and the virtual function mechanism is

ignored.

7. We cannot have virtual constructors, but we can have virtual destructors.

8. While a base pointer can point to any type of the derived object, the reverse is not true. That is to

say, we cannot use a pointer to a derived class to access an object of the base type.

9. When a base pointer points to a derived class, incrementing or decrementing it will not make it to

point to the next object of the derived class. It is incremented or decremented only relative to its base

type. Therefore, we should not use this method to move the pointer to the next object.

10. If a virtual function is defined in the base class, it need not be necessarily redefined in the

derived class. In such cases, calls will invoke the base function.

PURE VIRTUAL FUNCTIONS

It is normal practice to declare a function virtual inside the base class and redefine it in the derived

classes. The function inside the base class is seldom used for performing any task. It only serves as

a placeholder. For example, we have not defined any object of class medial therefore the function

display() in the base class has been defined 'empty'. Such functions called "do-nothing" functions.

Page 178: C++ Book

A "do-nothing" function may be defined as follows:

virtual void display() = 0;

Such functions are called pure virtual functions. A pure virtual function is a function declared in a

base class that has no definition relative to the base class. In such cases, the compiler requires each

derived class to either define the function or re declare it as a pure virtual function. Remember that a

class containing pure virtual functions cannot be used declare any objects of its own. As stated

earlier, such classes are called abstract base c/asses. The main objective of an abstract base class-is

to provide some traits to the derived classes and to create a base pointer required for achieving run

time polymorphism.

Summary

When we use the same function name in both the base and derived classes, the function in

base class is declared as virtual using the keyword virtual preceding its normal declaration.

When a function is made virtual, C++ determines which function to use at run time based on

the type of object pointed to by the base pointer, rather than the type of the pointer

Remember that a class containing pure virtual functions cannot be used declare any objects

of its own. As stated earlier, such classes are called abstract base c/asses. The main objective

of an abstract base class-is to provide some traits to the derived classes and to create a base

pointer required for achieving run time polymorphism.

Questions

1. What do you, mean by Virtual function? Why do we need virtual functions

2. explain pure virtual function

3. distingwish between virtual functions and pure virtual function

Page 179: C++ Book

UNIT I

Lesson 19

POLYMORPHISM

Objective

Concept of polymorphism

Static and Dynamic Binding

INTRODUCTION

Polymorphism is one of the crucial features of OOP. It simply means 'one name, multiple forms'.

you have already seen how the concept of polymorphism is implemented using the overloaded

functions and operators. The overloaded member functions are selected for invoking by matching

arguments, both type and number. This information is known to the compiler at the compile time

and, therefore, compiler is able to select the appropriate function for a particular .Call at the compile

time itself. This is called early binding or static binding or static linking. Also known as compile

time polymorphism, early binding simply mean that an object is bound to its function call at compile

time.

It would be nice if the appropriate member function could be selected while the program is running.

This is known as run time polymorphism. How could it happen? C++ supports a mechanism known

as virtual function to achieve run time polymorphism.

Achieving polymorphism

Polymorphism

Function overloading

Operator overloading

Compile time polymorphism

Run time polymorphism

Virtual functions

Page 180: C++ Book

At run time, when it is known what class objects are under consideration,. the appropriate version of

the function is invoked. Since the function is linked with a particular class much iter after the

compilation, this process is termed as late binding. It is also known as dynamic binding because the

selection of the appropriate function is done dynamically at run time.

Dynamic binding is one of the powerful features of C++. This requires the use of pointers to objects.

We shall discuss in detail how the object pointers and virtual functions are used to implement

dynamic binding.

Static and Dynamic Binding

In a strongly typed programming languages you typically have to declare variables prior to their use.

This also implies the variable's definition where the compiler reserves space for the variable. For

example, in Pascal expressions like

var i : integer;

declares variable i to be of type integer. Additionally, it defines enough memory space to hold an

integer value.

With the declaration we bind the name i to the type integer. This binding is true within the scope in

which i is declared. This enables the compiler to check at compilation time for type consistency. For

example, the following assignment will result in a type mismatch error when you try to compile it:

var i : integer;

...

i := 'string';

We call this particular type of binding “static” because it is fixed at compile time.

Definition (Static Binding) If the type T of a variable is explicitly associated with its name N by

declaration, we say, that N is statically bound to T. The association process is called static binding.

There exist programming languages, which are not using explicitly typed variables. For example,

some languages allow to introduce variables once they are needed:

... /* No appearance of i */

i := 123 /* Creation of i as an integer */

Page 181: C++ Book

The type of i is known as soon as its value is set. In this case, i is of type integer since we have

assigned a whole number to it. Thus, because the content of i is a whole number, the type of i is

integer.

Definition (Dynamic Binding) If the type T of a variable with name N is implicitly associated by its

content, we say, that N is dynamically bound to T. The association process is called dynamic

binding.

Both bindings differ in the time when the type is bound to the variable. Consider the following

example, which is only possible with dynamic binding:

if somecondition( ) == TRUE then

n := 123

else

n := 'abc'

The type of n after the if statement depends on the evaluation of somecondition( ). If it is TRUE, n

is of type integer whereas in the other case it is of type string.

Polymorphism allows an entity (for example, variable, function or object) to take a variety of

representations. Therefore we have to distinguish different types of polymorphism, which will be

outlined here.

The first type is similar to the concept of dynamic binding. Here, the type of a variable depends on

its content. Thus, its type depends on the content at a specific time:

v := 123 /* v is integer */

... /* use v as integer */

v := 'abc' /* v "switches" to string */

... /* use v as string */

Definition (Polymorphism (1)) The concept of dynamic binding allows a variable to take different

types dependent on the content at a particular time. This ability of a variable is called

polymorphism. Another type of polymorphism can be defined for functions. For example, suppose

you want to define a function isNull( ) which returns TRUE if its argument is 0 (zero) and FALSE

otherwise. For integer numbers this is easy:

boolean isNull(int i)

{

Page 182: C++ Book

if (i == 0) then

return TRUE

else

return FALSE

endif

}

However, if we want to check this for real numbers, we should use another comparison due to the

precision problem:

boolean isNull(real r) {

if (r < 0.01 and r > -0.99) then

return TRUE

else

return FALSE

endif

}

In both cases we want the function to have the name isNull. In programming languages without

polymorphism for functions we cannot declare these two functions because the name isNull would

be doubly defined. Without polymorphism for functions, doubly defined names would be

ambiguous. However, if the language would take the parameters of the function into account it

would work. Thus, functions (or methods) are uniquely identified by:

the name of the function (or method) and

the types of its parameter list.

Since the parameter list of both isNull functions differ, the compiler is able to figure out the correct

function call by using the actual types of the arguments:

var i : integer

var r : real

i = 0

r = 0.0

...

Page 183: C++ Book

if (isNull(i)) then ... /* Use isNull(int) */

...

if (isNull(r)) then ... /* Use isNull(real) */

Definition (Polymorphism (2)) If a function (or method) is defined by the combination of

its name and

the list of types of its parameters

we speak of polymorphism. This type of polymorphism allows us to reuse the same name for

functions (or methods) as long as the parameter list differs. Sometimes this type of polymorphism is

called overloading.

The last type of polymorphism allows an object to choose correct methods. Consider the function

move( ) again, which takes an object of class Point as its argument. We have used this function with

any object of derived classes, because the is-a relation holds.

Now consider a function display( ) which should be used to display drawable objects. The

declaration of this function might look like this:

display(DrawableObject o) {

...

o.print( )

...

}

We would like to use this function with objects of classes derived from DrawableObject:

Circle acircle

Point apoint

Rectangle arectangle

display(apoint) /* Should invoke apoint.print( ) */

display(acircle) /* Should invoke acircle.print( ) */

display(arectangle) /* Should invoke arectangle.print( ) */

The actual method should be defined by the content of the object o of function display( ). Since this

is somewhat complicated, here is a more abstract example:

Page 184: C++ Book

class Base {

attributes:

methods:

virtual foo( )

bar( )

}

class Derived inherits from Base {

attributes:

methods:

virtual foo( )

bar( )

}

demo(Base o) {

o.foo( )

o.bar( )

}

Base abase

Derived aderived

demo(abase)

demo(aderived)

In this example we define two classes Base and Derived. Each class defines two methods foo( ) and

bar( ). The first method is defined as virtual. This means that if this method is invoked its

definition should be evaluated by the content of the object.

We then define a function demo( ) which takes a Base object as its argument. Consequently, we can

use this function with objects of class Derived as the is-a relation holds. We call this function with a

Base object and a Derived object, respectively.

Page 185: C++ Book

Suppose, that foo( ) and bar( ) are defined to just print out their name and the class in which they are

defined. Then the output is as follows:

foo( ) of Base called.

bar( ) of Base called.

foo( ) of Derived called.

bar( ) of Base called.

Why is this so? Let's see what happens. The first call to demo( ) uses a Base object. Thus, the

function's argument is ``filled'' with an object of class Base. When it is time to invoke method foo( )

it's actual functionality is chosen based on the current content of the corresponding object o. This

time, it is a Base object. Consequently, foo( ) as defined in class Base is called.

The call to bar( ) is not subject to this content resolution. It is not marked as virtual. Consequently,

bar( ) is called in the scope of class Base.

The second call to demo( ) takes a Derived object as its argument. Thus, the argument o is filled with

a Derived object. However, o itself just represents the Base part of the provided object aderived.

Now, the call to foo( ) is evaluated by examining the content of o, hence, it is called within the scope

of Derived. On the other hand, bar( ) is still evaluated within the scope of Base.

Definition (Polymorphism (3)) Objects of superclasses can be filled with objects of their subclasses.

Operators and methods of subclasses can be defined to be evaluated in two contextes:

1. Based on object type, leading to an evaluation within the scope of the superclass.

2. Based on object content, leading to an evaluation within the scope of the contained

subclass.

“So now we will derive a program in C++ to explain how ‘polymorphism’ works….”

Polymorphism allows more than one function to have the same name, provided all functions are

either distinguishable by the typing or the number of their parameters. Using a function name more

than once is sometimes referred to as overloading the function name.

Here's an example:

#include<iostream>

using namespace std;

Page 186: C++ Book

int average(int first_number, int second_number, int

third_number);

int average(int first_number, int second_number);

/* MAIN PROGRAM: */

int main( )

{

int number_A = 5, number_B = 3, number_C = 10;

cout << "The integer average of " << number_A << " and ";

cout << number_B << " is ";

cout << average(number_A, number_B) << ".\n\n";

cout << "The integer average of " << number_A << ", ";

cout << number_B << " and " << number_C << " is ";

cout << average(number_A, number_B, number_C) << ".\n";

return 0;

}

/* END OF MAIN PROGRAM */

/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 3 INTEGERS: */

int average(int first_number, int second_number, int third_number)

{

return ((first_number + second_number + third_number)/3);

}

/* END OF FUNCTION */

/* FUNCTION TO COMPUTE INTEGER AVERAGE OF 2 INTEGERS: */

int average(int first_number, int second_number)

{

return ((first_number + second_number) / 2);

}

Page 187: C++ Book

/* END OF FUNCTION */

When the same function is repeatedly executed for different purposes, as mentioned in above

explanation, the function is then supposed to be overloaded.

Summary

Polymorphism is one of the crucial features of OOP. It simply means 'one name, multiple

forms'. It would be nice if the appropriate member function could be selected while the

program is running. This is known as run time polymorphism.

At run time, when it is known what class objects are under consideration,. the appropriate

version of the function is invoked. Since the function is linked with a particular class much

iter after the compilation, this process is termed as late binding. It is also known as dynamic

binding because the selection of the appropriate function is done dynamically at run time.

The overloaded member functions are selected for invoking by matching arguments, both

type and number. This information is known to the compiler at the compile time and,

therefore, compiler is able to select the appropriate function for a particular .Call at the

compile time itself. This is called early binding or static binding or static linking.

Questions

1. What do you mean by polymorphism? explain

2 Discuss the different ways by which we can access public member function of an

object

3 How does polymorphism promote extensibility?

Page 188: C++ Book

UNIT ILESSON 20

VIRTUAL BASE CLASSES, NESTING OF CLASS

Objective

Abstract Classes

Virtual Base Classes

Member Classes

ABSTRACT CLASSES

An abstract class is one that is not used to create objects. An abstract class is designed only to act as

a base class (to be inherited by other classes). It is a design concept in program development and

provides a base upon which other classes may be built. In the previous example, the student class is

an abstract class since it was not used to create any objects.

Basic abstract classes are something very similar to the class CPolygon of our previous example.

The only difference is that in our previous example we have defined a valid area() function for

objects that were of class CPolygon (like object poly), whereas in an abstract base class we could

have simply left without defining this function by appending =0 (equal to zero) to the function

declaration.

The class CPolygon could have been thus:

// abstract class CPolygon

class CPolygon {

protected:

int width, height;

public:

void set_values (int a, int b)

{ width=a; height=b; }

virtual int area (void) =0;

};

Page 189: C++ Book

Notice how we have appended =0 to virtual int area (void) instead of specifying an implementation

for the function. This type of function is called a pure virtual function, and all classes that contain a

pure virtual function are considered abstract base classes.

The greatest difference of an abstract base class is that instances (objects) of it cannot be created, but

we can create pointers to them. Therefore a declaration like:

CPolygon poly;

would be incorrect for the abstract base class declared above. Nevertheless the pointers:

CPolygon * ppoly1;

CPolygon * ppoly2

are be perfectly valid. This is because the pure virtual function that it includes is not defined and it is

impossible to create an object if it does not have all its members defined. Nevertheless a pointer that

points to an object of a derived class where this function has been defined is perfectly valid.

Here you have the complete example:

// virtual members

#include <iostream.h>

class CPolygon {

protected:

int width, height;

public:

void set_values (int a, int b)

{ width=a; height=b; }

virtual int area (void) =0;

};

class CRectangle: public CPolygon {

public:

int area (void)

{ return (width * height); }

};

class CTriangle: public CPolygon {

public:

int area (void)

Page 190: C++ Book

{ return (width * height / 2); }

};

int main () {

CRectangle rect;

CTriangle trgl;

CPolygon * ppoly1 = &rect;

CPolygon * ppoly2 = &trgl;

ppoly1->set_values (4,5);

ppoly2->set_values (4,5);

cout << ppoly1->area() << endl;

cout << ppoly2->area() << endl;

return 0;

}

output

20

10

If you review the program you will notice that we can refer to objects of different classes using a

unique type of pointer (CPolygon*). This can be tremendously useful. Imagine, now we can create a

function member of CPolygon that is able to print on screen the result of the area() function

independently of what the derived classes are.

// virtual members

#include <iostream.h>

class CPolygon {

protected:

int width, height;

public:

void set_values (int a, int b)

Page 191: C++ Book

{ width=a; height=b; }

virtual int area (void) =0;

void printarea (void)

{ cout << this->area() << endl; }

};

class CRectangle: public CPolygon {

public:

int area (void)

{ return (width * height); }

};

class CTriangle: public CPolygon {

public:

int area (void)

{ return (width * height / 2); }

};

int main()

{

CRectangle rect;

CTriangle trgl;

CPolygon * ppoly1 = &rect;

CPolygon * ppoly2 = &trgl;

ppoly1->set_values (4,5);

ppoly2->set_values (4,5);

ppoly1->printarea();

ppoly2->printarea();

return 0;

}

Output

Page 192: C++ Book

20

10

Remember that this represents a pointer to the object whose code is being executed. Abstract classes

and virtual members grant to C++ the polymorphic characteristics that make object-oriented

programming such a useful instrument. Of course we have seen the simplest way to use these

features, but imagine these features applied to arrays of objects or objects assigned through dynamic

memory.

VIRTUAL BASE CLASSES

We have just discussed a situation which would require the use of both the multiple and multilevel

inheritance. Consider a situation where all the three kinds of inheritance, namely, multilevel,

multiple and hierarchical inheritance, are involved. This is illustrated in fig. The 'child' has two

direct base classes 'parent1' and 'parent2' which themselves nave a common base class 'grandparent'.

The 'child' inherits the traits of 'grandparent' via two separate paths. It can also inherit directly as

shown by the broken line. The 'grandparent' is sometimes referred to as indirect base class.

Multipath inheritance

Inheritance by the 'child' as shown in Fig. above might pose some problems. All the public

and protected members of, grandparent' are inherited into 'child' twice, first via 'parent1' and again

via 'parent2'. This means, 'child' would have duplicate sets of the members inherited from

'grandparent'. This introduces ambiguity and should be avoided.

Grandparent

Parent 2Parent 1

Child

Page 193: C++ Book

The duplication of inherited members due to these multiple paths can be avoided by making

the common base class (ancestor class) as virtual base class while declaring the direct or

intermediate base classes which is shown as follow:

class A // grandparent

{

… …

… …

};

class B1 : virtual public A // parentl

{

… …

… …

};

class B2 : public virtual A // parent2

{

… …

… …

};

class C : public BI, public B2 // child

{

… … // only one copy of A

… … // will be inherited

};

When a class is made a virtual base class, C++ takes necessary care to see that only one

copy of that class is inherited, regardless of how many inheritance paths exist between virtual base

class and a derived class.

Note: The keywords virtual and public may be used in either order.

Page 194: C++ Book

For example, consider again the student results processing system discussed. Assume that the class

sports derives the roll number from the class student. Then, inheritance relationship will be as

shown below.

As virtual base class As virtual base class

Virtual base class

A program to implement the concept of virtual base class is illustrated below:

VIRTUAL BASE CLASS

#include <iostream>

using namespace std;

class student

{

protected:

int roll_number;

public:

void get_number(int a)

{

roll_number = a;

}

void put_number (void)

{

Sports

Student

Test

Result

Page 195: C++ Book

cout << “Roll No: “ << roll_number << “\n”;

}

};

class test : virtual public student

{

protected:

float part1, part2;

public:

void get_marks(float x, float y)

{

part1 = x; part2 = y;

}

void put_marks(void)

{

cout << “Marks obtained: “ << “\n”

<< “Part1 = “ << “\n”

<<”Part2 = “ << “\n”;

}

};

class sports : public virtual student

{

protected:

float score;

public:

void get_score(float s)

{

score = s;

}

void put_score(void)

{

cout << “Sports wt: “ << score << “\n\n”;

Page 196: C++ Book

}

};

class result : public test, public sports

{

float total;

public:

void display(void);

};

void result :: display(void)

{

total = part1 + part2 + score;

put_number();

put_marks();

put_score();

cout << “Total Score: “ << total << “\n”;

}

int main()

{

result student_!;

student_1.get_number(678);

student_1.get_marks(30.5, 25.5);

student_1.get_score(7.0);

student_1.display();

return 0;

}

The output of program would be:

Page 197: C++ Book

Roll No: 678

Marks obtained:

Part1 = 30.5

Part2 = 25.5

Sport wt: 7

Total Score: 63

MEMBER CLASSES: NESTING OF CLASSES

Inheritance is the mechanism of deriving certain properties of one class into another. We

have seen in detail how this is implemented using the concept of derived classes. C++ supports yet

another way of inheriting properties of one class into another. This approach takes a view that an

object can be a collection of many other objects. That is, a class can contain objects of other classes

as its members as shown below:

class alpha { };

class beta { };

c1ass gamma

{

alpha a; // a is an object of alpha class

beta b; // b is an object of beta class

……

} ;

All objects of gamma class will contain the objects a and b. This kind of relationship is called

containership or nesting. Creation of an object that contains another object is very different than the

creation of an independent object. An independent object is created by it’s constructor when it is

declared with arguments. On the other hand, a nested object is created in two stages. First, the

member objects are created using their respective constructors and then the other 'ordinary' members

are created. This means, constructors of all the member objects should be called before its own

constructor body is executed. This is accomplished using an initialization list in the constructor of

the nested class.

Page 198: C++ Book

Example:

class gamma

{

……

alpha a; // a is object of alpha

beta b; // b is object of beta

public:

gamma (arg1ist): , a(arg1istl), b(arg1ist2)

{

// constructor body

}

};

arglist is the list of arguments that is to be supplied when a gamma object is defined. These

parameters are used for initializing the members of gamma. arglistl is the argument list for, the

constructor of a and arglist2 is the argument list for the constructor of b. arglistl and arglist2 may or

may not use the arguments from arglist. Remember, a(arglistl) and b(arglist2) are function calls and

therefore the arguments do not contain the data types. They are simply variables or constants.

Example:

gamma (int x, int y, float z) : a(x), b(x,z)

{

Assignment section (for ordinary other members)

}

We can use as many member objects as are required in a class. For each member object we

add a constructor call in the initializer list. The constructors of the member objects are called in the

order in which they are declared in the nested class.

Page 199: C++ Book

Summary

An abstract class is one that is not used to create objects. An abstract class is designed

only to act as a base class (to be inherited by other classes).

C++ supports yet another way of inheriting properties of one class into another. This

approach takes a view that an object can be a collection of many other objects. That

is, a class can contain objects of other classes as its members

Questions

1. What is virtual base class?

2. what do you mean by abstract class?

3. when do we make a class virtual?

Page 200: C++ Book

UNIT I

LESSON 21

STREAMS

Objective

C++ streams

C++ stream class

INTRODUCTION

Every program takes some data as input and generates processed data as output following the

familiar input-process-output cycle. It is, therefore, essential to know how to provide the input data

and how to present the results in a desired form. We have, in the earlier chapters, used cin and cout

with the operators >> and << for the input and output operations. But we have not so far discussed as

to how to control the way the output is printed. C++ supports a rich set of I/O functions and

operations to do this. Since these functions use the advanced features of C++ (such as classes,

derived classes and virtual functions), we need to know a lot about them before really implementing

the C++ I/O operations.

Remember, C++ supports all of C's rich set of I/O functions. We can use any of them in the C++

programs. But we restrained from using them due to two reasons. First, I/O methods in C++ support

the concepts of OOP and secondly, I/O methods in C cannot handle the user-defined data types such

as class objects.

c++ uses the concept of stream and stream classes to implement its I/O operations with the console

and disk files. We will discuss in this chapter, how stream classes support the

console- oriented input-output operations. File-oriented I/O operations will be discussed in

the next chapter.

C++ STREAMS

The I/O system in C++ is designed to work with a wide variety of devices including terminals, disks,

and tape drives. Although each device is very different, the I/O system supplies an interface to the

programmer that is independent of the actual device being accessed. This interface is known as

stream.

Page 201: C++ Book

A stream is a sequence of bytes. It acts either as a source from which the input data can be obtained

or as a destination to which the output data can be sent. The source stream that provides data to the

program is called the input stream and the destination stream that receives output from the program

is called the output stream. In other words, a program extracts the bytes from an input stream and

inserts bytes into an output stream as illustrated in Fig. 10.1.

output stream

insertion into

Output stream

Fig. Data streams

The data in the input stream can come from the keyboard or any other storage device. Similarly, the

data in the output stream can go to the screen or any other storage device. As mentioned earlier, a

stream acts as an interface between the program and the inputJoutput device. Therefore, a C++

program handles data (input or output) independent of the devices used.

C++ contains several pre-defined streams that are automatically opened when a program begins its

execution. These include cin and cout which have been used very often in our

earlier programs. We know that cin represents the input stream connected to the standard input

device (usually the keyboard) and cout represents the output stream connected to the standard output

device (usually the screen). Note that the keyboard and the screen are default options. We can

redirect streams to other devices or files, if necessary.

Buffers and Synchronization

“What is a buffer?..Lets understand the working of a buffer memory.”

A buffer is a temporary holding area in memory which acts as an intermediary between a program

and a file or other I/0 device. Information can be transferred between a buffer and a file using large

chunks of data of the size most efficiently handled by devices like disc drives. Typically, devices

like discs transfer information in blocks of 512 bytes or more, while program often processes

information one byte at a time. The buffer helps match these two desperate rates of information

Page 202: C++ Book

transfer. On output, a program first fills the buffer and then transfers the entire block of data to a

hard disc, thus clearing the buffer for the next batch of output. C++ handles input by connecting a

buffered stream to a program and to its source of input. similarly, C++ handles output by connecting

a buffered stream to a program and to its output target.

When we operate with file streams, these are associated to a buffer of type streambuf.. For example,

with an out stream, each time the member function put (write a single character) is called, the

character is not written directly to the physical file with which the stream is associated. Instead of

that, the character is inserted in the buffer for that stream.

When the buffer is flushed, all data that it contains is written to the physic media (if it is an out

stream) or simply erased (if it is an in stream). This process is called synchronization and it takes

place under any of the following circumstances:

When the file is closed: before closing a file all buffers that have not yet been completely written or

read are synchronized.

When the buffer is full: Buffers have a certain size. When the buffer is full it is automatically

synchronized.

Explicitly with manipulators: When certain manipulators are used on streams a synchronization

takes place. These manipulators are: flush and endl.

Explicitly with function sync(): Calling member function sync() (no parameters) causes an

immediate syncronization. This function returns an int value equal to -1 if the stream has no

associated buffer or in case of failure

C++ STREAM CLASSES

The C++ I/O system contains a hierarchy of classes that are used to define various streams to deal

with both the console and disk files. These classes are called stream classes. Figure shows

the hierarchy of the stream classes used for input and output operations with the console unit.

Page 203: C++ Book

pointer

Input output

Fig. Stream classes for console I/O operations

These classes are declared in the header file iostream. This file should be included in all the

programs that communicate with the console unit.

As seen in the Fig. ios is the base class for istream (input stream) and ostream (output stream) which

are, in turn, base classes for iostream (input/output stream). The class ios is declared as the virtual

base class so that only one copy of its members are inherited by the iostream.

The class ios provides the basic support for formatted and unformatted I/O operations. The class

istream provides the facilities for formatted and unformatted input while the class ostream (through

inheritance) provides the facilities for formatted output. The class iostream provides the facilities for

handling both input and output streams. Three classes, namely, istream- withassign, ostream-

withassign, and iostream- withassign add assignment operators to these classes. Table gives the

details of these classes.

Table

Class name Contents

1. IOS Contains basic facilities that are (General

(input/output stream used by all other input and output

ios

streambufistream ostream

iostream

ostream_withassigniostream_withassignistream_withassign

Page 204: C++ Book

class) . classes.

Also contains a pointer to a buffer object (streambuf object).

Declares constants and functions that are necessary for handling formatted input and output

operations.

2. istream inherits the properties of ios.

(input stream) Declares input functions such as get(), getline()

and read().

Contains overloaded extraction operator.

3. ostream (output stream) inherits the properties of ios.

Declares output functions put() and write().

4. iostream (input / output stream) inherits the properties of ios istream and

ostream through multiple inheritance ,and thus

contains all the input and output functions.

5. streambuf Provides an interface to physical devices

through buffers.

Acts as a base for filebuf class used ios files.

Summary

C++ supports all of C's rich set of I/O functions.

First, I/O methods in C++ support the concepts of OOP and secondly, I/O methods in C

cannot handle the user-defined data types such as class objects.

The I/O system in C++ is designed to work with a wide variety of devices including

terminals, disks, and tape drives.

A stream is a sequence of bytes. It acts either as a source from which the input data can

be obtained or as a destination to which the output data can be sent.

The source stream that provides data to the program is called the input stream and the

destination stream that receives output from the program is called the output stream.

A buffer is a temporary holding area in memory which acts as an intermediary between a

program and a file or other I/0 device.

Page 205: C++ Book

When we operate with file streams, these are associated to a buffer of type streambuf

When the buffer is flushed, all data that it contains is written to the physic media (if it is

an out stream) or simply erased (if it is an in stream)

The C++ I/O system contains a hierarchy of classes that are used to define various

streams to deal with both the console and disk files.

ios is the base class for istream (input stream) and ostream (output stream) which are, in

turn, base classes for iostream (input/output stream).

Question

What is stream?. Explain C++ stream classes?

Describe briefly the features of I/O system supported by C++.

Page 206: C++ Book

UNIT I

LESSON 22

STREAMS II

Objective

Put & Get Function

Getline & Write function

put() and get() Functions

The classes istream and ostream define two member functions get() and put() respectively to handle

the single character input/output operations. There are two types of get() functions. We can use both

get(char *) and get (void) prototypes to fetch a character including the blank space, tab and the

newline character. The get (char *) version assigns the input character to its argument and the get

(void) version returns the input character.

Since these functions are members of the input/output stream classes, we must invoke them using an

appropriate object.

Example:

char c;

cin.get(c) ; // get a character from keyboard and assign it to c

while(c != '\n')

{

cout « c; // display the character on screen

cin.get(c); // get another character

}

This code reads and displays a line of text (terminated by a newline character). Rememter, the

operator >> can also be used to read a character but it will skip the white spaces and newline

character. The above while loop will not work properly if the statement

ci n >> c;

Page 207: C++ Book

is issued in place of

cin.get(c) ;

The get(void) version is used as follows:

cha r c;

c=cin/get(); // cin.get(c); replaced

…………

…………

The value returned by the function get() is assigned to the variable c.

The function put(), a member of ostream class, can be used to output a line of text, character by

character.

For example,

cout.put( ‘x’);

displays the character x and

cout. put (ch) ;

displays the value of variable ch.

The variable ch must contain a character value. We can also use a number as an argument to the

function put(). For example,

cout. put (68) ;

displays the character D. This statement will convert the int value 68 to a char value display the

character whose ASCII value is 68.

The following segment of a program reads a line of text from the keyboard and displays on the

screen.

char c;

cin.get(c); / / read a character

while (c ! = ‘ \n ‘ )

{

cout.put(c) ;

Page 208: C++ Book

cin.get(c); / / display the character on screen

}

Program illustrates the use of these two character-handling functions.

# include <iostream>

int main()

{

int count = 0;

char c;

cout << "INPUT TEXT\n”;

cin.get{c);

while(c!=’\n’)

{

cout.put(c);

count++ ;

cin.get( c);

}

cout <<"\n Number of characters = “<< cout << “\n”;

return 0;

}

Input

Object Oriented Programming

Output

Object Oriented Programming

Number of characters = 27

Page 209: C++ Book

Getline() and write() Functions

We can read and display a line of text more efficiently using the line-oriented input / output

functions getline() and write(). The getline() function reads a whole line of text that ends with a

newline character (transmitted by the RETURN key). This function can be invoked by using the

object cin as follows:

This function call invokes the function getline() which reads character input into the variable line.

The reading is terminated as soon as either the newline character '\n' is encountered or size-1

characters are read (whichever occurs first). The newline character is read but not saved. Instead, it

is replaced by the null character. For example, consider the following code:

char name [20] ;

cin.getl i ne(name, 20);

Assume that we have given the following input through the keyboard:

Bjarne Stroustrup <press RETURN>

This input will be read correctly and assigned to the character array name. Let us suppose the input is

as follows:

Object Oriented Programming <press RETURN>

In this case, the input will be terminated after reading the following 19 characters:

Object Oriented Pro

Remember, the two blank spaces contained in the string are also taken into account. We can also

read strings using the operator» as follows:

cin >> name;

But remember cin can read string that do not contain white spaces. This means that cin

Cin.getline(line,size);

Page 210: C++ Book

Can read just one word and not a series of Word such as “Bjarne Stroustrup”. But it can read the

following string correctly.

Bjarne_Stroustrup

After reading the string, cin automatically adds the terminating null character to the character array.

#include <iostream.h>

int main()

{

int size = 20;

char city[20];

cout<<” enter city name : \n”;

cin>> city;

cout<<”city name:”<<city<<”\n\n”;

cout<<” enter city name again : \n”;

cin.getline(city, size);

cout<<”city name now : “ <<city << “\n\n”;

cout<<”enter another city name:\n”;

cin.getline(city, size);

cout<<”new city name :” << city << “\n\n”;

return 0;

}

output

first run

enter city name:

Delhi

City name: Delhi

enter city name again:

city name now:

Page 211: C++ Book

enter another city name:

chennai

new city name: chennai

Second run

enter city name:

New Delhi

City name: New

enter city name again:

city name now: Delhi

enter another city name:

Greater Mumbai

new city name: Greater Mumbai

During first run, the newline character '\n' at the end of "Delhi" which is waiting in the input queue is

read by the getline() that follows immediately and therefore it does not wait for any response to the

prompt 'Enter city name again:'. The character '\n' is read as an empty line. During the second run,

the word "Delhi" (that was not read by cin) is read by the function getline() and, there(ore, here

again it does not wait for any input to the prompt 'Enter city name again:'. Note that the line of text

"Greater Bombay" is correctly read by the second cin.getline(city,size); statement.

Write() function displays an entire line and has the following form:

Cout.write (line, size)

First argument line represents the name of the string to be displayed and the second argument size

indicates the number of characters to display. Note that it does not stop displaying the Characters

automatically when the null character is encountered. If the size is greater than the «line, then it

displays beyond the bounds of line. Program illustrates how write() displays a string.

Displaying string with Write()

Page 212: C++ Book

#include<iostream,h>

#include<string.h>

int Main()

{

char * string1 = “C++”

char * string2 = “Programming”;

int m = strlen(string1);

int n = strlen(string2);

for(int i=1; i<n; i++)

{

cout.write(string2,i);

cout<< “\n”;

}

for(int i=n; i>0; i--)

{

cout.write(string2,i);

cout<< “\n”;

}

cout.write(string1,m).write(string2,n);

cout<< “\n”;

cout. write(string1,10);

return 0;

}

output

P

Pr

Pro

Prog

Progr

Page 213: C++ Book

Progra

Program

Programm

Programmi

Programmin

Programming

Programmin

Programmi

Programm

Program

Progra

Progr

Prog

Pro

Pr

P

C++ Programming

C++ Progr

The last line of the output indicates that the statement

cout.write(string1, 10);

displays more characters than what is contained in stringl.

It is possible to concatenate two strings using the write() function. The statement

cout.write(string1, m).write(string2, n);

is equivalent to the following two statements:

cout.write(string1, m);

cout.write(string2, n);

Summary

The classes istream and ostream define two member functions get() and put() respectively

to handle the single character input/output operations.

Page 214: C++ Book

The function put(), a member of ostream class, can be used to output a line of text,

charac-ter by character.

We can read and display a line of text more efficiently using the line-oriented input /

output functions getline() and write().

The getline() function reads a whole line of text that ends with a newline character

Write() function displays an entire line

Question

Discuss the various forms of get() function supported by the input stream. How are they used?

How do the following two statements differ in operation?

cin>>c;

cin.get(c);

Both cin & getline() function can be used for reading a string. Comment?

Page 215: C++ Book

UNIT ILesson 23

Tutorial on polymorphism and Streams

Page 216: C++ Book

UNIT ILESSON 24

WORKING WITH FILES

Objectives Opening a file with constructors File stream classes

INTRODUCTIONMany real-life problems handle large volumes of data and, in such situations, we need to use

some devices such as floppy disk or hard disk to store the data. The data is stored in these devices

using the concept of files. A file is a collection of related data stored in a particular area on the disk,

Programs can be designed to perform the read and write operations on these files. A program

typically involves either or both of the following kinds of data communication:

1. Data transfer between the console unit and the program.

2. Data transfer between the program and a disk file.

This is illustrated in Fig. below

External memory

Programfile interaction

Write Data Read data(to files) (from files)

Internal Memory

cout<< Console –program

(put data interaction to screen)

cin>>(get data fromkeyboard)

Data files

Program + Data

Sceen

Page 217: C++ Book

KeyboardConsole – program – file interaction

We have already discussed the technique of handling data communication between the

console unit and the program. In this chapter, we will discuss various methods available for storing

and retrieving the data from files.

The I/O system of C++ handles file operations, which are very much similar to the console

input and output operations. It uses file streams as an interface between the programs and the files.

The stream that supplies data to the program is known as input stream and the one that receives data

from the program is known as output stream. In other words, the input stream extracts (or reads) data

from the file and the output stream inserts (or writes) data to the file. This is illustrated in Fig. below

Input streamRead data Data input

Output stream Data O/P

Write data

File input and output streams

The input operation involves the creation of an input stream and linking it with the program and the

input file. Similarly, the output operation involves establishing an output stream with the necessary

links with the program and the output file.

ProgramDisk files

Page 218: C++ Book

Iostream file

Fstream file

Fig. Stream classes for file operations

CLASSES FOR FILE STREAM OPERATIONS

The I/O system of C++ contains a set of classes that define the file handling methods. These include

ifstream, ofstream and fstream. These classes are derived from fstreambase and from the

corresponding iostream class as shown in Fig. 11.3. These classes, designed to manage the disk files

are declared in fstream and therefore we must include this file in any program that uses files.

Table shows the details of file stream classes. Note that these classes contain many more features.

Class content

ifstream

Fstream base

filebufofstreamfstream

ios

ostreamstreambuf

iostream

istream

Page 219: C++ Book

Filebuf Its purpose is to set the file buffers to read and write. Contains Openprot constant used in the open() of file stream classes. Also contain close() and open() as member.

fstreambase Provides operations common to the file streams. Serves as a base forfstream, if stream and of stream class. Contains open() and close()functions.

ifstream Provides input operations. Contains openO with default input mode.Inherits the functions getO, getlineO, readO, seekgO and tellgOfunctions from istream.

Ofstream Provides output operations. Contains openO with default output mode. Inheritsput(), see}(p(), !~llP(),. and writ~(), functions from ostream.

Fstream Provides support for simultaneous input and output operations. Contains open() with default input mode. Inherits all the functions from istream and ostream classes through iostream.

OPENING AND CLOSING A FILE

If we want to use a disk file, we need to decide the following things about the file and itsintended use:

1. Suitable name for the file. 2. Data type and structure. 3. Purpose.4. Opening method.

The filename is a string of characters that make up a valid filename for the operating system. It may contain two parts, a primary name and an optional period with extension. Examples:

Input.data Test.doc INVENT.ORY Studentsalary OUTPUT

As stated earlier, for opening a file, we must first create a file stream and then link it to the filename.

A file stream can be defined using the classes ifstream, of stream, and ofstream that are contained in

the header file (stream. The class to be used depends upon the purpose, that is, whether we want to

read data from the file or write data to it. A file can be opened in two ways:

Page 220: C++ Book

Using the constructor function of the class. Using the member function open() of the class.

The first method is useful when we use only one file in the stream. The second method is used when we want to manage multiple files using one stream.

Opening Files Using Constructor

We know that a constructor is used to initialize an object while it is being created. Here, a filename is used to initialize the file stream object. This involves the following steps:

1. Create a file stream object to manage the stream using the appropriate class. That is to say, the class ofstream is used to create the output stream and the class ifstream to create the input stream.

2. Initialize the file object with the desired filename.

For example, the following statement opens a file named "results" for output:

ofstream outfile("results"); / / output only

This creates outfile as an ofstream object that manages the output stream. This object can be any

valid C++ name such as o_file, myfile or fout. This statement also opens the file results and attaches

it to the output stream outfile. This is illustrated in Fig.

DiskOutput stream

Input stream

Two file streams working on separate files

Similarly, the following statement declares infile as an if stream object and attaches it to the file data for reading (input),

Ifstream infile ("data") ; // input only

The program m~y contain statements like:

program

Results file

Data file

Page 221: C++ Book

outfile << "TOTAL"; outfile <<sum; infile >>number;infile >>string;

program1

put dataoutfile

program2 get data

infile

Two file streams working on one file

We can also-use the same file for both reading and writing data as shown in Fig. 11.5. The programs would contain the following statements:

Program 1

--------------------ofstream outfile ("salary"); // creates outfi1e and connects

// "salary" to it----------------------Program 2--------------------ifstream infile ("salary"); // creates infi1e and connects

// "salary" to it----------------------

The connection with a file is closed automatically when the stream object expires (when the program

terminates). In the above statement, when the program l is terminated, the salary file is disconnected

from the outfile stream. Similar action takes place when the program 1 terminates.

………….………….

……………………………..

Salary file

Page 222: C++ Book

Instead of using two programs, one for writing data (output) and another for reading data (input), we

can use a single program to do both the operations on a file.

Example.

--------------------

outfile.close(); // Disconnect salary from outfileifstream infile ("sa1ary") ; // and connect to infile

--------------------

infile.closeO; // Disconnect salary from infile

Although we have used a single program, we created two file stream objects, outfile (to put data to

the file) and infile (to get data from the file). Note that the use of a statement like

outfile.close();

disconnects the file salary from the output stream outfile. Remember, the object outfile still exists

and the salary file may again be connected to outflle later or to any other stream. In this example,

we are connecting the salary file to infile stream to read data.

Program uses a single file for both writing and reading the data. First, it takes data from the

keyboard and writes it to the file. After the writing is completed, the file is closed. The program

again opens the same file, reads the information already written to it and displays the same on the

screen.

Working with single file

// Creating files with constructor function

#include <iostream.h>#include <fstream.h>int main(){ofstream outf("ITEM");cout « "Enter item name:" ; char name [30] ;

Page 223: C++ Book

cin >> name;outf << name « "\n";cout << "Enter item cost:"; float cost;cin >> cost;outf << cost « "\n.";outf.close();ifstream inf ("ITEM") ;inf>> name; inf >>cost;cout << "\n.";cout << "Item name:” <<name <<”\n”;cout « "Iterm cost:” << cost <<”\n”;inf.close();return 0;}

The output of Program would be:

Enter itern name: CD-ROM Enter item cost : 250

Item name:CD-ROM Item cost:250

When a file is opened for writing only, a new file is created if there is no file of that name. If a file

by that name exists already, then its contents are deleted and the file is presented as a dean file. We

shall discuss later how to open an existing file for updating it without losing its original contents.

Opening Files Using open()

As stated earlier, the function open() can be used to open multiple files that use the same stream

object. For example, we may want to process a set of files sequentially. In such cases, we may create

a single stream object and use it to open each file in turn. This is done as follows

Example:

File-stream-class stream-objects;Stream-object.open (“filename”);

Example:

ofstream outfile; //Create stream (for output) outfile.open("DATAl"); // Connect stream to DATAl--------------------------

Page 224: C++ Book

outfile.close() ; // Disconnect stream from DATA1outfile.open("DATA2”); // Connect stream to DATA2

--------------------------outfile.close() ; // Disconnect stream from DATA2

---------------------------

The above program segment opens two files in sequence for writing the data. Note that the first

file is closed before opening the second one. This is necessary because a stream can be connected

to only one file at a time. See following Program.

// Creating files with open() function

#include <iostream.b> #include <fstream.h>

int main(){

ofstream fout; //create output streamfout.open ("country") // connect "country" to it

fout << "United States of America \n"; fout <<; "United Kingdom \n";fout << "South Korea \n";

fout.close(); //disconnect "country" andfout.open ("capital") ; //connect" capita1 "fout<< "Washi ngton\n";fout <<”london \n"; fout <<"Seoul \n";

fout.close(); // disconnect "capital"

// Reading the files const int N= 80; II size of linechar 1ine [N];

ifstream fin; // create input streamfin.open ("country"); // connect "country" to let

cout <<"contents of country file \n";whi1e (f in)

Page 225: C++ Book

{ // check end of filefin.getline(line, N); // read a line cout<< line ; //display it}fin.close(); // disconnect "country" andfin.open("capital "); // connect "capital"cout « "\nContents of capital file \n";while{fin) {fin.getline(line, N); cout << 1ine ;}fin.close();return 0;}

The output of Program would be:

Contents of country file United States of AmericaUnited KingdomSouth Korea

Contents of capital file WashingtonLondonSeoul

Page 226: C++ Book

Disk connect 1 file to fout fout

fin

Connect 1 file to fin

Fig. Streams working on multiple files

At times we may require to use two or more files simultaneously. For example, we may require to

merge two sorted files into a third sorted file. This means, both the sortedfilesha1!1 to be kept open

for reading and the third one kept open for writing. In such cases, we need create two separate input

streams for handling the two input files and one output stream for handling the output file.

// Reads the files created in Program

#include <iostream.h> #include <fstream.h>#include <stdlib.h> / / for exit() function

int main(){const int SIZE = 80; char line[SIZE];ifstream fin1, fin2; create two input streamsfin1.open(“country") ; fin2.open(”capital");for(int i=l; i<=10; i++){if(fin1.eof() ! = 0){cout <<”Exit from country \n";exit(1);}fin1.getline(line.SIZE);cout<< "Capital of "<<line;if(fin2.eof() != 0)

Country file

Capital file

program

program

Page 227: C++ Book

{cout<< "Exit from capital\n";exit (1) ;}

fin2.getline(line, SIZE); cout << 1ine << "\n";.}return 0;

The output of Program would be:Capital of United States of America WashingtonCapital of United KingdomLondonCapita] of South KoreaSeou1

1.4 DETECTING END-OF FILE

Detection of the end-of-file condition is necessary for preventing any further attempt to read data

from the file. This was illustrated in Program by using the statement

while(fi n)

An ifstream object, such as fin, returns a value of 0 if any error occurs in the file operation including

the end-of-file condition. Thus, the while loop terminates when fin returns a valuezero on reaching

the end-of-file condition. Remember, this loop may terminate due to other failures as well. (We will

discuss other error conditions later.)

There is another approach to detect the end-of-file condition. Note that we have used the

following statement in above Program

if(fin1.eof() ! = 0) {exit(l);}

eof() is a member function of ios class. It returns a non-zero value if the end-of-file (EOF) condition is encountered, and a zero, otherwise. Therefore, the above statement terminates the program on reaching the end of the file.

Page 228: C++ Book

Summary.

The C++ I/O system contains classes such as ifstream, ofstream and fstream todeal with file

handling. These classes are derived from fstreambase class and aredeclared in a header file

iostream.

A file can be opened in two. ways by using the constructor function of the class andusing the

member function open() of the class.

While opening the file using constructor, we need to pass the desired filename as a parameter

to the constructor.

The openO function can be used to open multiple files that use the same stream object. The

second argument of the openO function called file mode, specifies the purpose for which the

file is opened.

If we do not specify the second argument of the openO function, the default values specified

in the prototype of these class member functions are used while opening the file.

Questions

1 What are input and output streams?

2 What are the steps involved in using a file in a C++ program?

3 Describe the various classes available for file operations?

4 What is the difference between opening a file with a constructor function and opening

a file with openO function? When is one method preferred over the other?

Page 229: C++ Book

UNIT ILesson 25

Working with files II

Objective

File modes file pointers sequential access file Random access file

MORE ABOUT OPEN(): FILE MODES

We have used ifstream and of stream constructors and the function open() to create new files as well

as to open the existing files. Remember, in both these methods, we used only one argument that was

the filename. However, these functions can take two arguments, the second one for specifying the

file mode. The general form of the function open() with two arguments is:

stream-object.open("filename", mode);

The second argument mode (called file mode parameter) specifies the purpose for which file is

opened. How did we then open the files without providing the second argument in the previous

examples?

The prototype of these class member functions contain default values for the second argument and

therefore they use the default values in the absence of the actual values. The default valuel are as

follows:

ios::in for ifstream functions meaning open for reading only.

ios::out for ofstream functions meaning open for writing only.

The file mode parameter can take one (or more) of such constants defined in the class ios.

lists the file mode parameters and their meanings.

Table File mode parameters

Parameter Meaning

ios::app Append data to the end of the output file.

ios::ate Go to the end of the file when opened.

Page 230: C++ Book

ios::in Open for reading only

ios::out Open file for output

ios::binary Binary file (if not present, the file is opened as an ASCII file). See the later section "Binary I/O" for a definition of a binary file.

ios::trunc Delete contents of existing file when opening for write.

ios::nocreate Fail if the file does not exist. (Output files only. Opening an input file always fails if there is no file.)

ios::noreplace Open files if the file already exists

1. Opening a file in ios::out mode also opens it in the ios::trunc mode by default.

2. Both ios:app and ios::ate take us to the end of the file when it is opened, The difference

between the two parameters is that the ios::app allows us to add data to the end of the file

only, while ios::ate mode permits us to add data or to modify the existing data anywhere in

the file. In both the cases, a file is created by the specified name, if it does not exist.

3. The parameter ios::app can be used only with the files capable of output.

4. Creating a stream using ifstream implies input and creating a stream using ofstream implies

output. So in these cases it is not necessary to provide the mode parameters.

5. The fstream class does not provide a mode by default and therefore, we must provide the

mode explicitly when using an object of fstream class.

6. The mode can combine two or more parameters using the bitwise OR operator (symbol I )

shown as follows:

fout.open("data", ios::app | ios:: nocreate)

This opens the file in the append mode but fails to open the file if it does not exist.

FILE POINTERS AND THEIR MANIPULATIONS

Each file has two associated pointers known as the file pointers. One of them is called the

input pointer (or get pointer) and the other is called the output pointer (or put pointer). We can use

pointers to move through the files while reading or writing. The input pointer is used for reading the

contents of a given file location and the output pointer is used for writing to a given location. Each

time an input or output operation takes place, the appropriate pointer is

Page 231: C++ Book

automatically advanced.

Default Actions

When we open a file in read-only mode, the input pointer is automatically set at the beginning So

that we can read the file from the start. Similarly, when we open a file in write-only mode, the

existing contents are deleted and the output pointer is set at the beginning. This enables us to it write

to the file from the start. In case, we want to open an existing file to add more data, the file is opened

in 'append' mode. This moves the output pointer to the end of the file (i.e. the end of the existing

contents).

"hello" file

Open for reading only

input pointer

Open in append mode (for writing more data)

output pointer

Open for writing only

output pointer

Action on file pointers while opening a file

Functions for Manipulation of File Pointers

All the actions on the file pointers as shown in Fig. take place automatically by default. How do we

then move a file pointer to any other desired position inside the file? This is possible only if we can

take control of the movement of. the file pointers ourselves. The file stream classes support the

following functions to manage such situations:

seekg() Moves get pointer (input) to a specified location.

seekp() Moves put pointer(output) to a specified location.

H E L L O W O R L D

H E L L O W O R L D

Page 232: C++ Book

tellg() Gives the current position of the get pointer.

Tellp() Gives the current position of the put pointer.

For example, the statement

infile.seekg (10 );

moves the file pointer to the byte number 10. Remember, the bytes in a file are numbered beginning

from zero. Therefore, the pointer will be pointing to the 11th byte in the file.

Consider the following statements:

ofstream fileout; fileout.open("hello", ios::app); int p = fileout.tellp();

On execution of these statements, the output pointer is moved to the end of the file "hello" an! the

value of p will represent the number of bytes in the file.

Specifying the offset

We have just now seen how to move a file pointer to a desired location using the 'seek' functions.

The argument to these functions represents the absolute position in the file. This is shown Fig file

file pointer

start end

outfile.seekp(m);

m-bytesFile pointer

'Seek' functions seekg() and seekp() can also be used with two arguments as follows:

seekg (offset, ref position); seekp (offset, refposition);

Page 233: C++ Book

The parameter offset; represents the number of bytes the file pointer is to be moved from the

location specitied by the-parameter refposition.. The refposition takes one of the following three

constants defined in the ios class:

ios::beg start of the file ios::cur current position of the pointer ios::end end of the file

The seekg() function moves the associated file's 'get' pointer while the seekp() functionmoves the associated file's 'put' pointer.

SEQUENTIAL INPUT AND OUTPUT OPERATIONS

File stream classes support a number of member functions for performing the input and output

operations on files. One pair of functions, put() and get(), are designed for handling a single

character at a time. Another pair of functions, write() and read(), are designed to write and read

blocks of binary data.

Put() and get() Functions

Tbe function put() writes a single character to the associated stream. Similarly, the function getO

reads a single character from the associated stream. Program below illustrates how these fnctions

work on a file. The program requests for a string. On reeiving the string, the program writes it,

character by character, to the file using the put() function in a for loop. Note that the length of the

string i& used to terminate the for loop.

The program then displays the contents of the file on the screen. It uses the function get() to fetch a

character from the file and continues to do so until the end-of-file condition is reached. The character

read from the file is displayed on the screen using the operator <<.

#include <iostream.h> #i nclude <fstream.h> #i nclude <string.h>

int main()

Page 234: C++ Book

{char string[80];cout<<« n Enter a string \n ";cin>>string;

int len = strlen(string);fstream file; // input and output streamfile.open(“TEXT", ios::in | ios::out);for(int i=0; i<len; i++)

fi1e.put(string [i]); // put a character to file

file.seekg(0); // go to the startchar ch; while(file)

{file.get(ch) ; // get a character from filecout << ch; //display it ()n screen}

return 0;}

The output of Program would be

Enter a string

Cobol_Programming inputCobol_Programming output

We have useid an fstream objectto open the file. Since an fstream object can handle both the input

and output simultaneously, we have opened the file in ios::in | ios::out mode. After writing the file,

we want to read the entire file and display its content. Since the file pointer has already moved to

the end of the file, we must bring it back to the start of the file. This is done by the statement

file.seekg(0);

Write() and read() Functions for Binary files

The functions write() and read(), unlike the functions put() and get(), handle the data in binary form.

This means 'that the values are stored in the disk file in the same format in which they are stored in

the internal memory.

Page 235: C++ Book

The binary format is more accurate fro storing the numbers as they are stored in the exact internal

representation. There are no conversions while saving the data and therefore saving is much faster.

The binary input and output functions takes the following form:

infile. read ((char *) & V, sizeof (V));outfile.write ((char *) & V, sizeof (V));

These functions take two arguments. The first is the address of the variable V, and the second is the

length of that variable in bytes. The address of the variable must be cast to type char' (i.e. pointer to

character type). Program 11.5 illustrates how these two functions are used to save an array of float

numbers and then recover them for display on the screen.

Prog.: I/O operation on Binary Files

# include<iostream.h># include<fstream.h># include<iomainp.h>

const char * filename = "BINARY";

int main(){float height[4] = {175.5,153.0, 167.25, 160.70};ofstream outfile; outfile.open(filename);outfile.write ((char *) & height, sizeof(height));outfile.close();

for(int i;=0; i<4; i++) / / clear array from memoryheight[i] = 0;outfile.close();ifstream infile;infile.open (fi1ename) ;infile.read((char *) & height. sizeof(height));for(i=0;i<4;i++) {cout.setf (ios::showpoint);cout<< setw(10) << setprecision(2)

<< height[i];}return 0;

The output of Program

Page 236: C++ Book

175.50 153.00 167.25

Reading and Writing a Class Object

We mentioned earlier that one of the shortcomings of the I/O system of C is that it cannot handle

user-defined data types such as class objects. Since the class objects are the central element C++

programming, it is quite natural that the language supports features for writing to a reading from

the disk files objects directly. The binary input and output functions read() and write() are designed

to do exactly this job. These functions handle the entire structure of object as a single unit, using the

computer's internal representation of data. For instance, function write() copies a class object from

memory byte by byte with no conversion. one important point to remember is that only data members

are written to the disk me and member functions are not.

Program illustrates how class objects can be written to and read from the disk file!. The length of the

object is obtained using the sizeof operator. This length represents them total of lengths of all data

members of the object.

#include <iostream.h> #include <fstream.h>#include <iomainp.h>

class INVENTORY {

char name,[10]; // item nameint code; // item code

Page 237: C++ Book

float cost; / / cost of each itempublic:void readdata(void);void writedata(void);

};void INVENTORY:: readdata(void){//read from keyboardcout << "Enter name: ;cin >> name; cout << " Enter code:”; cin >> code; cout <<"Enter cost:”; cin>> cost;}void INVENTORY:: writedata (void) / / formatted{ / / screencout << setiosflags(ios::left)<< setw(10) << name.<< setiosflags(ios: :right)<< setw(10)<< code<< setprecision(2}<< setw(lO) <<<< endl;

}int main () {INVENTORY item[3];fstream fi1e;file.open (“STOCK.DAT” , ios::in | ios::out);cout << “ENTER DETAILS FOR THREE ITEMS \n” ;for(int i =0; i <3; i ++){item[i].readdata();file.write((char*) & item[i] .sizeof(item[i]));}file. seekg (0);cout << “\nOUTPUT\n\n”; for(i= 0; i < 3;I++) {

file. read [(char *) & item[ih sizeof(i tem[i]»; i tem[i] .writedata 0;return 0;}

Page 238: C++ Book

The output of Program

ENTER DETAILS FOR THREE ITEMS

Enter name: C++ Enter code: 101 Enter cost: 175Enter name: FORTRAN Enter code: 102 Enter cost: 150 Enter name: JAVA Enter code: 115 Enter cost: 225

OUTPUT

C++ 101 175 FORTRAN 102 150JAVA 115 225

The program uses 'for' loop for reading and writing objects. This is possible because we Know the

exact number of objects in the file. In case, the length of the file is not known, we can determine the

file-size in terms of objects with the help of the file pointer functions and use it in the 'for' loop or we

may use while (file) test approach to decide the end of the file. These techniques are discussed in the

next section.

UPDATING A FILE: RANDOM ACCESS

Updating is a routine task in the maintenance of any data file. The updating would include one or

more of the following tasks:

Displaying the contents of a file.

Modifying an existing item.

Adding a new item.

Deleting an existing item.

These actions require the file pointers to move to a particular location that corresponds to the

item/object under consideration. This can be easily implemented if the file contains a collection of

Page 239: C++ Book

items/objects of equal lengths. In such cases, the size of each object can be obtained using the

statement

int object_length = sizeof(object);

Then, the location of a desired object, say the mth object, may be obtained as follows:

int location = m * object_length;

The location gives the byte number of the first byte of the mth object. Now, we can set the file

pointer to reach this byte with the help of seekg() or seekp().

We can also find out the total number of objects in a file using the object_length as follows:

int n = file_size/object_length;

Tbe file_size can be obtained using the function tellgO or tellpO when the file pointer is located at

the end of the file.

Program illustrates how some of the tasks described above are carried out. The program uses the

"STOCKDAT" file created using Program for five items and performs following operations on the

file:

1. Adds a new item to the file.3. Modifies the details of an item. 4. 3, Displays the contents of the file

#include <iostream. h>#include <fstream.h> #inc1ude <iomanip. h>c1ass INVENTORY {char name[l0] ; int code;float cost;

public:

void getdata(void) {cout << "Enter name: “; ci n >> name ; cout << Enter code:”; cin >> code;cout<<"Enter cost :”;cin >> cost;}void putdata (void) {cout << setw(10) << name << setw(l0) << code

Page 240: C++ Book

<< setprecision(2)<< setw(10) << cost << endl;}}; // End of class definition

int main() {INVENTORY item; fstream inoutfile;

inoutfile.open("STOCK.DAT", ios:: ate | ios:: in |ios::out | ios::binary);inputfile.seekg(0,ios:: beg) ; // go to start

cout << "CURRENT CONTENTS OF STOCK" << "\n";while(inoutfile.read((char *) & item, sizeof item)){item.putdataO;} inoutfi1e.c1ear(); // turn of EOF flag

/* »»»»»»> Add one more item ««««««« * /

cout << "\n ADD AN ITEM \n”;item.getdata(); char ch; cin.get(ch);inoutfile.write( (char & item, si zeof item);

/ / Display the appened file

inoutfi1e.seekg(Q). // go to the startcout << "CONTENTS OF APPENDED FILE \n";

while (inoutfile.read((char *) & item , sizeof item)){item.putdata();}

//find number of objects in the fi1e

int last= inoutfile.tellg();int n = last/sizeof(item);cout << "Number of objects = " « n « "\n";

Page 241: C++ Book

cout <<”Total bytes in the file = ”<<last<<”\n”;

/*<<<<<<<<<<<<MODIFY THE DETAILS OF AN ITEM <<<<<<<<<<< */

cout <<”Enter object number to be updated \n";int object;cin>>object;cin.get(ch);int location=(object-1)*-sizeof(item);

if(inoutfile.eof())inoutfile.clear();

cin.get(ch);I

int location" (object-I) * sizeof(item);if(inout fi1e .eof()) inoutfile.clear() ;

inoutfi1e.seekp(location) ;cout << "Enter new values of object \n"; item.getdata(); cin.get(ch);

inoutfile.write«char *) & item, sizeof item)?<< flush;

/-*»»»»»»> SHOW UPDATED FILE ««««<<<<<<< */

inoutfile.seekg(O); // go to the start

cout << "CONTENTS OF. UPDATED FILE \n”;

while(inoutfile.read((char *) & item sizeof item)){item.putdata() ;}

inoutfile.close();

return 0; } //End of main

The output of Program would be:

CURRENT CONTENTS OF STOCK

Page 242: C++ Book

AA 11 100 BB 22 200 CC 33 300 DO 44 400 XX 99 900

ADD AN ITEMEnter name: YY Enter code: 10Enter cost: 101

CONTENTS OF APPENDED FI LEAA 11 100BB 22 200CC 33 300DD 44 400XX 55 500YY 66 600

Number of objects = 6Tota1 bytes in the fi1es = 96 Enter object number to be updated 6Enter new values of the object Enter name: ZZEnter code: 20Enter cost: 201

CONTENTS OF UPDATED FI LEAA 11 100 SS 22 200 CC 33 300 DD 44 400 XX 99 900 ZZ 20 201

We are using the fstream class to declare the me streams. The fstream class inherits two buffers, one

for input and another for output, and synchronizes the movement of the file pointers on these buffers.

That is, whenever we read from or write to the file, both the pointers move in tandem. Therefore, at

any point of time, both the pointers point to the same byte.

Since we have to add new objects to the file as well as modify some of the existing objects, we open

the file using ios::ate option for input and output operations. Remember, the option ios::app allows

Page 243: C++ Book

us to add data to the end of the file only. The ios::ate mode sets the file pointers at the end of the file

when opening it. We must therefore move the 'get' pointer to the.beginning of the file using the

function seekg() to read the existing contents of the file.

At the end of reading the current contents of the file, the program sets the EOF flag on. This prevents

any further reading from or writing to the file. The EOF flag is turned off by using the function

clear(), which allows access to the file once again.

After appending a new item, the program displays the contents of the appended file and

also the total number of objects in the file and the memory space occupied by them.

To modify an object we should reach to the first byte of that object. This is achieved using

the statements .

int location = (object-1) * sizeof(item};

inoutfile.seekp(location};

The program accepts the number and the new values of the object to be modified and updates it

finally , the contents of the appended and modified file are displayed.

Remember , we are opening an existing file for reading and updating the values. It is, therefore,

essential that the data members are of the same type and declared in the same order as in the , file.

Since, the member functions are hot stored, they can be different.

Summary

When a file is opened for writing only, a new file is created only if there is no file of that

name. If a file by that name already exists, then its contents are deleted and the file is

presented as a clean file.

To open an existing file for updating without losing its original contents, we need to open it

in an append mode.

Page 244: C++ Book

The fstream class does not provide a mode by default and therefore we must provide the

mode explicitly when using an object off stream class. We can specify more than one file

modes using bitwise OR operator while opening a file.

Each file has associated two file pointers, one is called input or get pointer, while the other is

called output or put pointer. These pointers can be moved along the files by member

functions.

putO and getO functions handle single character at a time. writeO and readO functions write

and read blocks of binary data

.

Questions

1 .What is a file mode? Describe the various file mode options available.

2 Write a statement that will create an object called fob/or writing, and associate it with a file name

DATA.

How many file objects would you need to create to manage the following situations?

(a) To process four files sequentially.

(b) To merge two sorted files into a third file.

Explain.

Both ios::ate and ios::app place the file pointer at the end of the file (when it is opened). What then,

is the difference between them?

Page 245: C++ Book

UNIT I

Lesson 26

Working with file III

Objectives

Error handling Command line arguments

ERROR HANDLING DURING FILE OPERATIONS

So far we have been opening and using the files for reading and writing on the assumption that

everything is fine with the files. This may not be true always. For instance, one of the Following

things may happen when dealing with the files:

1. A file which we are attempting to open for reading does not exist.

2, The file name used for a new file may already exist.

3, We may attempt an invalid operation such as reading past the end-of-file.

4. There may not be any space in the disk for storing more data.

5. We may use an invalid file name.

6. We may attempt to perform an operation when the file is not opened for that purpose.

The c++ file stream inherits a 'stream-state' member from the class ios. This member records

information on the status of a file that is being currently used. The stream state member uses bit

fields to store the status of the error conditions stated above.

The class ios supports several member functions that can be used to read the status ! recorded in a

file stream. These functions along with their meanings are listed in Table

Table

Error handling functionsfunction Return value and meaning

Returns true (non-zero value) if end-of-file is encounteredeofOwhile reading;Otherwise returns false(zero)

Fail() Returns true when an input or output operation has failed

Page 246: C++ Book

BadO Returns true if an invalid operation is attempted or anyUnrecoverable error has occurred. However, if it is false, itMay be possible to recover from any other error reported,And continue operation.

goodO Returns true if no error has occurred. This means, all theAbove functions are false. For instance, if file.goodO isTrue, all is well with the stream file and we can ,proceed toPerform I/O operations. When it returns false, no furtherOperations can be carried out. .

These functions may be used in the appropriate places in a program to locate the status of a file stream and thereby to take the necessary corrective measures. Example:

ifstream infile; infile.open("ABC"); while(!infile.fail ()){…………(process the fi 1 e)……..…..

}i f(infi1e.eof()){(terminate program normally)

}

elseif(infile.bad()){}else{ infile.clear() ;

……… (report fatal error) // clear error state……..

Page 247: C++ Book

}…..………

The function clear() (which we used in the previous section as well) resets the error stateSil that further operations can be attempted.Remember that we have already used statements such aswhile(infile) {

…….……..}andwhile(infile.read(……))

{…….……

Here, infile becomes false (zero) when end of the file is reached ( and eofO becomes true).

COMMAND-LINE ARGUMENTS

Like C, C++ too supports a feature that facilitates the supply of arguments to the main() function.

These arguments are supplied at the time of invoking the program. They are typically used to pass

the names of data files. Example:

C > exam data results

Here, exam is the name of the file containing the program to be executed, and data and results are the

filenames passed to the program as command-line arguments.

The command-line arguments are typed by the user and are delimited by a space. The first argument

is always the filename (command name) and contains the program to be executed. How do these

arguments get into the program?

The main() functions which we have been using up to now without any arguments can take two

arguments as shown below:

main(int argc, char * argv[])

The first argument argc (known as argument counter) represents the number of arguments in the

command line. The second argument argv (known as argument vector) is an array of char type

pointers that points to the command line arguments. The size of this

Page 248: C++ Book

array will be equal to the value of argc. For instance, for the command line.

C > exam data results

the value of argc would be 3 and the argv would be an array of three pointers to strings as shown below:argu [0]_> exam argu [1] n_> dataargu[2] ---> results

Note that argv[0] always represents the command name that invokes the program. The character pointers argv[l] and argv[2] can be used as file names in the file opening statements as shown below:

……..……..infile.open(argv[l]); // open data fi 1 e for reading

outfile.open(argv[2]); // open results file for writing

Program illustrates the use of the command-line arguments for supplying theThe command line is

Test ODD EVEN

The program creates two files called ODD and EVEN using the command-line arguments and a set

of numbers stored in an array are written to these files. Note that the odd numbers are written to the

file ODD and the even numbers are written to the file EVEN. The then displays the contents of the

files.

#include <iostream.h> #include <fstream.h> #include <stdlib.h>

main(int argc, char * argv[]){int number [9] = {1l.22.33.44.55!66.77 .88.99};It(argc != 3){

cout<<”argc=”<<argc<<”\n”;cout <<”Error in arguments \n”;exit(1);}

Page 249: C++ Book

ofstream foutl. fout2;

fout1.open(argv[1]);if(fout1.fail()){

cout << could not open. the file”<< argv[2] <<” \n”;

exit(1);}for ( int i=0; i<9;i++){if(number[ i ] % 2 == 0) fout2 « number[i] « “ "; // write to. EVEN file

e1sefout 1<< number[i]<<” ”; // write to ODD file

}fout1.close();fout2.close();

ifstream. fin;

char ch;

for(i=1; i<argc; i++){fin.open(argv[i]);

cout « "Contents of “<< argv[i] << “\n”;

do .{fin.get(ch); / / read a valuecout << ch; / / display it}while(fin); cout << ''\n\n”;fin.close();} return 0;}

The output of Program would be:

Cantents af ODD 11 33 55 77 99

Page 250: C++ Book

Cantents af EVEN 22 44 66 88

Page 251: C++ Book

Summary

. The class ios supports many member functions for managing errors that may occur during

file operations.

File names may be supplied as arguments to the main() function at the time of invoking the

program. These arguments are known as command-line arguments.

.

Questions

1. What does the "current position" mean when applied to files?

2. Write statements using seekg() to achieve the following:

(a) To move the pointer by 15 positions backward from current position.

(b) To go to the beginning after an operation is over.

(c). To go backward by 20 bytes from the end.

(d) To go to byte number 50 in the file.

Page 252: C++ Book

UNIT I

LESSON 27

TEMPLATE I

Objective

Need of Template

Class template

Templates

INTRODUCTION (Need of Template)

Templates is one of the features added to C++ . It is a new concept which enable us define generic

classes and functions and thus provides support for generic programming. Generic programming is

an approach where generic types are used as parameters in algorithms so that they work for a variety

of suitable data types and data structures. Support for generic programming in C++ is considered by

some to be as important a language goal for C++ as is support for object-oriented programming

(using base/derived classes and virtual functions).

Templates are a powerful but complex feature, about which we will have more to say. Languages

like C or Java(tm), that do not have templates, typically use macros or rely on using base class

pointers and virtual functions to synthesize some of the properties of templates.

A template can be used to create a family of classes or functions. For example, a class template for

an array class would enable us to create arrays of various data types such as int

Array and float array. Similarly, we can define a template for a function, say mul( ), that would help

us create various versions of mul( ) for multiplying, int, float and double types.

Page 253: C++ Book

A template can be considered as a kind of macro. When an object of a specific type is led for actual

use, the template definition for that class is substituted with the required type. Since a template is

defined with a parameter that would be replaced by a specified type at the time of actual use of the

class or function, the templates are sometimes called parameterized classes or functions.

CLASS TEMPLATES

Consider a vector class defined as follows:

class vector

{

int *v;

int size;

public:

vector(int m) / /, create a null vector

{

v = new int[size = m];

for(int i=0; i<size; i++)

v[i] = 0;

}

vector(int *a) / / create a vector from an array

{

for(int i=O; i<size; i++)

v[i] = a[i];

}

int operator*(vector &y) / / scalar product

{

int sum = 0;

for(int i=0; i<size; i++)

sum += this -> v[i] * Y - v[i];

Page 254: C++ Book

return sum;

}

};

The vector class can store an array of int numbers and perform the scalar product of vectors as

shown below:

int main( )

{

int x[3] = {1,2,3};

int y[3] = {4,5,6};

vector v1(3); / / Creates a nuII vector of 3 integers

vector v2(3);

v1= x; / / Creates v 1 from the array x

v2= y;

int R = v1 * v2;

cout<< “R = “ R;

return 0;

}

Now suppose we want to define a vector that can store an array of float values. We can do this by

simply replacing the appropriate int declarations with float in the vector class. This means that we

have to redefine the entire class all over again.

Assume that we want to define a vector class with the data type as a parameter and then use this

class to create a vector of any data type instead of defining a new class every time. The template

mechanism enables us to achieve this goal.

As mentioned earlier, templates allow us to define generic classes. It is a simple process to create a

generic class using a template with an anonymous type. The general format of a class template is:

template<class T>

class classname

{

// .........

Page 255: C++ Book

// class member specification

// with anonymous type T

// wherever appropriate

// .........

);

The template definition of vector class shown below illustrates the syntax of a template:

template<class T>

class vector

{

T* v; / / Type T vector

int size;

public:

vector(int m)

{

v = new T [size = m];

for(int i=0; i<size; i++)

v[i] = 0;

}

vector(T* a)

{

for(int i=0; i<size; i++)

v[i]=a[i];

}

T operator*(vector &y)

{

T sum = 0;

for(int i=0; i<size; i++)

sum += this -> v[i] * Y - v[i];

return sum;

}

};

Page 256: C++ Book

Remember:

Class template definition is very similar to an ordinary class definition except. prefix

template<class T> and the use of type T. This prefix tells the compiler Iii we are going to declare a

template and use T as a type name in the declaration, Thus vector has become a parameterized class

with the type T as its parameter, T may be substituted by any data type including the user-defined

types. Now, we can create vectors for holding different data types.

Example:

vector <int> v1(10); // 10 element int vector

vector <float> v2 (25) ; // 25 element float vector

Remember:

The type T may represent a class name as well.

Example:

vector <complex> v3(5); // vector of 5 complex numbers

A class created from a class template is called a template class. The syntax for defining, object of a

template class is:

classname<type> objectname (arglist) ;

This process of creating a specific class from a class template is called instantiation, compiler will

perform the error analysis only when an instantiation takes place. So it is, advisable to create and

debug an ordinary class before converting it into a template.

Following Programs illustrate the use of a vector class template for performig scalar product of int

type vectors as well as float type vectors.

#include <iostream>

const size = 3;

Page 257: C++ Book

Template.<class T>

Class vector

{

T* V; // type T vector

Public :

Vector( )

{

v = new T[size];

for(int i=0;i<size;i++)

{

v[i]= 0

}

}

vector(T* a)

{

for(int i=0;i<size;i++)

{

v[i]= a[i];

}

}

T operator* (vector &y)

{

T sum = 0;

for(int i=0;i<size;i++)

{

sum + = this-> v[i] * y.v[i];

return sum;

}

};

int main()

{

int x[3] = {1,2,3);

Page 258: C++ Book

int y[3] = {4,5,6);

vector <int> v1;

vector <int> v2;

vl = X;

v2 = Y;

int R = v1 * v2;

cout <<” R = “ << R << “\n”;

return 0;

}

Output R= 32

Here is another example of class template

While implementing class template member functions, the definitions are prefixed by the keyword

template. Here is the complete implementation of class template Stack:

//stack.h

#pragma once

template <class T>

class Stack

{

public:

Stack(int = 10) ;

~Stack( ) { delete [] stackPtr ; }

int push(const T&);

int pop(T&) ; // pop an element off the stack

int isEmpty( )const { return top == -1 ; }

int isFull( ) const { return top == size - 1 ; }

private:

int size ; // Number of elements on Stack

int top ;

T* stackPtr ;

Page 259: C++ Book

} ;

//constructor with the default size 10

template <class T>

Stack<T>::Stack(int s)

{

size = s > 0 && s < 1000 ? s : 10 ;

top = -1 ; // initialize stack

stackPtr = new T[size] ;

}

// push an element onto the Stack

template <class T>

int Stack<T>::push(const T& item)

{

if (!isFull( ))

{

stackPtr[++top] = item ;

return 1 ; // push successful

}

return 0 ; // push unsuccessful

}

// pop an element off the Stack

template <class T>

int Stack<T>::pop(T& popValue)

{

if (!isEmpty( ))

{

popValue = stackPtr[top--] ;

return 1 ; // pop successful

}

return 0 ; // pop unsuccessful

}

Page 260: C++ Book

Using a class template

Using a class template is easy. Create the required classes by plugging in the actual type for the type

parameters. This process is commonly known as "Instantiating a class".

Here is a sample driver class that uses the Stack class template.

#include <iostream>

#include "stack.h"

using namespace std ;

void main( )

{

typedef Stack<float> FloatStack ;

typedef Stack<int> IntStack ;

FloatStack fs(5) ;

float f = 1.1 ;

cout << "Pushing elements onto fs" << endl ;

while (fs.push(f))

{

cout << f << ' ' ;

f += 1.1 ;

}

cout << endl << "Stack Full." << endl

<< endl << "Popping elements from fs" << endl ;

while (fs.pop(f))

cout << f << ' ' ;

cout << endl << "Stack Empty" << endl ;

cout << endl ;

IntStack is ;

int i = 1.1 ;

Page 261: C++ Book

cout << "Pushing elements onto is" << endl ;

while (is.push(i))

{

cout << i << ' ' ;

i += 1 ;

}

cout << endl << "Stack Full" << endl

<< endl << "Popping elements from is" << endl ;

while (is.pop(i))

cout << i << ' ' ;

cout << endl << "Stack Empty" << endl ;

}

Program Output

Pushing elements onto fs

1.1 2.2 3.3 4.4 5.5

Stack Full.

Popping elements from fs

5.5 4.4 3.3 2.2 1.1

Stack Empty

Pushing elements onto is

1 2 3 4 5 6 7 8 9 10

Stack Full

Popping elements from is

10 9 8 7 6 5 4 3 2 1

Stack Empty

Page 262: C++ Book

Summary

Templates is one of the features added to C++ . It is a new concept which enable us define

generic classes and functions and thus provides support for generic programming.

Generic programming is an approach where generic types are used as parameters in

algorithms so that they work for a variety of suitable data types and data structures.

Templates are a powerful but complex feature

A template can be used to create a family of classes or functions.

This process of creating a specific class from a class template is called instantiation.

While implementing class template member functions, the definitions are prefixed by the

keyword template.

Question

What is Template? Define Class template with suitable example?

Define class template? Give an example of class stack template?

Page 263: C++ Book

UNIT I

LESSON 28

TEMPLATE II

Objective

Function template

Implementing function template

Template Instantiation

FUNCTION TEMPLATES

Like class templates, we can also define function templates that could be used to create family of

functions with different argument types.

To perform identical operations for each type of data compactly and conveniently, use function

templates. You can write a single function template definition. Based on the argument types

provided in calls to the function, the compiler automatically instantiates separate object code

functions to handle each type of call appropriately. The STL algorithms are implemented as function

templates.

The general format of a function template is:

template<class T>

returntype functioname (arguments of type T)

{

// .....

// Body of function

// with type T

// wherever appropriate

// .....

}

Page 264: C++ Book

The function template syntax is similar to that of the class template except that we are defining

functions instead of classes. We must use the template parameter T as and when necessary in the

function body and in its argument list.

Implementing Template Functions

Function templates are implemented like regular functions, except they are prefixed with the

keyword template. Here is a sample with a function template.

#include <iostream>

using namespace std ;

//max returns the maximum of the two elements

template <class T>

T max(T a, T b)

{

return a > b ? a : b ;

}

Following example declares a swap( ) function template that will swap two values of given type of

data.

template<class T>

void swap (T&x, T&y)

{

T temp = X;

X = Y;

Y = temp;

}

This declares a set of overloaded functions, one for each type of data, We can invoke the Swap( )

function like any ordinary function. For example, we can apply the swap Function as follows:

void f(int m, int n, float a, float b)

Page 265: C++ Book

{

swap(m,n); // swap two integer values.

swap(a,b); // swap two float values

//………..

}

This will generate a swap() function from the function template for each set of argument types.

Following shows how a template function is defined and implemented.

Example Function Template

# <inc1ude<iostream>

using namespace std;

template <class T>

Void swap(T &x. T &y)

{

T temp = x;

x =y;

y = temp;

}

void fun (int m. int n, float a, float b)

{

cout <<” m and n before swap: " << m << " “ << n<<”\n”;

swap(m.n);

cout <<” m and n after swap:" << m << " " << n << "\n";

cout « "a and b before swap:" << a << " " << b << "\n";

swap(a.b);

cout « "a and b after swap:" << a << “ " << b << "\n";

}

int main( )

{

Page 266: C++ Book

fun(l00,200,l1.22,33.44) ;

return 0;

}

The output of Program

m and n before swap: 100 200

m and n after swap: 100 200

a and b before swap: 11.22 33.439999

a and b after swap: 33.439999 11.22

Another function often used is sort() for sorting arrays of various types such as int and

double. The following example shows a function template for bubble sort

template<class T>

bubble(T a[], int n)

{

for(int i=0; i<n-l; i++)

for(int j=n-l; i<j; j--)

if(a[j] < a[j-l])

{

T temp = v[j];

v [j] = v [j -1] ;

v[j-l] = temp;

}

}

Note that the swapping statements

T temp = v[j];

v[j] = v[j-l];

v[j-l] = temp;

Page 267: C++ Book

may be replaced by the statement

swap(v[j],v[j-l]);

where swap() has been defined as a function template.

Ex.] Program returns the maximum of the two elements using template function.

#include <iostream>

using namespace std ;

//max returns the maximum of the two elements

template <class T>

T max(T a, T b)

{

return a > b ? a : b ;

}

void main( )

{

cout << "max(10, 15) = " << max(10, 15) << endl ;

cout << "max('k', 's') = " << max('k', 's') << endl ;

cout << "max(10.1, 15.2) = " << max(10.1, 15.2) << endl ;

}

Program Output

max(10, 15) = 15

max('k', 's') = s

max(10.1, 15.2) = 15.2

Page 268: C++ Book

Template Instantiation

When the compiler generates a class, function or static data members from a template, it is referred

to as template instantiation.

A class generated from a class template is called a generated class.

A function generated from a function template is called a generated function.

A static data member generated from a static data member template is called a generated

static data member.

The compiler generates a class, function or static data members from a template

when it sees an implicit instantiation or an explicit instantiation of the

template.

This is an example of implicit instantiation of a class template.

template <class T>

class Z

{

public:

Z( ) {} ;

~Z( ) {} ;

void f( ){} ;

void g( ){} ;

} ;

int main( )

{

Z<int> zi ; //implicit instantiation generates class Z<int>

Z<float> zf ; //implicit instantiation generates class Z<float>

return 0 ;

}

Page 269: C++ Book

Summary

Function templates are implemented like regular functions, except they are prefixed with the

keyword template

When the compiler generates a class, function or static data members from a template, it is

referred to as template instantiation.

A function generated from a function template is called a generated function

Question

What is Template? Define Function template with suitable example?

Show how template function is define & implemented ?

Page 270: C++ Book

UNIT I

LESSON 29

TEMPLATE III

Objective

Class with multiple arguments

Function with multiple arguments

Overloading Of Template Functions

MULTIPLE ARGUMENTS :

CLASS TEMPLATES WITH MULTIPLE PARAMETERS

We can use more than one generic data type in a class template. They are declared as a comma

separated list within the template specification as shown below:

template<class T1, class T2, ...>

class classname

{

……….(Body of the class)

……….

……….

};

Following program demonstrates the use of a template class with two generic data types.

# include<iostream>

using namespace std;

Page 271: C++ Book

template <class T1 , class T2>

class test

{

Tl a;

T2 b;

publ ic:

Test(Tl x, T2 y)

{

a = x;

b = y;

}

void show()

{

cout « a « “and “ «b « "\n";

}

};

int main()

{

Test <.float , int> test (1.23,123);

Test <int, char> test2 (l00,'W');

test1.show();

test2.show() ;

return 0;

};

The output will be:

1.23 and 123

100 and W

FUNCTION TEMPLATES WITH MULTIPLE PARAMETERS

Like template classes, we can use more than one generic data type in the template statement, using a

comma-separated list as shown below:

Page 272: C++ Book

template<class T1, class T2, ...>

return type functi onname (arguments of types T1, T2,…)

{

……………(Body of function)

…………….

……………

}

Program illustrates the concept of using two generic types in template functions.

#<include <iostream>

#<include <string>

using namespace std;

template<class T1, class T2>

void display(T1 x, T2 y)

{

cout « X « “ “ « y « “\n”;

}

int main()

{

display(1999, EBG);

display(12.34. 1234);

return 0;

}

The output of Program would be:

1999 EBG

12.34 1234

Page 273: C++ Book

C++ templates allow one to implement a generic Queue<T> template that has a type parameter T. T

can be replaced with actual types, for example, Queue<Customers>, and C++ will generate the class

Queue<Customers>. For example,

template <class T>

class Stack

{

} ;

Here T is a template parameter, also referred to as type-parameter.

1. C++ allows you to specify a default template parameter, so the definition could now look

like:

2. template <class T = float, int elements = 100> Stack { ....} ;

Then a declaration such as

Stack<> mostRecentSalesFigures ;

would instantiate (at compile time) a 100 element Stack template class named

mostRecentSalesFigures of float values; this template class would be of type Stack<float, 100>.

Note, C++ also allows non-type template parameters. In this case, template class Stack has an int as

a non-type parameter.

If you specify a default template parameter for any formal parameter, the rules are the same

as for functions and default parameters. Once a default parameter is declared all subsequent

parameters must have defaults.

Default arguments cannot be specified in a declaration or a definition of a specialization. For

example,

template <class T, int size>

class Stack

{

} ;

OVERLOADING OF TEMPLATE FUNCTIONS

Page 274: C++ Book

A template function may be overloaded either by template functions or ordinary function of its

name. In such cases, the overloading resolution is accomplished as follows:

1. Call an ordinary function that has an exact match.

2. Call a template function that could be created with an exact match.

3. Try normal overloading resolution to ordinary functions and call the one that ma'

An error is generated if no match is found. Note that no automatic conversions are applied to

arguments to the template functions.

Following Program shows how a template function overloaded with an explicit function.

#include<iostream>

#include<string>

using namespace std;

template < class T>

void display (T x)

{

cout <<”Template display :”<<x<<”\n”;

}

void display (int x) //overloads the generic display( )

{

cout <<”Explicit display : ”<<x<<”\n”;

}

int main( )

{

display(100);

display(12.34);

display(‘C’);

return 0;

}

The output will be

Explicit display : 100

Page 275: C++ Book

Template display :12.34

Template display:C

Remember: The call display (100) invokes the ordinary version of display() and not the template

version.

Summary

They are declared as a comma separated list within the template specification

Like template classes, we can use more than one generic data type in the template statement,

using a comma-separated list

C++ templates allow one to implement a generic Queue<T> template that has a type parameter T

T can be replaced with actual types, for example, Queue<Customers>

If you specify a default template parameter for any formal parameter, the rules are the same as

for functions and default parameters.

A template function may be overloaded either by template functions or ordinary function of its

name

Question

Explain class template & function template with multiple arguments?

Shows how a template function can be overloaded with an explicit function.

Page 276: C++ Book

UNIT I

LESSON 30

EXCEPTION HANDLING

Objective

What is exception handling? Exception Handling Mechanism. Throw Mechanism.

INTRODUCTION

We know that it is very rare that a program works correctly first time. It might have bu~, The two

most 'Common types of bugs are logic errors and syntactic errors. The logic error occur due to poor

understanding of the problem and solution procedure. The syntactic error arise due to poor

understanding of the language itself. We can detect these errors by using exhaustive, debugging and

testing procedures.

We often come across some peculiar problems other than logic or syntax errors. They are

Known as exceptions.. Exceptions are run time anomalies or unusual conditions that a program may

encounter while executing. Anomalies might include conditions such as division by zero,Access to

an array outside of its bounds, or running out of memory or disk space. When a Program encounter

an exceptional condition, it is important that it is identified and dealt effectively. ANSI C++ provides

built-in language features to detect and handle exceptions, which are basically run time errors.

Exception handling was not part of the original C++. It is a new feature added to ANSI C++

Today, almost all compilers support this feature. C++ exception handling provides a type-safe

Integrated approach, for coping with the unusual predictable problems that arise while executing

a program.

BASICS OF EXCEPTION HANDLING

Exceptions are of two kinds, namely, synchronous exceptions and asynchronous exceptions. I

such as "out-of-range index" and "over-flow" belong to the synchronous type exceptions.errors that

are caused by events beyond the control of the program (such as keyboard interrupts) are called

asynchronous exceptions. The proposed exception handling mechanism, in C++ is designed to

handle only synchronous exceptions.

Page 277: C++ Book

The purpose of the exception handling mechanism is to provide means to detect and report

“exceptional circumstance” so that appropriate action can be taken. The mechanism

Suggest a separate error handling code that performs the following tasks:

1. Find the problem (Hit the exception).

2. Inform that an error has occurred (Throw the exception).

3. Receive the error information (Catch the exception).

4. Take corrective actions (Handle the exception).

The error handling code basically consists of two segments, one to detect errors and to throw

exceptions, and the other to catch the exceptions and to take appropriate actions.

EXCEPTION HANDLING MECHANISM

In C there are several ways to have a program react to situations which break the normal

unhampered flow of the program:

The function may notice the abnormality and issue a message. This is probably the least

disastrous reaction a program may show.

The function in which the abnormality is observed may decide to stop its intended task,

returning an errorcode to its caller. This is a great example of postponing decisions: now the

calling function is faced with a problem. Of course the calling function may act similarly, by

passing the error-code up to its caller.

The function may decide that things are going out of hand, and may call exit() to terminate

the program completely. A tough way to handle a problem.

The function may use a combination of the functions setjmp() and longjmp()) to enforce non-

local exits. This mechanism implements a kind of goto jump, allowing the program to

proceed at an outer section, skipping the intermediate levels which would have to be visited

if a series of returns from nested functions would have been used.

In C++ all the above ways to handle flow-breaking situations are still available. However, the last

Page 278: C++ Book

way, using setjmp() and longjmp() isn't often seen in C++ (or even in C) programs, due to the fact

that the program flow is completely disrupted.

In C++ the alternative to using setjmp() and longjmp() are exceptions. Exceptions are a mechanism

by which a controlled non-local exit is realized within the context of a C++ program, without the

disadvantages of longjmp() and setjmp().

Exceptions are the proper way to bail out of a situation which cannot be handled easily by a function

itself, but which are not disastrous enough for the program to terminate completely. Also, exceptions

provide a flexible layer of flow control between the short-range return and the crude exit().

C++ exception handling mechanism is basically built upon three keywords, namely, try, throw, and

catch. The keyword try is used to preface a block of statements (surrounded by braces), which may

generate exceptions. This block of statements is known as try block. When an error is detected, it is

thrown using a throw statement in the try block. Throw followed by an expression of a certain type,

throws the expression value as an exception. The throw statement should be executed somewhere

within the try-block: either directly or from within a function called directly or indirectly from the

try-block. A catch block defined by the keyword catch 'catches' the exception 'thrown' by the throw

statement in the try block, and handles it appropriately. The relationship is shown in Fig.

Try block throwing Exception

The catch block that catches an exception must immediately follow the try block that throws the

exception. The general forms of these two blocks are as follows:

try block

Detects and throws an exception

catch block

Catches and handles the exception……………………try { ………..throw exception; / / Block of statements which

/ / detects and throws an exception

}catch (type arg) / / Catches exception{

/ / Block of statements that / / handles the exception

}………………

Page 279: C++ Book

When the try block throws an exception, the program control leaves the try block and enters the

catch statement of the catch block. Note that exceptions are objects used to transmit information

about a problem. If the type of object thrown matches the arg type the catch statement, then catch

block is executed for handling the exception. If they do not match, the program is aborted with the

help of the abort( )function which is invoked by default. When no exception is detected and thrown,

the control goes to the statement immediately after the catch block. That is, the catch block is

skipped. This simple try-catch mechanism is illustrated in Program.

Try Block Throwing An Exception.

#include <iostream.h>

using namespace std;

int main( )

{

int a,b;

cout<< “enter values of a and b \n”

cin>>a;

cin>>b;

int x = a – b;

try

Page 280: C++ Book

{

if(x ! = 0)

{

cout<< “ result (a/x) = “ << a/x << “\n”;

}

else //There is an Exception

{

throw(x); //Throws int object

}

}

catch (int i) //Catches the exception

{

cout<<”Exception caught : x = “ x << “\n”;

}

cout<< “END”;

return 0;

}

The output of Program

First Run

Enter Values of a and b

20 15

Result (a/x) = 4

END

Second Run

Enter Values of a and b

10 10

Except; on caught: x = 0

END

Page 281: C++ Book

Program detects and catches a division-by-zero problem. The output of first run shows a

successful execution. When no exception is thrown, the catch block is skipped and execution

resumes with the first line after the catch. In the second run, the denominator x becomes zero and

therefore a division-by-zero situation occurs: This exception is thrown using the object x. Since the

exception object is an int type, the catch statement containing int type argument catches the

exception and displays necessary message.

Most often, exceptions are thrown by functions that are invoked from within the try blocks.

The point at which the throw is executed is called the throw point. Once an exception is thrown to

the catch block, control cannot return to the throw point. This kind of relationship js shown in Fig.

Function invoked by try block throwing exception

The general format of code for this kind of relationship is shown below

Throw point

Function that causes an exception

try block

Invokes a function that contains an exception

catch block

Catches and handles the exception

Type function(arg list) // function with exceptin{

……….………throw(object); //throws object……….………

}

……….………

try{……….……… invoke function here……….………}

catch (type arg) //catches exception{……….……… handles exception here……….………} ………….

Page 282: C++ Book

Remember :

Try block is immediately followed by the catch block, irrespective of the location of the

throw point.

Program demonstrate how a try block invokes a function that generates an exception.

// Invoking function that generates exception.

#include <iostream>

using namespace std;

void divide(int x, int y , int z)

{

cout<< “\n we r inside the function \n”

if((x-y) != 0) // it is ok

{

int R = z / (x-y);

Page 283: C++ Book

cout<< “ Result = “ << R <<”\n”;

}

else //There is a problem

{

Throw(x-y) //throw point

}

}

int main( )

{

try

{

cout<< “ we r inside the Try block \n”;

divide(10,20,30); //invoke divide( )

divide(10,20,30); //invoke divide( )

}

catch(int i) //catches the exception

{

cout<< “ caught the exception \n”;

}

return 0;

}

Output

We r inside the try Block

We r inside the function

Result = -3

We r inside the function

Caught the exception

Page 284: C++ Book

THROWING MECHANISM

When an exception that is desired to be handled is detected, it is thrown using the throw statement in

one of the following forms:

throw(exception);

throw except ion;

throw; // used for rethrowing an exception

The operand object exception may be of any type, including constants. It is also possible to

Throw objects not intended for error handling.

When an exception is thrown, the catch statement associated with the try block will catch it. That is,

the control exits the current try block, and is transferred to the catch block after that try block.

Objects defined locally in functions are automatically destroyed once exceptions are thrown within

these functions. However, if the object itself is thrown, the exception catcher receives a copy of the

thrown object. This copy is constructed just before the local object is destroyed.

The next source illustrates this point. Within the function Object::fun() a local Object toThrow is

created, which is thereupon thrown as an exception. The exception is caught outside of Object::fun(),

in main(). At this point the thrown object doesn't actually exist anymore,

Let's first take a look at the sourcetext:

#include <iostream.h>

#include <string>

class Object

{

public:

Object(string name)

Page 285: C++ Book

name(name)

{

cout << "Object constructor of " << name << "\n";

}

Object(Object const &other)

name(other.name + " (copy)")

{

cout << "Copy constructor for " << name << "\n";

}

~Object()

{

cout << "Object destructor of " << name << "\n";

}

void fun()

{

Object

toThrow("'local object'");

cout << "Object fun() of " << name << "\n";

throw toThrow;

}

void hello()

{

cout << "Hello by " << name << "\n";

}

private:

string

name;

};

int main()

Page 286: C++ Book

{

Object

out("'main object'");

try

{

out.fun();

}

catch (Object o)

{

cout << "Caught exception\n";

o.hello();

}

}

The class Object defines some simple constructors and members. The copy constructor is special in

that it adds the text " (copy)" to the received name, to allow us to monitor the construction and

destruction of objects somewhat more closely. The member function fun() generates the exception,

and throws its locally defined object. Just before the exception the following output is generated by

the program:

Object constructor of 'main object'

Object constructor of 'local object'

Object fun() of 'main object'

Then the exception is generated, resulting in the next line of output:

Copy constructor for 'local object' (copy)

The throw clause receives the local object, and treats it as a value argument: it creates a copy of the

local object. Next, the exception is processed. The local object is destroyed, and the catcher catches

an Object, which again is a value parameter. Hence, another copy is created. We see the following

lines:

Page 287: C++ Book

Object destructor of 'local object'

Copy constructor for 'local object' (copy) (copy)

Now the message inside the catcher is displayed, and the hello member of the object received by the

catcher is called, showing us once again that we received a copy of the copy of the local object of the

fun() member function:

Caught exception

Hello by 'local object' (copy) (copy)

Now the program terminates, and the still living objects are destroyed in their reversed order of

creation:

Object destructor of 'local object' (copy) (copy)

Object destructor of 'local object' (copy)

Object destructor of 'main object'

If the catcher would have implemented so as to receive a reference to an object (catch (Object &o)),

the double copy would have been avoided. In that case the output of the program would have been:

Object constructor of 'main object'

Object constructor of 'local object'

Object fun() of 'main object'

Copy constructor for 'local object' (copy)

Object destructor of 'local object'

Caught exception

Hello by 'local object' (copy)

Object destructor of 'local object' (copy)

Object destructor of 'main object'

showing that only a single copy of the local object is used.

Page 288: C++ Book

Of course it's a bad idea to throw a pointer to a locally defined object: the pointer is thrown, but the

object to which the pointer refers dies once the exception is thrown, and the catcher receives a wild

pointer. Bad news.

Summarizing, local objects are thrown as copied objects, pointers to local objects should not be

thrown. However, it is possible to throw pointers or references to dynamically generated objects,

taking care that the generated object is properly deleted when the generated exception is caught.

Exceptions are thrown in situations where a function can't continue its normal task anymore,

although the program is still able to continue. Imagine a program which is an interactive calculator.

The program continuously requests expressions, which are then evaluated. In this case the parsing of

the expression may show syntax errors, and the evaluation of the expression may result in

expressions which can't be evaluated, e.g., because of the expression resulting in a division by zero.

A bit more sophistication would allow the use of variables, and non-existing variables may be

referred to.

Throw point can be in a deeply nested scope within a try block or in a deeply nested

function call. In. any case, control is transferred to the catch statement.

Page 289: C++ Book

Summary

Exceptions are peculiar problems that a program may encounter at run time.

Exceptions are of two types: synchronous and asynchronous. c++ provides mechanism

for handling synchronous exceptions.

An exception is typically caused by a faulty statement in a try block. The statement discovers

the error and throws it, which is caught by a catch statement.

The catch statement defines a block of statements to handle the exception appropriately.

When an exception is not caught, the program is aborted.

A try block may throw an exception directly or invoke a function that throws an exception.

Irrespective of location of the throw point, the catch block is placed immediately after the try

block.

Question

Explain basic concept on exception handling in c++ with suitable example?

What are the advantages of using exception-handling mechanism in a program?

What should be placed inside Try Block

Explain Throwing mechanism?

Page 290: C++ Book

UNIT I

LESSON 31

EXCEPTION HANDLING II

Objective

Catching Mechanism

CATCHING MECHANISM

As stated earlier, code for handling exceptions is included in catch blocks. A catch block looks like

a function definition and is of the form

catch(type arg)

{

// Statements for

// managing except ions

}

The type indicates the type of exception that catch block handles. The parameter arg is an optional

parameter name. Note that the exception-handling code is placed between two braces. The catch

statement catches an exception whose type matches with the type of catch argument. When it is

caught, the code in the catch block is executed.

If the parameter in the catch statement is named, then the parameter can be used in the exception-

handling code. After executing the handler, the control goes to the statement immediately

following the catch block.

Due to mismatch, if an exception is not caught, abnormal program termination will occur.

11isimportant to note that the catch block is simply skipped if the catch statement does not catch

an exception.

Page 291: C++ Book

Multiple Catch Statements

It is possible that a program segment has more than one condition to throw an exception. In such

cases, we can associate more than one catch statement with a try (much like the conditions in a

switch statement) as shown below:

Try

{

// try block

}

catch(typel arg)

{

// catch blockl

}

catch (type2 arg)

{

// catch b1ock2

}

…….

…….

catch(typeN arg)

{

// catch b1ockN

}

When an exception is thrown, the exception handlers are searched in order for an appropriate

match. The first handler that yields a match is executed. After executing the handler, the control

goes to the first statement after the last catch block for that try. (In other words, all other handlers

are bypassed). When no match is found, the program is terminated.

Page 292: C++ Book

It is possible that arguments of several catch statements match the type of an exception. In such

cases, the first handler that matches the exception type is executed.

Program shows a simple example where multiple catch statements are used to handle; various

types of exceptions.

Multiple catch statement Program

#include <iostream.h>

using namespace std;

void test(int x)

{

try

{

if(x = = 1) throw x; // int

else

if(x = = 0) throw ‘x’; // char

else

if(x = = -1) throw 1.0; // double

cout<< “end of try block \n”;

}

catch(char c) //catch 1

{

cout<< “Caught a character \n”

}

catch(int m) //catch 2

{

cout<< “Caught an integer \n”

}

Page 293: C++ Book

catch(double d) //catch 3

{

cout<< “Caught a double \n”

}

cout<< “End of try-catch system \n\n”;

}

}

int main( )

{

cout<< “Testing Multiple Catches”

cout<<” x= = 1 \n”;

test( 1 );

cout<<” x= = 0 \n”;

test( 0 );

cout<<” x= = -1 \n”;

test( -1 );

cout<<” x= = 2 \n”;

test( 2 );

return 0;

}

The output of the Program

Testing Multiple Catches

x = = 1

Caught an integer

End of try-catch system

Page 294: C++ Book

x = = 0

Caught a character

End of try-catch system

x = = -1

Caught a double

End of try-catch system0

x = = 2

End of try-block

End of try-catch system

The program when executed first, invokes the function test( ) with x = 1 and therefore throws x an

int exception. This matches the type of the parameter m in catch2 and therefore catch2 handler is

executed. Immediately after the execution, the function test( ) is again invoked with x = 0. This

time, the function throws 'x', a character type exception and therefore the first handler is executed.

Finally, the handler catch3 is executed when a double type exception is thrown. Note that every

time only the handler, which catches the exception, is executed and all other handlers are

bypassed.

When the try block does not throw any exceptions and it completes normal execution,

control passes to the first statement after the last catch handler associated with that try block.

Point :

Try block does not throw any exception, when the test( ) is invoked with x = 2.

The default catcher

In cases where different types of exceptions can be thrown, only a limited set of handlers may be

required at a certain level of the program. Exceptions whose types belong to that limited set are to

be processed, all other exceptions are treated differently, e.g., they are passed on to an outer level

of exception handling.

Page 295: C++ Book

Here is an example showing the use of a default exception handler:

try

{

// this code may throw

// different types of

// exceptions

}

catch (char *message)

{

// code to process

// char pointers

}

catch (int value)

{

// code to process

// ints

}

catch (...)

{

// code to process other exceptions,

// often passing the exception on

// to outer level exception handlers:

throw;

}

Page 296: C++ Book

The reason for passing unspecified exceptions on to outer level exception handlers is simply the

fact that they are unspecified: how would you process an exception if you don't know its type? In

these situations the outer level exception handlers should of course know what exceptions other

than char *s and ints to expect.

Catch All Exceptions

In some situations, we may not be able to anticipate all possible types of exceptions and

therefore may not be able to design independent catch handlers to catch them. In such

circumstances, we can force a catch statement to catch all exceptions instead of a certain type

alone. This could be achieved by defining the catch statement using ellipses as follows:

Program illustrates the functioning of catch (…)

include <iostream>

using namespace std;

void test(int x)

{

try

{

if(x = = 1) throw x; // int

if(x = = 0) throw ‘x’; // char

if(x = = -1) throw 1.0; // double

}

catch(...)

{ // catch all

catch(...) { // Statements for processing // all exceptions}

Page 297: C++ Book

cout << "Caught an exception \n";

}

}

int main( )

{

cout << Testing Generic Catch \n";

test(-1);

test(0);

test(1);

return 0;

}

The output of the Program

Testing Generic Catch

Caught an except ion

Caught an exception

Caught an except ion

Note that all the throws were caught by the catch(...) statement.

It may be a good idea to use the catch(...) as a default statement along with other catch

handler so that it can catch all those exceptions which are not handled explicitly.

Note

Remember, catch(...) should always be placed last in the list of handlers. Placing it before other

catch blocks would prevent those blocks from catching exceptions.

Summary

A catch block defined by the keyword catch 'catches' the exception 'thrown' by the throw

statement in the try block, and handles it appropriately

Page 298: C++ Book

An exception is typically caused by a faulty statement in a try block. The statement

discovers the error and throws it, which is caught by a catch statement.

The catch statement defines a block of statements to handle the exception appropriately.

When an exception is not caught, the program is aborted.

We can place two or more catch blocks together to catch and handle multiple types of

exceptions thrown by a try block.

It is also possible to make a catch statement to catch all types of exceptions using ellipses

as its argument.

It may be a good idea to use the catch(...) as a default statement along with other catch

handler so that it can catch all those exceptions which are not handled explicitly

Remember, catch(...) should always be placed last in the list of handlers

Question

Explain multiple catch statement?

When catch handler is used?

When do we use multiple catch statement?

Give a key advantage and key disadvantage of catch(….)

List the advantages of exception handling

Page 299: C++ Book

UNIT I

LESSON 32

Group discussion on topics covered

Like

Exceptional handling

Templates

Page 300: C++ Book

UNIT II

LESSON 33

CLASS IMPLEMENTATION

Objective

Implementation of classes

An object, such as a CD Player, a printer, a car, etc, is built from assembling various parts. In

the same way, C++ allows you to group various variables and create a new object called a

class.”

Imagine a company that manufactures shoeboxes hires you to write a program that would help

design and identify those shoeboxes. A shoebox is recognized for its dimensions (length, width,

height), color, and shoe size that a particular box can contain, etc. The variables that characterize

such an object are defined in the program below:

#include <iostream>

#include <iomanip>

#include <string>

using namespace std;

int main( )

{

// Define the characteristics of a shoe box

// The following characteristics are COMPLETELY random

double Length(12.55), Width(6.32), Height(8.74);

string Color("Yellow Stone");

float ShoeSize = 10.50;

// Display the characteristics of the shoe box

Page 301: C++ Book

cout << "Characteristics of this shoe box";

cout << setiosflags(ios::fixed) << setprecision(2);

cout << "\n\tLength = " << Length << "\n\tWidth = " << Width

cout << "\n\tHeight = " << Height << "\n\tVolume = " <<

Length * Width * Height

cout << "\n\tColor = " << Color << "\n\tSize = " << ShoeSize

<< "\n\n";

return 0;

}

The program would produce: 

Characteristics of this shoebox

Length = 12.55

Width = 6.32

Height = 8.74

Volume = 693.22

Color = Yellow Stone Size = 10.50 Press any key to continue...

Unless dealing with one shoebox, this program would be rudimentary to run for each object. The

solution is to create an object called box that groups everything that characterizes the object.

Now we will learn how to implement a class…. ”

To create a class, use the class keyword followed by a name for the object. Like any other declared

variable, the class declaration ends with a semi-colon. The name of a class follows the rules we

have applied so far for variable and function names. To declare a class called ShoeBox, you would type the following:

class ShoeBox;

Page 302: C++ Book

As a name that represents a group of items, a class has a body that would be used to define the

items that compose it. The body of a class starts with an opening curly bracket "{" and ends with a

closing one "}". Therefore, another way to create a class is:

class ClassName

{

};

This could also be created as:

Class ClassName

{

};

Either of these techniques produces the same effect.

Since a class is built from combining other identifiers, you will list each variable inside of the body

of the class. Each item that composes the class is represented as a complete variable declared with

a data type and a name. As a variable, each declaration must end with a semi-colon.

Continuing with our shoebox object, you could create it using the class as follows: 

class ShoeBox

{

double Length, Width, Height;

char Color[12];

float ShoeSize;

};

Page 303: C++ Book

The items that compose a class are called members of the class.

 

“Now that we have understood how to implement a ‘class’, we will now understand about

accessing the class and the components within it..”

Accessing a Class  

A common object in real life is visibly made of two categories of parts: those you can see or touch

and those you do not have access to. The parts you can see or touch are considered visible or

accessible. In C++, such parts are referred to as public. Those you cannot see or touch are

considered hidden. In C++, such parts are referred to as private. Like objects in real life, a class is

made of sections that the other functions or other objects cannot “see” and those the other objects

can access. The other objects of of the program are sometimes referred to as the clients of the

object. The parts the client of an object can touch in a class are considered public and the others

are private.

When creating a class, you will define which items are public and which ones are private. The

items that are public are created in a section that starts with the public keyword followed by a

semi-colon. The others are in the private section. If you do not specify these sections, all of the

members of a class are considered private. For example, all of the members of the previously

defined ShoeBox class are private.

Using the public and private sections, our shoebox object can be created as:

 

class ShoeBox

{

public:

double Length, Width, Height;

string Color;

private:

float ShoeSize;

Page 304: C++ Book

};

The public and private keywords are referenced by their access level because they control how

much access a variable allows. You can create as many public sections or as many private sections

as you want.

For example, the above class could be created as: 

class ShoeBox

{

public:

double Length, Width, Height;

public:

string Color;

double Volume;

private:

float ShoeSize;

private:

char Material;

string Color;

};

When creating a class with different public and private sections, all of the declared variables under

an access level keyword abide by the rules of that access level. The fact that you use different

public sections does not by any means warrant different public levels to the variables. A variable

declared as public in one public section has the same public level of access as any other variable

that is declared in another public section.

A variable that is declared in a class is called a member of the class. Once the class has been

defined, you can use it as an individual variable.

“ Now lets understand how ‘class members’ are declared..”

Page 305: C++ Book

After defining a class, you can declare it as a variable using the same syntax we have used for any

other variable. A class is declared using its name followed by a name for the defined variable and

ending with a semi-colon. For example, our ShoeBox class can be declared as follows:

ShoeBox Shake;

When an object has been declared, you can access any of its members using the member access

operator "." [Dot operator]. First, type the name of the object variable, followed by a period,

followed by the name of the member you want to access. For example, to access the member

Length of the above class, you would write:

Shake.Length;

Using this syntax, you can display the value of a class member:

cout << Shake.Length;

or you can request its value from the user, using the cin operator. Here is an example:

cin >> Shake.Lengh;

Using the cout extractor to display the values of the object members, our program could be as

follows:

 

#include <iostream>

#include <string>

using namespace std;

class ShoeBox

{

public:

double Length, Width, Height;

Page 306: C++ Book

string Color;

private:

float ShoeSize;

};

int main( )

{

ShoeBox Shake; // Display the characteristics of the shoe box

cout << "Characteristics of this shoe box";

cout << "\n\tLength = " << Shake.Length

<< "\n\tWidth = " << Shake.Width

<< "\n\tHeight = " << Shake.Height

<< "\n\tVolume = " << Shake.Length * Shake.Width *

Shake.Height

<< "\n\tColor = " << Shake.Color

<< "\n\tSize = " << Shake.ShoeSize

<< "\n\n";

return 0;

}

“At this time, if you observe very carefully there is a problem? The problem is because we are

trying to access a ‘private member’ of the ‘class’, and we know the restrictions of a ‘private

section’ of a class its obvious that the program would produce the following error.” 

[C++ Error] <filename.cpp>(30): E2247 'ShoeBox::TShoeSize' is not accessible

“Even if you change the ShoeSize member access from private to public, the program would

render unpredictable results because the members have not been given appropriate values.”

Page 307: C++ Book

Characteristics of this shoe box Length = 0 Width = 1.79571e-307 Height = 4.17266e-315 Volume

= 0 Color = Size = 3.58732e-43Press any key to continue...

 

Techniques of Initializing a Class

“Now that we have learnt how to declare a class and its members, we will now concentrate on

class initialization.”

There are various techniques used to initialize a class: initializing individual members or

initializing the class as a whole. To initialize a member of a class, access it and assign it an

appropriate value.

 

#include <iostream>

#include <string>

using namespace std;

class ShoeBox

{

public:

double Length, Width, Height;

string Color;

float ShoeSize;

private:

};

int main( )

{

ShoeBox Shake;

double Volume; // Initializing each member of the class

Page 308: C++ Book

Shake.Length = 12.55;

Shake.Width = 6.32;

Shake.Height = 8.74;

Shake.Color = "Yellow Stone";

Shake.ShoeSize = 10.50;

Volume = Shake.Length * Shake.Width * Shake.Height;

// Display the characteristics of the shoe box

cout << "Characteristics of this shoe box";

cout << "\n\tLength = " << Shake.Length

<< "\n\tWidth = " << Shake.Width

<< "\n\tHeight = " << Shake.Height

<< "\n\tVolume = " << Volume

<< "\n\tColor = " << Shake.Color

<< "\n\tSize = " << Shake.ShoeSize << "\n\n";

return 0;

}

This time, the program would render a reasonable result.

You can also initialize an object as a variable. This time, type the name of the variable followed by

the assignment operator, followed by the desired values of the variables listed between an opening

and a closing curly brackets; each value is separated with a comma. The first rule you must keep in

mind is that the list of variables must follow the order of the declared members of the class. The

second rule you must observe is that none of the members of the class must be another class. In the

following example, one of the members of the class is another class, namely a string. Because of

the way a variable of the class is declared, the program would not compile:

#include <iostream>

#include <string>

using namespace std;

Page 309: C++ Book

class ShoeBox

{

public:

double Length, Width, Height;

string Color;

float ShoeSize;

private:

};

int main( )

{

// Declaring and initializing the class as a variable

ShoeBox LadyShake = { 12.55, 6.32, 8.74, "Yellow Stone",

10.50 };

Double Volume = LadyShake.Length * LadyShake.Width *

LadyShake.Height;

// Display the characteristics of the shoe box

cout << "Characteristics of this shoe box";

cout << "\n\tLength = " << LadyShake.Length

<< "\n\tWidth = " << LadyShake.Width

<< "\n\tHeight = " << LadyShake.Height

<< "\n\tVolume = " << Volume

<< "\n\tColor = " << LadyShake.Color

<< "\n\tSize = " << LadyShake.ShoeSize << "\n\n";

return 0;

}

Page 310: C++ Book

Summary

To create a class, use the class keyword followed by a name for the object. Like any

other declared variable, the class declaration ends with a semi-colon.

Each item that composes the class is represented as a complete variable declared with a

data type and a name

Like objects in real life, a class is made of sections that the other functions or other

objects cannot "see" and those the other objects can access

The other objects of of the program are sometimes referred to as the clients of the

object. The parts the client of an object can touch in a class are considered public and

the others are private.

When creating a class, you will define which items are public and which ones are

private.

The public and private keywords are referenced by their access level because they

control how much access a variable allows.

A variable that is declared in a class is called a member of the class

When an object has been declared, you can access any of its members using the

member access operator "." [Dot operator].

You can also initialize an object as a variable.

Question

Define class? Explain implementation of class with suitable example?

Explain the access modifier in class & explain how they differ from each other?

Page 311: C++ Book

UNIT II

LESSON 34

IMPLEMENTATION II

Objective

Object concepts

Making instance of object:

#include <iostream>

#include <string>

class ShoeBox

{

private:

double Length, Width, Height;

public:

ShoeBox()

{

}

ShoeBox(double L1, double W1, double H1)

{

Length=L1;

Width= W1;

Height=H1;

}

void display()

{

cout<<endl<<Length<<Width<<Height;

}

};

Page 312: C++ Book

void main( )

{

ShoeBox s1(10,20.66,15);

ShoeBox s1(5,3.89,9);

Cout<<endl<<sizeof(s1);

Cout<<endl<<sizeof(s2);

}

In our program there are Two objects of the type ShoeBox, so there are two instance of Length,

Width, Height in memory. So Length, Width & Height are instance of object. However there is

only one instance of two constructor functions and the display() function. All the objects of class

share these functions.

Tuning Objects 

“Similar to tuning a radio set in order to get clear and error free reception, we can tune objects

of a class by specifying applying certain techniques and implementing certain tools which make

object programming all the more powerful.”

There are other features you can apply to make your objects more professional and less prone to

errors. These include constant arguments, constant, private, and inline methods, etc.

Constant Arguments

When studying functions, we learned that when a function receives an argument that it does not

modify, the argument should be declared as constant. This allows the compiler to make sure the

argument would not be modified. The same technique applies to an argument used by a method of

an object.

To declare an argument of an object’s method as constant, type the const keyword on the left of the

argument’s data type. To improve our ShoeBox object, we would like to know the area of each

Page 313: C++ Book

side because different things will be displayed on each side and we need to know how much space

is available. If we were dealing with a rectangle, we would just declare an Area( ) method as

follows:

Double Area( );

On a box (rectangular parallelepiped), we have three rectangles types that represent the six faces.

We can declare one method that takes any two sides and calculates their area. Such a method

would be declared as follows:

 

double Area(Double Side1, Double Side2);

After declaring it in the public section, we would define it as follows:

double ShoeBox::Area(Double Side1, Double Side2)

{

return Side1 * Side2;

}

In the Display( ) method, we could display the area of the length by the height using:

cout << “\n\tArea = “ << Area(Length, Height);

As you can see, the Side1 and Side2 arguments are not modified; therefore, they should be

declared as constants. To declare each as constant, we would change the declaration of the method

as follows:

Double Area(const Double Side1, const Double Side2);

And we would define it as follows:

double ShoeBox::Area(const Double Side1, const Double Side2)

Page 314: C++ Book

{

return Side1 * Side2;

}

For an example such as this one, the const keyword can be typed before or after the data type, the

result would be the same. If a method is receiving more than one argument, their constancy is

independent: the fact that one of them needs to be constant does not imply anything about the

other(s).

To help the method specify what side it is calculating the area, we could provide a string that

names the side. We could declare the method as follows:

void Area(const Double Side1, const Double Side2, PChar SideName);

We would then define the new method as follows:

void ShoeBox::Area(const Double S1, const Double S2, PChar n)

{

cout << "\nThe area of the " << n << " side is: " << S1 * S2;

}

In the Display( ) method, we could specify the name of the side and provide the corresponding

measures as follows:

Area(Length, Height, "front");Area(Length, Width, "top");Area(Width, Height, "left");

Here is the complete implementation: 

#include <iostream>

#include <string>

using namespace std;

class ShoeBox

Page 315: C++ Book

{public:

double CalcVolume( )

{

return Length * Width * Height;

}

void Area(const double Side1, const double Side2, char SideName[]);

float CalcShoeSize( )

{

return Length - 0.35;

}

void Display( );

private:

double Length;

double Width;

double Height;

char Color[32];

};

void ShoeBox::Area(const double S1, const double S2, char N[])

{

cout << "\nThe area of the " << N << " side is: " << S1 * S2;

}

void ShoeBox::Display( )

{

// Initializing the dimensions

Page 316: C++ Book

Length = 10.42;

Width = 5.28;

Height = 5.88;

Color = "Yellow Stone";

// Display the characteristics of the shoe box

cout << "Characteristics of this shoe box";

cout << "\nDimensions(L*H*W) = "

<< Length << " * " << Height << " * " << Width;

Area(Length, Height, "front");

Area(Length, Width, "top");

Area(Height, Width, "left");

cout << "\n\tVolume = " << CalcVolume( )

<< "\n\tColor = " << Color

<< "\n\tSize = " << CalcShoeSize( );

}

int main( )

{

ShoeBox Bambou;

Bambou.Display( );

return 0;

}

Constant Methods

Some of the method members of an object, though using member variables of the same object, do

not modify them. To make sure that such a method does not alter the value of a member variable,

the method should be declared and implemented as constant.

Page 317: C++ Book

To declare a method as a constant, add the const keyword to the right side of the method when

declaring it. Here is an example:

string SpecFullName( ) const;

The CalcVolume( ) and the CalcShoeSize( ) methods do not modify the member variables they

receive. You can reinforce this by declaring them as const:

double CalcVolume( ) const;float CalcShoeSize( ) const;

When implementing the method, type the const keyword on the right side of the method’s closing

parenthesis:

double ShoeBox::CalcVolume( ) const

{

return Length * Width * Height;

}

float ShoeBox::CalcShoeSize( ) const

{

return Length - 0.35;

}

If you decide to define constant methods locally (inline), the only difference is to remove the semi-

colon of the end of the declaration and define the method normally.

Notice that the Display( ) method assigns values to the member variables, which means it alters

their values. Therefore, it cannot be declared or defined as constant. Here is the new version of our

ShoeBox object:

class ShoeBox

Page 318: C++ Book

{

public:

double CalcVolume( ) const

{

return Length * Width * Height;

}

void Area(const double Side1, const double Side2, char SideName[]);

float CalcShoeSize( ) const

{

return Length - 0.35;

}

void Display( );

private:

double Length;

double Width;

double Height;

string Color;

};

The program would still produce the same result.

Private Methods

At this time, we know that one of the responsibilities of a member method of an object is to carry

assignments. Another job performed by methods is to communicate with the clients of an object.

As you might have found out, some of the methods of an object are exclusively used to carry

assignments. The external functions or other objects do not call such methods and do not

communicate with them. If you create a class and know that a particular member method is not

Page 319: C++ Book

used to transfer data to the client methods, you can declare such a method as private, just like you

would do with a member variable.

To declare a method as private, include it in the private section of the object. To implement it,

follow the same rules we have learned about implementing the methods of an object. The biggest

difference you must keep in mind (which will also be very important when we learn about

inheritance) is that this function method is not available to the outside world. Here is an example:

 

class Employee

{

public:

void IdentifyEmployee( );

string FullName( ) const { return FirstName + " " + LastName; }

void GetHourlySalary( );

void CalcTotalHours( );

void Display( );

void CalcNetPay( )

{

if( IsMarried( ) == false )

NetPay = GrossPay - (GrossPay * 30 / 100);

else

NetPay = GrossPay;

}

private:

void CalcGrossPay( );

bool inline IsMarried( ) const;

string FirstName;

string LastName;

double TotalHours;

double HourlySalary;

double WeeklySalary;

Page 320: C++ Book

double GrossPay;

double NetPay;

};

 

Objects and Their Implementations  

An object is made of the material that compose it and the actual structure of the object, which

defines how the object is built and used. This means, a class is be made of two parts: its building

block and its definition. These two parts of a class can be kept in different files that have access to

each other. 

Class' Header File

The building block or foundation of an class is made of the class' creation, listing all of its

members. This foundation is created in a file called a header file, similar to the one we learned

when studying functions. The name of the file follows the naming rules we have applied so far.

The header file has an extension of .h.

You create an object’s header file the same we did when studying functions. To create the header

file, you can just define the class as an object. If some of the members are defined in files outsde of

the object, include their header file(s).

Here is what our ShoeBox header file would look like:

#include <iostream>

#include <string>

using namespace std;

class ShoeBox

{

public:

double CalcVolume( ) const

{

Page 321: C++ Book

return Length * Width * Height;

}

void Area(const double Side1, const double Side2, char SideName[32]);

float CalcShoeSize( ) const

{

return Length - 0.35;

}

void Display( );

private:

double Length;

double Width;

double Height;

string Color;

};

Class Source Code

This file used to implement the object is called a source file. It is used to define what the object is

supposed to do. It contains all or some of the methods and their implementations.

To create the source file, from the New property page of the New Items dialog box, click the Cpp

File icon and click OK. By default, the (first) file is called File1.cpp. To change that name, you

must save the project and replace the name of the file with the desired name.

A source file should at least start with a line that specifies the name of the header file that it is

implementing. Since this file is usually created in the same project, it is specified with an include

line that is encloses the file name with double-quotes. An example would be:

#include "Book.h"

Page 322: C++ Book

The main area of the file is made of the class' implementation. Here is what the source file of our

ShoeBox would look like:

#include "File1.h"

void ShoeBox::Area(const Double S1, const Double S2, PChar N)

{

cout << "\nThe area of the " << N << " side is = " << S1 * S2;

}

void ShoeBox::Display( )

{ // Initializing the dimensions

Length = 14.32;

Width = 8.36;

Height = 6.54;

Color = "Brown Carpet";

// Display the characteristics of the shoe box

cout << "Characteristics of this shoe box";

cout << "\nDimensions(L*H*W) = "

<< Length << " * " << Height << " * "

<< Width; Area(Length, Height, "front");

Area(Length, Width, "top");

Area(Height, Width, "left");

cout << "\n\tVolume = " << CalcVolume( )

<< "\n\tColor = " << Color

<< "\n\tSize = " << CalcShoeSize( );

}

The main( ) function of our shoe box project is reduced to simply calling the appropriate ShoeBox

method member:

#include <iostream.h>

#include "ShoeBox.h"

int main( )

{

Page 323: C++ Book

ShoeBox Sala;

Sala.Display( );

return 0;

}

Summary

To declare an argument of an object's method as constant, type the const keyword on

the left of the argument's data type.

some of the methods of an object are exclusively used to carry assignments. The

external functions or other objects do not call such methods and do not communicate

with them.

To declare a method as private, include it in the private section of the object.

An object is made of the material that compose it and the actual structure of the object,

which defines how the object is built and used

a class is be made of two parts: its building block and its definition. These two parts of

a class can be kept in different files that have access to each other.

Question what is an object? Explain implementation of objects & instance of object?

What do u understand instance of objects?

Page 324: C++ Book

UNIT II LESSON 35

DATA DRIVEN

Objective Data driven concept

Introduction

A Dynamic Data Driven Application System (DDDAS) is an application software system capable

of accepting and effectively utilizing remote data in real time (i.e., during the execution of the

application software). Many software systems currently utilize static input data, i.e., input data

which is specified a priority. The key concept of DDDAS is the generalization of application

software systems to dynamically utilize real-time data arising from remote experiment and

simulation, and to control such remote experiment and simulation to improve the performance of

the application software system. The concept is illustrated

schematically in Fig. 1.

Dynamic Data Driven Application Systems have become a major subject of research interest due

to the continuing rapid advances in technology. These include, for example, improvements in

computer processor performance (i.e. doubling every 18 to 24 months (Berkowitz 1996)), network

bandwidth, Rapid Prototyping (RP) and real-time data acquisition and control (e.g., using Micro-

Electro Mechanical Systems (MEMS)). These rapid technological advances provide the means to

revolutionize the use of existing and future application software systems. For example, the NSF

TeraGrid1 is a multi-year e_ort to deploy20 TFlops of computing capacity at five sites connected

through a 40 Gbps network.

The Tera Grid will o_er unprecedented remote computing capability which can be utilized in real-

time by application software systems executing at users’

sites. The incorporation of the NSF Tera grid into an application software system

is therefore an example of a Dynamic Data Driven Application System.

1 http://www.ncsa.uiuc.edu/About/TeraGrid/

Page 325: C++ Book

Conventional Engineering Design Optimization Engineering design is a potential Dynamic Data

Driven Application System Where in remote real-time input from high performance computing

resources

(e.g., NSF Tera grid) and experiment (e.g., using capability for rapid fabrication of new

experimental configurations) can produce a better design in shorter time with lower cost than the

conventional approach. Fig. 2 illustrates the conventional approach to engineering design. An

initial design is typically evaluated using simulation software executing on local computer

resources. An example is Computational Fluid Dynamics (CFD) simulation using one of the

several available commercial CFD software packages (e.g., fluent, gasp, star-cd). The results of the

simulation are reviewed by the designer and additional simulations performed as needed. An

experiment is then planned and executed, and the results compared with the simulation. The

process is iterated until a satisfactory design has been achieved. A major limitation of the

conventional approach is the absence of synergistic real-time use of remote experimental data and

high performance computer resources (e.g., the NSF Tera Grid).

Page 326: C++ Book

4 Data Driven Design Optimization Methodology

We are developing an integrated software system, denoted Data Driven DesignOptimization

Methodology (DDDOM), to synergistically incorporate remote experiment and simulation into an

automated design optimization methodology. The DDDOM is comprised of six elements as

illustrated in Fig. 3 and are summarized below. Controller The DDDOM Controller provides

direction and control of the design optimization process. It is written in Perl (Wall et al 2000), a

powerful systems programming language which enables robust program control on local and

remote systems. The Controller utilizes the Globus software system (Foster and Kesselman 1997)

to link to the NSF Tera Grid. User Interface The User Interface provides for the initiation and

monitoring of the design optimization. It also provides visualization of the intermediate results of

the design optimization process. The interface is written in Perl/Tk (Lidie and Walsh 2002). Both

Perl and Perl/Tk operate on virtually every platform and operating system.

Page 327: C++ Book

Optimizer A Multi-Criteria Design Optimization (MDO) algorithm is used to search the design

space to define the Pareto Set. Both local (i.e., gradient-based) and global (i.e., stochastic-based)

algorithms are used. Examples are CFSQP(Lawrence et al 1994) and GADO (Rasheed and

Hirsh 1999), respectively.Surrogate Model Surrogate Models of the objective functions f are

developedduring the design optimization using experiment and simulation. Thesemodels are

utilized by the optimizer to search the design space for the ParetoSet. We utilize Response

Surfaces (Myers and Montgomery 1995) and Radial

Basis Function Artificial Neural Networks (Hertz et al 1991). The SurrogateModel incorporates

the measure of uncertainty _ in the results generated by theexperiment and simulation.

Experiment : Experiments are performed in real-time with the conditions of the experiment

defined by the Controller. The interface with experiments is typically National Instruments Lab

View (Travis 2002). Rapid Prototyping is used to build new models as needed with minimal

delay (e.g., one day).

Page 328: C++ Book

Simulation : Simulations can be performed locally (i.e., at the same site as the DDDOM is

operated) or remotely (e.g., on the NSF Tera Grid). The simulations are performed in real-time

with the conditions of the simulation defined by the Controller.

5 Example

A five minute demonstration has been developed to illustrate the principle of operation of the

DDDOM. The limited duration of the demonstration precludes the actual use of RP which

typically requires several hours for fabrication of the prototype for experiment. Therefore, we have

selected a single experimental con-

figuration. Nonetheless, the experiment provides data to the DDDOM Controller in real time, and

the Controller directs the experiment, thereby illustrating the DDDOM concept.

The specific problem is defined as follows. Consider the flow of air in a converging-diverging

nozzle attached to a stagnation chamber as illustrated in Fig.The nozzle is designed to achieve

Mach 2 at the exit assuming isentropic expansion throughout the nozzle. Depending upon the ratio

of stagnation pressure pt1 to ambient pressure pa, the flow in the diverging section of the nozzle

can be 1) subsonic everywhere, 2) supersonic and subsonic with a normal shock at some location

in the diverging section, and 3) supersonic everywhere (Anderson 2003). In the latter case, the

theoretical exit Mach number is two. A one-dimensional simulation based upon inviscid gas

dynamics (Liepmann and Roshko 1957) indicates that the exit pressure ratio pe vs stagnation

pressure pt1 behaves as shown by the curve denoted Simulation in Fig. 5. This behavior

is idealized, however, due to the neglect of the viscous boundary layer on the nozzle walls and the

e_ect of the interaction of the normal shock wave (if it exists) with the boundary layers.

Consequently, the actual exit pressure pe vs stagnation pressure pt1

curve di_ers substantially from the idealized shape.

Page 329: C++ Book

Data Driven Design Optimization Methodology

A Dynamic Data Driven Application System

1 Introduction

A Dynamic Data Driven Application System (DDDAS) is an application softwaresystem capable

of accepting and effectively utilizing remote data in realtime (i.e., during the execution of the

application software). Many software systemscurrently utilize static input data, i.e., input data

which is specified apriori. The key concept of DDDAS is the generalization of application

softwaresystems to dynamically utilize real-time data arising from remote experiment

andsimulation , and to control such remote experiment and simulation to improvethe

performance of the application software system. The concept is illustratedschematically in Fig.

1.

Dynamic Data Driven Application Systems have become a major subject of research interest due

to the continuing rapid advances in technology. These include, for example, improvements in

computer processor performance (i.e., doubling every 18 to 24 months (Berkowitz 1996)), network

bandwidth, Rapid Prototyping (RP) and real-time data acquisition and control (e.g., using Micro-

Electro Mechanical Systems (MEMS)). These rapid technological advances provide the means to

revolutionize the use of existing and future application software systems. For example, the NSF

Page 330: C++ Book

TeraGrid1 is a multi-year e_ort to deploy 20 TFlops of computing capacity at five sites connected

through a 40 Gbps network. The TeraGrid will o_er unprecedented remot computing capability

which can be utilized in real-time by application software systems executing at users’ sites. The

incorporation of the NSF Teragrid into an application software system is therefore an example of a

Dynamic Data Driven Application System.

Group discussion session on the article Function Decomposition and the differences

between two

Summary

6 Conclusions

Engineering design is an example of a Dynamic Data Driven Application System Where in real-

time data from experiment and simulation can be effectively utilized to yield better designs in

shorter time. A Data Driven Design Optimization Methodology (DDDOM) is being developed

which incorporates experiment and simulation in a real-time, synergistic manner. The theory and

organization of DDDOM is described. An example demonstration is described.

Page 331: C++ Book

UNIT II

LESSON 36

ANALYSIS AND DESIGN METHODS

Formal(OMT) object based design methods

Objective

Purpose of method

S/W life cycle

What is the Purpose of a Method?

A method defines a reproducible path for obtaining reliable results. All knowledge-based

activities use methods that vary in sophistication and formality. Cooks talk about recipes, pilots go

through checklists before taking off, architects use blueprints, and musicians follow rules of

composition.

Similarly, a software development method describes how to model and build software

systems in a reliable and reproducible way.

In general, methods allow the building of models from model elements that constitute the

fundamental concepts for representing systems or phenomena.. The object-oriented approach to

software development proposes the equivalent of notes – objects – to describe software.

Methods also define a representation – often graphical – that allows both the easy manipulation of

models, and the communication and exchange of information between the various parties involved.

A good representation seeks a balance between information density and readability.

Over and above the model elements and their graphical representations, a method defines the rules

that describe the resolution of different points of view, the ordering of tasks and the allocation of

responsibilities. These rules define a process that ensures harmony within a group of cooperating

elements, and explains how the method should be used.

As time goes by, the users of a method develop a certain 'know-how' as to the way it should be used.

This know-how, also called experience, is not always clearly formulated, and is not always easy to

pass on.

From Functional to Object-Oriented Methods

Page 332: C++ Book

Although object-oriented methods have roots that are strongly anchored back in the 60s, structured

and functional methods were the first to be used. This is not very surprising, since functional

methods are inspired directly by computer architecture (a proven domain well known to computer

scientists). The separation of data and code, just as exists physically in the hardware, was translated

into the methods; this is how computer scientists got into the habit of thinking in terms of system

functions.

This approach is natural when looked at in its historical context, but today, because of its lack of

abstraction, it has become almost completely anachronistic. There is no reason to impose the

underlying hardware on a software solution. Hardware should act as the servant of the software that

is executed on it, rather than imposing architectural constraints.

More recently, towards the beginning of the 80s, object-oriented methods started re-emerging.

History – with a big H – is said to repeat itself. The lesser history of methods repeats itself as well:

the paths followed by functional methods and object-oriented methods are similar. To begin with,

there was programming, with subprograms and objects as alternatives for the basic elements of

structure. A few years later, software scientists pushed the idea of structure towards design as well,

and invented structured

design in one instance, and object-oriented design in the other. Later again, progress was

made in the area of analysis, always using the same paradigm, either functional or object-

oriented. Both approaches are therefore able to provide a complete path across the whole

software lifecycle.

The evolution of methods, whether object-oriented or not, always progresses from programming

towards analysis.

In practice, the situation is a bit more complex – methods often do not cover the full lifecycle. This

results in methods being mixed and matched: method A is used for analysis followed by method B,

which is used for the design. As long as it uses a single paradigm – the functional approach or the

object-oriented approach – this compartmentalization remains reasonable. Although it may remain

understandable, the mixture of paradigms is clearly less reasonable.

Page 333: C++ Book

Towards the mid-80s, the benefits of object-oriented programming began to gain recognition, and

object design seemed like a sensible approach for people who wanted to use an object-oriented

programming language such as Smalltalk. However, from the analysis standpoint, the concept of

object-orientation was still only vapor and supposition. At that time, corporations had developed a

strong knowledge of functional analysis and semantic data modeling methods. Computer scientists

were inclined to follow a functional analysis phase with an object-oriented design phase.

This approach has serious drawbacks attached to the paradigm shift. Moving from a functional

approach to an object-oriented one requires a translation of the functional model elements into object

model elements, which is far from being straightforward or natural. Indeed, there is no direct

relationship between the two sets, and it is therefore necessary to break the model elements from one

approach in order to create model element fragments that can be used by the other. This paradigm

shift, right in the middle of the development effort, can greatly hinder the navigation from the

statements of requirements obtained early in the analysis phase, to the satisfaction of those

Requirements in the design phase. Moreover, an object-oriented design obtained after translation

very often lacks abstraction, and is limited to the encapsulation of low-level objects available in the

implementation and execution environments. All this implies a great deal of effort in order to obtain

results that are not very satisfactory.

The combination of a functional approach for analysis and an object-oriented approach for design

and implementation does not need to exist today, as modern object-oriented methods cover the full

software lifecycle

Page 334: C++ Book

During the past decade, object-oriented applications – going from requirements analysis to

implementation – have been developed in all sectors of programming. The experience acquired on

these projects has helped the understanding of how to join together the various activities required to

support a fully object-oriented approach. To date, the evolution of these practices is not complete,

and there are still a few advocates of the mixed approach, prisoners beneath the weight of their

habits. Corporations that are on the brink of the transition to object-orientation should not reproduce

this flaw. It is far easier to deploy an approach that is completely object-oriented. In addition,

software developed using this approach is simpler, more reliable and more easily adapted to the

expectations of its users.

The Proliferation of Object-Oriented Methods

The first few years of the 90s saw the blossoming of around fifty different object-oriented methods.

This proliferation is a sign of the great vitality of object-oriented technology, but it is also the fruit of

a multitude of interpretations of exactly what an object is. The drawback of this abundance of

methodologies is that it encourages confusion, leading users to adopt a 'wait and see' attitude that

limits the progress made by the methods. The best way of testing something is still to deploy it;

methods are not cast in stone – they evolve in response to comments from their users.

Fortunately, a close look at the dominant methods allows the extraction of a consensus around

common ideas. The main characteristics of objects, shared by numerous methods, are articulated

around the concepts of class, association (described by James Rumbaugh), partition into subsystems

(Grady Booch), and around the expression of requirements based on studying the interaction

between users and systems (Ivar Jacobson's use cases).

Finally, well-deployed methods, such as Booch and OMT (Object Modeling Technique), were

reinforced by experience, and adopted the methodology elements that were most appreciated by the

users.

Booch and OMT Getting Closer

The second generations of the Booch and OMT methods, called Booch'93 and OMT-

2, were far more similar to one another than their predecessors had been. The remaining differences

were minor, and pertained primarily to terminology and notation. Booch'93 was influenced by OMT

Page 335: C++ Book

and adopted associations, Harel diagrams and event traces. In turn, OMT-2 was influenced by Booch

and introduced message flows, hierarchical models and subsystems, and model components. More

importantly, it removed data flow diagrams from the functional model. These were inherited

functional baggage and were not well integrated with the overall OMT approach.

By this stage, both methods offered complete lifecycle coverage, but with a notable distinction in

focus. Booch'93 focused on implementation, while OMT-2 concentrated on analysis and abstraction.

Nonetheless, there were no serious incompatibilities between the two methods.

Object-oriented concepts have a history that is often complex and intricate. The elements presented

in the table below emerged from the experience of deploying the various

methods, and have influenced the effort to unify the Booch and OMT methods

Origin Element

Booch Categories and subsystems

Embley Singleton classes and composite objects

Fusion Operation descriptions, message numbering

Gamma et al Frameworks, patterns and notes

Harel Statecharts

Jacobson Use cases

Meyer Pre- and post-conditions

Odell Dynamic classification, emphasis on events

OMT Associations

Shlaer-Mellor Objects lifecycles

Wirfs-Brock Responsibilities and collaborations

Summary

Page 336: C++ Book

Methods also define a representation – often graphical – that allows both the easy

manipulation of models, and the communication and exchange of information between the

various parties involved.

The evolution of methods, whether object-oriented or not, always progresses from

programming towards analysis.

The second generations of the Booch and OMT methods, called Booch'93 and OMT-2, were

far more similar to one another than their predecessors had been.

OMT-2 was influenced by Booch and introduced message flows, hierarchical models and

subsystems, and model components. More importantly, it removed data flow diagrams from

the functional model.

Questions

1. discuss S/W life cycle

2. Give the details of OMT design method

Page 337: C++ Book

UNIT IILESSON 37

ANALYSIS AND DESIGN METHODS

CRC Methods

Objective :

Conceptual Overview of CRC cards

Design and analysis method

Conceptual Overview

A CRC cards is an index card that is use to represent the responsibilities of classes and the

interaction between the classes. CRC cards are an informal approach to object oriented modeling.

The cards are created through scenarios, based on the system requirements, that model the behavior

of the system. The name CRC comes from Class, Responsibilities, and Collaborators which the

creators found to be the essential dimensions of object oriented modeling.

CRC cards where introduced by Kent Beck and Ward Cunningham in there paper "A Laboratory for

Teaching Object-Oriented Thinking" released in OOPLSA '89. There original purpose was to teach

programmers the object-oriented paradigm. When Kent Beck wrote the draft version of their paper

he change Collaborators to helpers. Ward Cunningham changed it back to Collaborators when he

reviewed the paper. The initials of Cunningham's son are CRC.

Why uses CRC cards?

They are portable... No computers are required so they can be used anywhere. Even away from the

office.

They allow the participants to experience first hand how the system will work. No computer tool can

replace the interaction that happens by physically picking up the cards and playing the roll of that

object...

They are a useful too for teaching people the object-oriented paradigm.

Page 338: C++ Book

They can be used as a methodology them selves or as a front end to a more formal methodology

such as Booch, Wirfs-Brock, Jacobson, etc.

Although CRC cards where created for teaching, they have proven useful for much more. They

become an accepted method for analysis and design. The biggest contributing factor to their success

is the fact that they provide an informal and non threatening environment that is productive to

working and learning.

1. The CRC card session.

The Group

The ideal group size for a CRC card session is five or six people. This size generally allows

everyone to productively participate. In groups of large size the productive is cut by more

disagreements and the amount of participation by everyone is lower. If there are more than six

people, one solution is to have the extra people be present strictly as observers.

The group five or six people in the core group should be composed of developers, domain experts,

and an object-oriented technology facilitator. In the initial Analysis phase there should be two or

three domain experts, one object-oriented technology facilitator, and the rest of the group made up of

people how are responsible for delivering the system. As the project moves more in to the design

phase, some of the domain experts can be replaced with developers. There should always be at least

one domain expert in the group to clarify an question that arise about the behavior of the system.

The Cards

The cards should look something like this:

Page 339: C++ Book

The exact format of the card can be customized to the preferences of the group, but the minimal

required information is the name of the class, it's responsibilities and the collaborators. The back of

the card can be used for a description of the class. During the design phase attributes of the class can

be recorded on the back as well. One way to think of the card is the front as the public information,

and the back as the encapsulated, implementation details.

The Session

Before starting a session there needs to be some kinds of requirements for the systems. Weather they

are implicitly or explicitly define the people participating in the group need to be familiar with them.

A session also needs to focus on one part of the problem at a time. So a subset of the problem needs

to be chosen to explored during the CRC card session.

Creating class

The first step in modeling an system in the object-oriented paradigm is to identify the class in the

problem domain. So this is the first step in a CRC card session. Using the problem statement or

requirements document, identify the classes that are obvious in the subset of the problem that is

going to explored in this session. One useful tool is to find all of the nouns and verbs in the problem

statement. The nouns are a good key to what class are in the system, and the verbs show what there

responsibilities are going to be. Use this information for the basis of a brainstorming session and

identify all the class that you see. Remember in a brainstorming session there should be no or little

Page 340: C++ Book

discussion of the ideas. Record them and filter the results after the brainstorming. After the classes

have been chosen pass out cards and assign the class to the member of the group. Each person

should be responsible for at least on class. They are the owner of that class for the session. Each

person records the name of their class on a card. One class per card.

Responsibilities

Once a reasonable set of classes have be assigned to the group, responsibilities can be added. Add

responsibilities that are obvious from the requirements or the name of the class. You don't need to

find them all or any. The scenarios will make them more obvious. The advantage of finding some in

the beginning is that it help provide a starting place.

Super classes and Subclasses

Super classes and subclasses can be defined at any time they become obvious. The scenarios will

illuminate these as well. It is up to the group to decided if they want to define any hierarchical

relationships now or wait till the scenarios to do this.

Attributes

Attributes of class don't really need to be defined any time soon. They are an implementation detail.

The responsibilities of the class will help make these clear. Attributes are general not defined at all

till the design phase, but they can be defined at anytime the group thinks it is appropriate. Remember

these are implementation details and should go on the back of the card.

Scenario execution

These are the heart of the CRC card session. Scenarios are walk-throughs of the functions of the

system in detail. Take required functionality from the requirements document and use this as a

scenarios. Start with scenarios that are part of the systems normal operation first, and then

exceptional scenarios, like error recover, later.

First decide which class is responsible for this function. The owner of the class then picks up his

card. When a card is in the air it is an object and can do things. The own announces that he needs to

fulfill his responsibility. The responsibility is refined in to smaller tasks if possible. These smaller

tasks can be fulfilled be the object is appropriate or they can be fulfilled be interacting with other

objects. If no other appropriate class exist, maybe you need to make one. This is the fundamental

procedure of the scenario execution.

Lets move on the Analysis and try out first CRC card session.

2. CRC cards for analysis.

Page 341: C++ Book

Analysis is the process of modeling what a system does, not how it does it. Lets start by modeling a

sample system using CRC cards.

Activity 1.

Problem statement.

This application will support the operations of a technical library for an R&D organization. This

includes the searching for and lending of technical library materials, including books, videos, and

technical journals. Users will enter their company ids in order to use the system; and they will enter

material ID numbers when checking out and returning items.

Each borrower can be lent up to five items. Each type of library item can be lent for a different

period of time (books 4 weeks, journals 2 weeks, videos 1 week). If returned after their due date, the

library user's organization will be charged a fine, based on the type of item( books $1/day, journals

$3/day, videos $5/day).

Materials will be lent to employees with no overdue lendables, fewer than five articles out, and total

fines less than $100.

...(Design Constraints)...

With this problem statement identify the class and assign them to the group members. Make a card

for each class.

Some ideas for class:

application

library

material

books

videos

journal

company

system

ID numbers

item

borrower

date

Page 342: C++ Book

organization

employee

article

fine

This list is made up of the nouns in the problem statement. It is up to you to decide which ones if any

are good classes for this problem.

Now lets try our first scenario, taken from the requirement that the system bust allow users to check

out lendables.

"What happens when Johny Codewarrior, who has no accrued fines and one outstanding book, not

overdue, checks out a book entitle Document, Your job depends on it?"

More about Analysis

The strength of CRC cards for analysis.

Common Project Vocabulary -

Spread Domain Knowledge -

Making the Paradigm Shift -

Live Prototyping -

Identifying Holes in Requirements -

When is the analysis done, and time to move on to design? When all the different responsibilities are

in place and the system has become stable. After all the normal behavior has been covered,

exceptional behavior needs to be simulated. When you notice that the responsibilities are all in place

to support the new scenarios, and there is little change to the cards, this is a sign the you are ready to

start design.

Activity 2.

Now let do some more scenarios and try to stabilize our system. Try these:

"What happens when Johny Codewarrior returns the book Document, Your job depends on it two

days late? He has no other item checked out and no acquired fines."

"What happens when Ivar Jacobson uses the search feature to look for the book Object-Oriented

Software Engineering of which there are 2 copies available?"

Page 343: C++ Book

"What happens when Grady Booch uses the search feature to look for the book Object-Oriented

Analysis and Design with Application of which there is 1 copy available and the database is down?"

3. CRC cards for Design.

In the design phase, the concentration moves from what to how. In this phase developers replace

some of the domain experts in the group, but there still should be one domain expert in the group.

Strength of CRC card for Design

Spreading Objet-Oriented Design Expertise

Design Reviews

Framework for Implementation

Informal Notation

Things to consider in Design

Target Environment

Language

Choice of supporting software components

Performance Requirements

Other - memory, security...

CRC Element at the Design Stage

Classes

Think about what class are need to make the system work. Do you need a List class to hold objects?

Do you need class to handle exceptions? Do you need wrapper classes for other subsystems? New

classes that are looked for in this part, are classes that support the implementation of the system.

Scenarios and Responsibilities

During the problem modeling in the analysis phase the distinction between class and object is blurry.

Now think about the objects in your scenarios. Who create the objects? What happens when it is

created and destroyed? What is the lifetime of the object vs. the lifetime of the information held be

the object?

Attributes

Page 344: C++ Book

Now is the time to look at what information the objects hold compared to what is requested from

other classes or computed of the fly. Use the back of the card to record the attributes found for the

classes.

New things to record your cards

Sub responsibilities

Break you responsibilities into sub responsibilities and list the sub responsibilities indented under the

main responsibilities. Move the collaborators next to the sub responsibilities that use them.

Collaborating Responsibilities

After the Collaborator class on your card list the responsibility of the used class that is used in the

collaboration.

Data passed

After the collaborating responsibilities on your cards, list the data past back by the collaborating

object in parenthesis.

Activity 3.

Redo the scenarios you did in the analysis phase, but know take in to consideration all of the design

heuristics discussed. Make up your own scenarios and try them...

System Requirements

Cards:

Should be physical cards, not virtual cards. CASE tools for support of CRC cards are useful, but they

cannot replace the interaction that physical cards facilitate.

3x5 or 4x6 are the perferable size. But you can really use anything you want.... Napkins???

Denny's??? Ahh the possiblities are endless...

Summary

A CRC cards is an index card that is use to represent the responsibilities of classes and the

interaction between the classes. CRC cards are an informal approach to object oriented

modeling.

Why uses CRC cards?

They are portable... No computers are required so they can be used anywhere. Even away from the

office.

Page 345: C++ Book

They allow the participants to experience first hand how the system will work. No computer

tool can replace the interaction that happens by physically picking up the cards and playing

the roll of that object...

They are a useful too for teaching people the object-oriented paradigm.

Questions

1.What is CRC card? Why we are in need of using CRC cards?

Page 346: C++ Book

UNIT II

LESSON 38

DESIGN REFINEMENT

Objective:

Concept of coupling and cohesion

Design Refinement

Refinement presupposes that implementation is being inherited as well as abstraction.

Refinement has different significance depending on whether the client is another component

entirely, or is a part of B. Clearly any class can be a client of itself (self-dependency would seem

to be non-problematic, but some of the concerns in refinement with base as client cast doubt on

this).

Coupling and Cohesion between modules (i.e., classes).

Specific measures of coupling are:

1. The number of classes that a given class inherits from;

2. The number of classes that a given class references as data members;

3. The number of methods that a given method calls;

4. The number of parameters that a given method has.

Specific measures of cohesion are:

1. The degree to which all methods in a class perform a logically-related aspect of

system functionality

2. The degree to which a method performs a single specific function

In general, coupling should be minimized and cohesion should be maximized.

Techniques to reduce coupling

Limit the number of classes that communicate with (i.e, call functions of) other classes.

Page 347: C++ Book

I. E.g. in an MVP design, a Process-class method invoked by a View class method

may forward a Model-class exception rather than catching the exception and

calling a View-class method.

II. E.g.,

a. In the Rolodex system, the Process-class method Rolodex Command

Processor. Process Command is called from a View-class method in

Rolodex Command Editor.

b. The process Command method throws an Input Errors exception back

to the view, rather than catching the exception and calling a View

class.

c. This limits coupling by not having a View class reference in the

Rolodex Command Processor process class.

Limit the number of calls between classes that do need to communicate with each other.

I. E.g., in the Rolodex system, the dialog button functions, such as OKAddButton,

can communicate directly with the model, without having to go through a parent

view class.

II. E.g., OKAddButton. ActionPerformed can call Rolodex. Add directly

III. More highly-coupled alternative would be some chain-of-command call such as

AddCardDialog.getRolodex().add.

Limit the number of public functions in each class.

I. In general, make a function public only if there is a demand for it from some other

class.

II. Do not add public get functions "in case" they may be needed; the same goes for

public set functions.

III. E.g., since AddCardDialog.getRolodex is never used, it should not be provided.

Page 348: C++ Book

Limit the types of function parameters and return values to the smallest type necessary.

I. Consider the Rolodex.find operation.

II. It returns zero or more cards, which could be returned as Rolodex object, or a

simpler CardList object.

III. The Card List object is preferable, since callers of Rolodex.find do not need all of

the information in a full Rolodex, but only a simple list.

Design to limit the amount of change needed if data representations change.

I. When using external process classes (e.g., C++ from Java), design wrapper

classes that define a generic process class that hides details of external class.

II. With a properly designed wrapper class, little or no changes to a Model class are

necessary when changing underlying data representations in Process classes.

Use exception handling wisely.

I. Consider again the use of exception handling to communicate between models

and views.

II. The InputErrors exception classes provide a generic, string-based representation

that can be used uniformly for error communication.

Ease of debugging -- a major rationale for limiting coupling.

I. Consider the debugging question: "If something goes wrong in module X, where

do I look for the problem?"

II. First, look in module X for the problem.

III. If it's caused immediately there, then look at all other modules that connect to X.

IV. Repeat this process until the source of the problem is located.

Clearly, this problem isolation process will be made more orderly, and potentially shorter if the

number of directly connected modules is limited

Techniques to increase coherence(Cohesion)

Page 349: C++ Book

Generally, coupling measures are easier to pinpoint exactly.

Limiting the coupling between classes in turn increases cohesiveness, since

decoupling eliminates unnecessary items from classes.

To address cohesion directly means to design each class to represent a single, clearly

identifiable piece of data and/or encapsulate a single clearly identifiable area of

functionality.

To a large extent, the MVP design technique promotes cohesion, since it has well-

defined functionality for each category of design class.

Limiting the size of each individual scoping unit (class or function), per our design

and implementation conventions, is also a way to foster cohesion.

I.e., it's harder to do too much in a class or function if you can't do that much there in

the first place.

Summary

Coupling" and "cohesion" are terms used to denote module interconnectedness. Coupling refers to

how much inter-module connection exists in a design and Cohesion refers to how much intra-module

cohesiveness a design has.

In general, coupling should be minimized and cohesion should be maximized.

Specific measures of coupling are:

The number of classes that a given class inherits from;

The number of classes that a given class references as data members;

The number of methods that a given method calls;

The number of parameters that a given method has.

Specific measures of cohesion are:

The degree to which all methods in a class perform a logically-related aspect of system

functionality

Page 350: C++ Book

The degree to which a method performs a single specific function

Questions:

1. Define the concept of cohesion and coupling.

2. State steps to minimize cohesion

3. State steps to maximize coupling

Page 351: C++ Book

UNIT III

LESSON 39

STANDARD TEMPLATE LIBRARY(STL)

Objective

Intro to STL

Components of STL

Containers

Algorithms

Iterators

Sequential Containers

Introduction to the Standard Template Library

The Standard Template Library, or STL, is a C++ library of container classes, algorithms, and

iterators; it provides many of the basic algorithms and data structures of computer science. The STL

is a generic library, meaning that its components are heavily parameterized: almost every component

in the STL is a template. STL distinguishes general algorithms from the more specialized data and

methods encapsulated by ordinary abstract data types. In this way, complex and powerful algorithms

can be implemented independently of the data to which they are applied, allowing for generalization

and reuse of these algorithms. You should make sure that you understand how templates work in C+

+ before you use the STL.

The idea behind STL can easily be shown by the following consideration:

Imagine software components as a three-dimensional space. One dimension represents the data types

(int, double, char, ...), the second dimension represents the containers (array, linked-list, ...) and the

third dimension represents the algorithms (sort, merge, search, ...).

Page 352: C++ Book

Figure: Component space

With this scenario given, i*j*k different versions of code have to be designed - a sort algorithm for

an array of int, the same sort algorithm for an array of double, a search algorithm for a linked-list of

double and so on. By using template functions that are parameterized by a data type, the i-axes can

be dropped and only j*k versions of code have to be designed, because there has to be only one

linked-list implementation which then can hold objects of any data-type. The next step is to make the

algorithms work on different containers - that means that a search algorithm should work on arrays

as well as on linked-lists, etc. Then, only j + k versions of code have to be created.

“Lets shortly summarize a few points about STL before we proceed further….”

1. Library of classes for use in manipulating data structures

2. High level code (most of the details hidden from view -- need only know the interface)

3. Safe reusable code:

1. Minimize need to manipulate pointers

2. Minimize dangers of reading past end of arrays

3. Minimize software development time for implementation of standard data structures

Templatized so can be used with variety of data types

Page 353: C++ Book

Components of STL

The STL contains several components. But at its core there are three key components

They are

Containers

A container is an object that actually stores data. It is a way data is organized in memory.

The STL containers are implemented by template classes and therefore can be easily

customized to hold different types of data.

Containers are classes to contain data. Examples:

1. sequential containers

list

vector

deque

2. associative containers

set

map

multiset

multimap

3. container adaptors

stack

queue

priority_queue

Algorithms

Basic algorithms that can be used to manipulate the contents of containers. An algorithm

is a procedure that is used to process the data contained in the containers, The STL

includes many different kinds of algorithms to provide support to tasks such as

initializing, searching, copying, sorting, and merging. Algorithms are implemented by

template functions.

Examples:

a. copy()

b. sort()

Page 354: C++ Book

Iterators

Iterators are classes to access elements in containers. Act like pointers, but

minimize the need to dereference. Minimize the need to implement loops for

accessing or outputting data

Containers and algorithms

Like many class libraries, the STL includes container classes: classes whose purpose is to contain

other objects.

The STL includes the classes vector, list, deque, set, multiset, map, multimap, hash_set,

hash_multiset, hash_map, and hash_multimap. Each of these classes is a template, and can be

instantiated to contain any type of object. You can, for example, use a vector<int> in much the

same way as you would use an ordinary C array, except that vector eliminates the chore of

managing dynamic memory allocation by hand.

vector<int> v(3); // Declare a vector of 3 elements.

v[0] = 7;

v[1] = v[0] + 3;

v[2] = v[0] + v[1]; // v[0] == 7, v[1] == 10, v[2] == 17

Characteristics of Containers

Here are some general characteristics of all containers:

1. Collections of items -- numbers, names, ordered pairs of items, etc.

2. Objects are stored in different ways depending on the container. Each container has its way

of storing objects.

Each container has methods (member functions) to do basic tasks.

The STL also includes a large collection of algorithms that manipulate the data stored in containers.

You can reverse the order of elements in a vector, for example, by using the reverse algorithm.

Page 355: C++ Book

reverse(v.begin(), v.end()); // v[0] == 17, v[1] == 10, v[2] == 7

There are two important points to notice about this call to reverse. First, it is a global function, not

a member function. Second, it takes two arguments rather than one: it operates on a range of

elements, rather than on a container. In this particular case the range happens to be the entire

container v.

The reason for both of these facts is the same: reverse, like other STL algorithms, is decoupled

from the STL container classes. This means that reverse can be used not only to reverse elements in

vectors, but also to reverse elements in lists, and even elements in C arrays. The following program

is also valid.

double A[6] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7 };

reverse(A, A + 6);

for (int i = 0; i < 6; ++i)

cout << "A[" << i << "] = " << A[i];

This example uses a range, just like the example of reversing a vector: the first argument to reverse

is a pointer to the beginning of the range, and the second argument points one element past the end

of the range. This range is denoted [A, A + 6); the asymmetrical notation is a reminder that the two

endpoints are different, that the first is the beginning of the range and the second is one past the end

of the range.

STL Example Code

Look at these sample code fragments, then read the discussion points afterwards.

Operations using a list class object

This example instantiates a list of int and then does some operations on it. A list class stores

data in the form of a linked list (Click here for a copy of the example code.):

#include < list > // std header file for STL list class

#include < algorithm > // std header file for STL algorithms

int main()

{

Page 356: C++ Book

int num;

list < int > numbers; // declare an object of list class in STL

for( int i = 0; i < 10; i++ ) // read some numbers and insert in list:

{

cin >> num;

// insert the number before current beginning

numbers.insert( numbers.begin(), num );

}

numbers.sort(); // sort the numbers (low to high): member function

numbers.reverse(); // reverse the order: member function

numbers.remove(3); // remove all instances of the number 3

numbers.erase( ++numbers.begin() ); // erase the second element

ostream_iterator <int> output( cout, "\n" ); // output the list

copy( numbers.begin(), numbers.end(), output );

}

Points to note about this example:

1. You must include the header file list which declares the class template list.

2. You can instantiate a list object to any valid data type. The example object holds integers.

list is an example of a container class.

3. Just like any linked list, this one will add a node as needed when a new number is inserted.

4. insert()

1. This insert member function of the list class inserts the second argument before

the location specified by the first argument.

Page 357: C++ Book

2. Its first argument is an iterator which for the list class is basically like a pointer to a

node in the list.

3. The list member function begin() returns an iterator (pointer) to the first node

5. Other member functions of the list class:

1. sort()

This is a member function of the list class. There is also a sort() non-member

algorithm that can be used.

2. reverse()

Reverse the current order of elements.

3. remove()

Delete all nodes storing instances of the argument passed in.

4. erase()

Delete the node occurring at the position indicated by the iterator argument. This

example deletes the first node after the beginning, i.e. the second node. Note the

difference between remove and erase. To delete all instances of an element, use

remove. To delete element at a given position, use erase.

6. Syntax of the iterator numbers.begin()

Notice that to get the next node after the beginning, I had to use the increment operator ++.

This gave a pointer to the second node in the list.

7. Output the list:

Output was accomplished using another iterator.

1. Instantiate an object of type ostream_iterator <int>.

2. The call to the ostream_iterator constructor says that cout will be the ostream

used and newlines \n will be the delimiters between successive outputs.

3. The ostream_iterator object is named output.

4. The STL algorithm function copy() writes all the list elements (from begin() to

end() to output.

Page 358: C++ Book

Operations using a vector class object

A vector is a class that stores data using an array. This example instantiates an array of string

objects (Click here for a copy of the example code.).

#include < vector > // std header file for STL vector class

#include < algorithm > // std header file for STL algorithms

#include < string > // header for string class

int main()

{

vector < string > names; // declare an object of vector class in STL

char Name[10];

for( int i = 0; i < 10; i++ ) // read some names and insert in vector:

{

cin >> Name;

names.insert( names.begin(), Name );

}

names.erase( names.end() ); // erase the last string

sort( names.begin(), names.end() ); // sort the array: must use STL algorithm

for( unsigned i = 0; i < names.size(); i++ ) // output the array

cout << names[i] << endl;

}

Points to note about this example:

1. You must include the header file vector which declares the class template vector.

Page 359: C++ Book

2. You can instantiate a vector object to any valid data type. The example object holds strings.

vector is another example of a container class.

3. vector stores objects in an array. But unlike arrays that you are familiar with, this one grows

or shrinks automatically as elements are added or removed.

4. Overloaded member subscript operator [ ]

Notice the subscript operator in the expression names[i]. A vector object is not an array,

but the overloaded subscript operator lets you have random access to the array of data

elements contained within it.

5. The vector member function end() returns an iterator (pointer) to the last element in the

array.

6. erase()

Delete the node occurring at the position indicated by the iterator argument. This example

deletes the last node.

7. size()

This is a member function that returns the number of elements in the class. size() is also a

member of the list class.

8. Note the member functions that are missing: Several member functions seen in the list

example are missing here:

9. remove

10. sort

11. reverse

This has to do with the different storage methods of a vector vs a list. Because vector

elements are stored in an array, the operations listed here cannot be implemented as

efficiently as they can be for data stored in linked lists.

12. STL Algorithms

We were able to sort the vector using the generic STL algorithm. The vector class does not

have its member sort().

13. Output of the array:

Page 360: C++ Book

1. Notice we used a for loop together with overloaded index operator [ ] to output the

vector elements.

2. Output could also have been done using an ostream_iterator:

3. ostream_iterator<string> out( cout, "\n" );

4. copy( names.begin(), names.end(), out );

Discussion of these examples

These two examples have illustrated several points.

We saw examples of different types of objects:

1. container objects

1. list

2. vector

2. iterator objects

1. value returned by begin() and end()

2. ostream_iterator

3. We saw that list had different member functions than vector. This was related to the

different ways that list and vector store their data.

4. Thus there is an issue of which container object to use. Each has its good points and

drawbacks.

5. We saw two examples of STL algorithms:

6. copy()

7. sort()

Notice that the STL algorithm sort() is different from the list class member sort(). To

use it, we included the header algorithm.

Next we will discuss STL container objects with reference to these points.

Containers

These are classes for storing data. There are sequential containers that store data in the form of lists,

and associative containers.

Page 361: C++ Book

Here are examples of methods common to all containers except stack, queue and

priority_queue:

1 Begin() find the first element.

2 Return an iterator (like a pointer) to that element

3 end() find the last element.

4 Return an iterator (like a pointer) to that element

5 size() return the number of elements currently container

6 erase() remove an element from the container at location

specified by iterator

7 operator=assign one container to another -- do memberwise

8 copy of objects stored in right side

9 operator== test for equality of two containers

10 operator!= test for inequality of two containers

Sequential Containers

These are containers that hold items in lists but are implemented in different ways. A list means a

collection of objects in which there is a first and a last object, and each object (except first and last)

has a predecessor and a successor. In other words, a list implies an ordering.

Now look at three types of classes implementing lists:

1. list class

1. Implemented as a doubly linked list (non-contiguous memory). This means each node

has a pointer forwards to the next node, and a pointer backwards to the previous node.

2. In addition to basic member functions above, also has these member functions:

3. sort() sort the elements in the list

4. reverse() reverse the current order of list

5. remove() delete all instances of argument object

6. Efficient insertion at beginning or end of list.

7. Linear time (O(N)) to access other elements of the list: must traverse the list.

8. List grows or shrinks automatically as elements are added or removed.

Page 362: C++ Book

2. vector classes

1. Implemented as array (contiguous memory).

2. Efficient insertion at back of array: just add item to slot after current last.

3. Linear time(O(N)) to insert or remove element at front: must shift all the other array

elements to fill up empty hole.

4. Efficient access of indexed element: random access. This is accomplished by:

5. Overloaded subscript member operator [].

6. Grows or shrinks automatically as elements are added or removed.

3. deque class

1. Implemented in non-contiguous memory

2. Combine list's efficient insert/remove of front elements with vector's efficient

random access of indexed elements.

3. Has overloaded member subscript operator.

4. Grows or shrinks automatically as elements are added or removed.

The method of data storage in a container influences the efficiency of operations on the data. Here is

a table:

Operation vector deque list

--------- ------ ----- ----

Insert at beginning O(N) constant constant

Insert at end constant constant constant

Erase at beginning O(N) constant constant

Erase at end constant constant constant

Get first element constant constant constant

Page 363: C++ Book

Get last element constant constant constant

Get middle element constant constant O(N)

Here O(N) means that the complexity of the operation depends upon the number of elements N stored

in the container object. It is a measure of the time needed to do the task. As N grows, then the time to

do the task grows roughly proportional to N.

Summary

A collection of generic classes and functions is called the Standard Template Library(STL). STL

components are part of C++ standard library.

The STL contains several components. But at its core there are three key components

They are

· Containers

· Algorithms.

· Iterators

The STL does, however, include several other types of components.

First, the STL includes several utilities: very basic concepts and functions that are used in

many different parts of the library. The concept Assignable, for example, describes types that

have assignment operators and copy constructors; almost all STL classes are models of

Assignable, and almost all STL algorithms require their arguments to be models of

Assignable.

Second, the STL includes some low-level mechanisms for allocating and deallocating

memory. Allocators are very specialized, and you can safely ignore them for almost all

purposes.

Page 364: C++ Book

Finally, the STL includes a large collection of function objects, also known as functors. Just

as iterators are a generalization of pointers, function objects are a generalization of functions:

a function object is anything that you can call using the ordinary function call syntax. There

are several different concepts relating to function objects, including Unary Function (a

function object that takes a single argument, i.e. one that is called as f(x)) and Binary

Function (a function object that takes two arguments, i.e. one that is called as f(x, y)).

Function objects are an important part of generic programming because they allow

abstraction not only over the types of objects, but also over the operations that are being

performed.

Questions

1. what is STL How it is different from standard library

2. Discuss three types of containers

Page 365: C++ Book

UNIT III

Lesson 40

Standard Template Library(STL) II

Objective

Algorithm

Iterator

Concept modeling

ALGORITHMS

Algorithms are functions that can be used generally across a variety of containers for processing

their contents. Although each container provides functions for its basic operations, STL provides

more than sixty standard algorithms to support more extended or complex operations. Standard

algorithms also permit us to work with two different types of containers

at the same time. Remember, STL algorithms are not member functions or friends of containers.

They are standalone template functions.

STL algorithms reinforce the philosophy of reusability. By using these algorithms, programmers can

save a lot of time and effort. To have access to the STL algorithms, we must include <algorithm> in

our program.

STL algorithms, based on the nature of operations they perform, may be categorized as

under:

. Retrieve or non-mutating algorithms . Mutating algorithms

. Sorting algorithms

. Set algorithms

. Relational algorithms

These algorithms are summarized in Tables.

STL also contains a few numeric algorithms under the header file <numeric>. They are listed

Non-mutating algorithms

Page 366: C++ Book

Operations Description

Adjacent_find( ) Finds adjacent pair of objects that are equal

count( ) Counts occurrence of a value in a sequence

count_if( ) Counts number of elements that matches a predicate

equal( ) True if two ranges are the same

find( ) Finds first occurrence of a value in a sequence

for_each( ) Apply an operation to each element

search( ) Finds a subsequence within a sequence

Mutating algorithms

Operations Description

copy( ) Copies a sequence

fill() Fills a sequence with a specified value

generate( ) Replaces all elements with the result of an operation

iter_swap( ) Swaps elements pointed to by iter:'tors

remove( ) Deletes elements matching a predicate

replace( ) Replaces elements with a specified value

Sorting algorithm

Operations Description

binary _search( ) Conducts a binary search on an ordered sequence

equalrange( ) Finds a subrange of elements with a given value

merge( ) Merges two consecutive sorted sequences

pop_heap( ) Deletes the top element

push_heap() Adds an element to heap I

sort( ) Sorts a sequence

Page 367: C++ Book

Iterators

Iterators behave like pointers and are used to access container elements. They are often used to

traverse from one element to another, a process known as iterating through the container.

There are five types of iterators as described

Iterator Access method Direction of movement I/O

capability

Remark

Input Linear Forward only Read only Cannot be saved

output Linear Forward only Write only Cannot be saved

Forward Linear Forward only Read / write Can be saved

Bidirectional Linear Forward & backward Read / write Can be saved

Random Random Forward & backward Read / write Can be saved

Different types of iterators must be used with the different types of containers. Note that only

sequence and associative containers are traversable with iterators.

In the example of reversing a C array, the arguments to reverse are clearly of type double*. What

are the arguments to reverse if you are reversing a vector, though, or a list? That is, what exactly

does reverse declare its arguments to be, and what exactly do v.begin() and v.end() return?

The answer is that the arguments to reverse are iterators, which are a generalization of pointers.

Pointers themselves are iterators, which is why it is possible to reverse the elements of a C array.

Similarly, vector declares the nested types iterator and const_iterator. In the example above,

the type returned by v.begin() and v.end() is vector<int>::iterator. There are also some

iterators, such as istream_iterator and ostream_iterator, that aren't associated with containers

at all.

Iterators are the mechanism that makes it possible to decouple algorithms from containers:

algorithms are templates, and are parameterized by the type of iterator, so they are not restricted to a

single type of container. Consider, for example, how to write an algorithm that performs linear

search through a range. This is the STL's find algorithm.

template <class InputIterator, class T>

Page 368: C++ Book

InputIterator find(InputIterator first, InputIterator last, const T& value)

{

while (first != last && *first != value) ++first;

return first;

}

Find takes three arguments: two iterators that define a range, and a value to search for in that range.

It examines each iterator in the range [first, last), proceeding from the beginning to the end,

and stops either when it finds an iterator that points to value or when it reaches the end of the range.

First and last are declared to be of type InputIterator, and InputIterator is a template

parameter. That is, there isn't actually any type called InputIterator: when you call find, the

compiler substitutes the actual type of the arguments for the formal type parameters InputIterator

and T. If the first two arguments to find are of type int* and the third is of type int, then it is as if

you had called the following function.

int* find(int* first, int* last, const int& value) {

while (first != last && *first != value) ++first;

return first;

}

Concepts and Modeling

One very important question to ask about any template function, not just about STL algorithms, is

what the set of types is that may correctly be substituted for the formal template parameters. Clearly,

for example, int* or double* may be substituted for find's formal template parameter Input

Iterator. Equally clearly, int or double may not: find uses the expression *first, and the

dereference operator makes no sense for an object of type int or of type double. The basic answer,

then, is that find implicitly defines a set of requirements on types, and that it may be instantiated

with any type that satisfies those requirements. Whatever type is substituted for Input Iterator

must provide certain operations: it must be possible to compare two objects of that type for equality,

it must be possible to increment an object of that type, it must be possible to dereference an object of

that type to obtain the object that it points to, and so on.

Find isn't the only STL algorithm that has such a set of requirements; the arguments to for_each and

count, and other algorithms, must satisfy the same requirements. These requirements are sufficiently

important that we give them a name: we call such a set of type requirements a concept, and we call

this particular concept Input Iterator. We say that a type conforms to a concept, or that it is a model

Page 369: C++ Book

of a concept, if it satisfies all of those requirements. We say that int* is a model of Input Iterator

because int* provides all of the operations that are specified by the Input Iterator requirements.

Concepts are not a part of the C++ language; there is no way to declare a concept in a program, or to

declare that a particular type is a model of a concept. Nevertheless, concepts are an extremely

important part of the STL. Using concepts makes it possible to write programs that cleanly separate

interface from implementation: the author of find only has to consider the interface specified by the

concept Input Iterator, rather than the implementation of every possible type that conforms to that

concept. Similarly, if you want to use find, you need only to ensure that the arguments you pass to it

are models of Input Iterator. This is the reason why find and reverse can be used with lists,

vectors, C arrays, and many other types: programming in terms of concepts, rather than in terms of

specific types, makes it possible to reuse software components and to combine components together.

Refinement

Input Iterator is, in fact, a rather weak concept: that is, it imposes very few requirements. An Input

Iterator must support a subset of pointer arithmetic (it must be possible to increment an Input

Iterator using prefix and postfix operator++), but need not support all operations of pointer

arithmetic. This is sufficient for find, but some other algorithms require that their arguments satisfy

additional requirements. Reverse, for example, must be able to decrement its arguments as well as

increment them; it uses the expression --last. In terms of concepts, we say that reverse's

arguments must be models of Bidirectional Iterator rather than Input Iterator.

The Bidirectional Iterator concept is very similar to the Input Iterator concept: it simply imposes

some additional requirements. The types that are models of Bidirectional Iterator are a subset of

the types that are models of Input Iterator: every type that is a model of Bidirectional Iterator is

also a model of Input Iterator. Int*, for example, is both a model of Bidirectional Iterator and a

model of Input Iterator, but istream_iterator, is only a model of Input Iterator: it does not

conform to the more stringent Bidirectional Iterator requirements.

We describe the relationship between Input Iterator and Bidirectional Iterator by saying that

Bidirectional Iterator is a refinement of Input Iterator. Refinement of concepts is very much like

inheritance of C++ classes; the main reason we use a different word, instead of just calling it

"inheritance", is to emphasize that refinement applies to concepts rather than to actual types.

Page 370: C++ Book

There are actually three more iterator concepts in addition to the two that we have already discussed:

the five iterator concepts are

Output Iterator,

Input Iterator,

Forward Iterator,

Bidirectional Iterator, and

Random Access Iterator;

Forward Iterator is a refinement of Input Iterator, Bidirectional Iterator is a refinement of

Forward Iterator, and Random Access Iterator is a refinement of Bidirectional Iterator.

(Output Iterator is related to the other four concepts, but it is not part of the hierarchy of

refinement: it is not a refinement of any of the other iterator concepts, and none of the other iterator

concepts are refinements of it.) The Iterator Overview has more information about iterators in

general.

Container classes, like iterators, are organized into a hierarchy of concepts. All containers are

models of the concept Container; more refined concepts, such as Sequence and Associative

Container, describe specific types of containers.

Other parts of the STL

If you understand algorithms, iterators, and containers, then you understand almost everything there

is to know about the STL. The STL does, however, include several other types of components.

First, the STL includes several utilities: very basic concepts and functions that are used in many

different parts of the library. The concept Assignable, for example, describes types that have

assignment operators and copy constructors; almost all STL classes are models of Assignable, and

almost all STL algorithms require their arguments to be models of Assignable.

Second, the STL includes some low-level mechanisms for allocating and deallocating memory.

Allocators are very specialized, and you can safely ignore them for almost all purposes.

Finally, the STL includes a large collection of function objects, also known as functors. Just as

iterators are a generalization of pointers, function objects are a generalization of functions: a

function object is anything that you can call using the ordinary function call syntax. There are

Page 371: C++ Book

several different concepts relating to function objects, including Unary Function (a function object

that takes a single argument, i.e. one that is called as f(x)) and Binary Function (a function object

that takes two arguments, i.e. one that is called as f(x, y)). Function objects are an important part

of generic programming because they allow abstraction not only over the types of objects, but also

over the operations that are being performed.

STL include files  STL is divided into the following header files  in order to reduce compilation time.

algo.h includes all the algorithms

bool.h simulates bool

bvector.h bit_vector

deque.h deque

function.h operators, function objects and function adaptors

iterator.h iterator tags, stream iterators and iterator adaptors

list.h list

map.h map

multimap.h multimap

multiset.h multiset

pair.h pair

random.C random number generator. It should be compiled and

linked if random_shuffle is used.

Page 372: C++ Book

set.h set

stack.h container adaptors

tempbuf.C an auxiliary buffer for get_temporary_buffer; it should be

compiled and linked if get_temporary_buffer, stable_partition,

inplace_merge or stable_sort are used.

tempbuf.h get_temporary_buffer

vector.h vector

(There are some other STL include files besides these but they are mainly for use with DOS and/or

Windows C++ compilers, for working with different memory models. They are not necessary for use

with the IBM xlC or Apogee apCC compilers.)

Summary

An algorithm is a procedure that is used to process the data contained in the containers, The STL

includes many different kinds of algorithms to provide support to tasks such as initializing,

searching, copying, sorting, and merging.

Algorithms are standalone functions that are used to carry out operations on the contents of

containers, such as sorting, searching, etc.

Iterators behave like pointers and are used to access container elements.

Iterators are the mechanism that makes it possible to decouple algorithms from containers:

algorithms are templates, and are parameterized by the type of iterator, so they are not restricted

to a single type of container.

Page 373: C++ Book

Questions

1. what is an algorithm?. Discuss it in brief?

2. What is an Iterator? Discuss it in brief?

3. Write a function template palindrome that takes as a parameter a const vector and

returns true or false depending upon whether the vector does or does not read the

saim forwards as backwords

Page 374: C++ Book

UNIT IV

LESSON 41

UNIFIED MODELING LANGUAGE (UML)

Objective

Concept of UML

UML Goals

UML Scope

UML Constituents

UML things

Overview of UML :

The Unified Modelling Language (UML) is a general-purpose visual modelling language. UMLis

used to' specify, visualize, construct, and document the artifacts of a software system. It captures

decisions and understanding about systems that is to be developed. It is commonly used to

understand. analyse, design, browse, configure, maintain, and control information about such

systems und~ development. It is specifically' designed for use with all development methods,

lifecycle stages.

application domains, and media. The modelling language is oriented to unify past experience about I

modelling techniques and to incorporate current software best practices into a standard approach.

UML covers semantic concepts, notation, and guidelines. It has different parts such as static,

dynamic, environmental, and organizational parts. It is intended to be supported by interactive visual

modelling CASE tools that have code generators and report writers. The UML specification does not

define a standard process however; it is intended to be useful with an iterative-development process.

It is intended to support most existing 00 development processes and methodologies. I

The UML captures information about the static system structure and dynamic behaviour of a system.

A system is modelled as a collection of discrete objects that interact with each other to perfonn work

that finally benefits an outside user. The static structure is used to define the kinds of

objectsimportant to a system and to its implementation, as well as the relationships among these

objects. The dynamic behaviour is used to define the history of objects over time and the

Page 375: C++ Book

communications among objects to accomplish goals. Modelling a system from several separate but

related viewpoints allows it to be understood for different purposes.

The UML also includes organizational constructs for arranging models into packages that

permit

software teams to do following:

To partition large systems into workable pieces,

To understand and control dependencies among the packages

To manage the versioning of model units in a complex development environment.

It conains constructs for representing implementation decisions and for organizing run-time

elements into components.

UML is not a programming language. Some CASE Tools such as Rational Rose can provide code

generators from UML into a variety of programming languages, as well as construct reverse

engineered models from existing programs.

The UML is not a highly formal language intended for theorem proying. There are a number

of such languages, but they are not easy to understand or to use for most purposes.

The UML is a general-purpose modeling language. For specialized domains, such as GUI

layout, VLSI circuit design, or rule-based artificial intelligence, a more specialized tool with a

special language might be appropriate.

UML is a discrete modelling language. It is not intended to model continuous systems such as those

found in engineering and physics. UML is intended to be a universal general-purpose modelling

language for discrete systems such as those made of software, firmware, or digital logic, etc.

What is UML ? :

The Unified Modelling Language is a language that unifies the industry's best software engineering

practices for modelling OO systems. UML's architecture is shown in Fig.

The UML Scope,

unification

Page 376: C++ Book

Process Programming Tool/Repository Language Specification

The Unified Modelling Language

The UML has following specifications:

UML is a language: It is not simply a notation for drawing diagrams, but a complete

language for capturing knowledge (semantics) about a subject and expressing knowledge

(syntax) regarding the subject for the purpose of communication.

UML applies to modelling and systems: Modelling involves a focus on understanding

(knowing) a subject (system) and capturing and being able to communicate this knowledge.

UML is the result of unifYing the information systems and technology industry's best

engineering

practices (principles, techniques, methods, and tools).

UML is used for specifying, visualizing, constructing and documenting systems.

UML is used for expressing the artifacts of system intensive process.

UML is based on the object-oriented paradigm.

UML is a modelling language for specifying, visualizing, constructing and documenting the

artifacts of a system-intensive process.

UML is an evolutionary general-purpose, broadly applicable, tool-supported, industry-

standardized modelling language.

UML applies to a multitude of different types of systems, domains and methods or process.

UML enables the capturing, communicating and leveraging of strategic, tactical, and

operational

knowledge to facilitate increasing value by increasing quality, reducing costs and reducing

time started the to -market while managing risks and being proactive about ever-increasing

change and complexity. .

UML was originally conceived by Rational Software Corporation and the Three Amigos as

Page 377: C++ Book

follows :

Grady Booch's work has involved the ,use of Ada and the application of data

abstraction and information hiding with an emphasis on iterative software

development and software architecture. He has been influential in

disseminating object orientation. He is the inventor of the Booch method, as

expressed in his book Object-Oriented Analysis and Design.

James Rumbaugh's work has involved various topics concerning research and

development within the context of complex algorithms and data structures. He

co-authored the Object Modelling Technique (OMT) with Mike Blaha, Bill

Premerlani, Fred Eddy and Bill Lorensen.

Ivar Jacobson's work has involved the application of object orientation to the

context 0f business reengineering and the industrialization of software

development. He is often knoWl1 as the father of use cases. He is the inventor

of the Object-Oriented Software Engineering: A Use Case Driven Approach.

UML is supported by the UML Partners Consortium (Rational Software Corporation,

Microsoft Corporation, Hewlett-Packard Company, Oracle Corporation, Sterling Software,

MCI System house Corporation, Unisys Corporation, ICON Computing.

What Does Unified Mean? :

The word unified has the following relevant meanings for UML :

Across historical methods and notations: The UML combines the commonly accepted concepts

from many OO methods, selecting a clear definition for each concept, as well as a notation and

terminology. The UML can represent most existing models as well as or better than the original

methods can.

Across the development lifecycle : The UML is seamless from requirements to Implementation.

The same set of concepts and notation can be used in different phases of development and even

mixed within a single model. It is unnecessary to translate from one stage to another. This

seamlessness is critical for iterative, incremental development.

Across application domains: The UML is intended to model most application domains, with the

systems that are large, complex, real-time, distributed, data or computation intensive, among other

properties. There may be specialized areas in which a special-purpose language is more useful, but

Page 378: C++ Book

UML is intended to be as good as or better than any other general-purpose modelling language for

most software application areas.

Across implementation languages and platforms: The UML is intended to be usable for systems

implemented in various implementation languages and platforms, including programming languages,

databases, 4GLs, organization documents, firmware and so on. The front-end aspect should be

identical or similar in all cases, while the backend work may differ somewhat for each medium.

Across development processes: The UML is a modelling language, and not a description of a

detailed development process. it is intended to be usable as the modelling language underlying most

existing or new development processes, just as a general purpose programming language can be used

in

many styles of programming. It is particularly intended to support the iterative, incremental style of

development that we recommend.

Across internal concepts: In constructing the UML metamodel, you can see, discover and represent

underlying relationships among various concepts, trying to capture model1ing concepts in a broad

way applicable to many known and unknown situations. This process led to a better understanding of

the concepts and a more general applicability of them. This was not the original purpose of the

unification work, but it was one of the most important results.

Scope and Goals of UML :

These were a number of goals behind the development of the UML. Some .of these goals are

as follows:

UML is a general-purpose modelling language that all modellers can use. It is intended to

address current software development issues, such as large scale, distribution, concurrency,

patterns, and team development.

UML is not intended to be a complete development method. It does not include a systematic

development process. '

A final goal of UML was to be as simple as possible while still being capable of modelling

the full range of practical systems that need to the built.

UML has different kinds of models; it is very difficult to master it in one day. It is more complicated

than the some of its antecedents, because it is intended to be more comprehensive. However, you do

not have to learn it al1 at once, any more than you would a programming language, an operating

system, or a complex user application.

Page 379: C++ Book

UML Goals:

.

The goals of the UML are to

Be a ready-to-use expressive visual modelling language that is simple and extensible.

Have extensibility and specialization mechanisms for extending, rather than modifying, core

concepts.

Fonnalize a core set of concepts that constitute the object-oriented paradigm. Extensions

will not require reimplementation of the core object oriented paradigm (analysis and

design) concepts in order to be applicable to a broad set of applications. Instead,

practitioners can extend this core set of concepts based on varying interpretations without

having to be repeatedly redefined the fundamental concepts.

Allow adding new concepts and notation beyond the core.

Allow variant interpretations of existing concepts when there is no clear consensus.

Allow specialization of concepts, notation, and constraints for particular domains.

Be implementation independent (programming language).

Be process independent (development).

Encourage the growth of the object-oriented tools market.

Support higher-level concepts (collaborations, frameworks, patterns and components).

Address recurring architectural complexity problems (physical distribution and distributed

systems, concurrency and concurrent systems, replication, security, load balancing and fault

tolerance) using component technology, visual programming, patterns, and frameworks.

Be scalable.

Be widely applicable (general purpose and powerful) and usable (simple, widely accepted,

evolutionary). Integrate the best engineering practices.

The UML Scope:

The scope of the UML encompasses

Combines the concepts of Booch, OMT, and OOSE

Page 380: C++ Book

Focusing on a standard modelling language (common notation) and not a standard process

Incorporating the object-oriented community's consensus on core modelling concepts

Providing sufficient notation to address contemporary modelling issues directly and

economically

Providing sufficient semantics to address the following issues directly and economically:

Contemporary modelling issues

Future modelling issues (specifically related to component technology, distributed

computing, frameworks and executability)

Model interchange among tools

Repository interfaces (to modelling artifacts) among tools

Providing extensibility mechanisms to address the following issues directly and economically

Current deviations within the object-oriented community

Extending the UML for individual projects

Future modelling approaches (on top of the UML)

What the UML Is Not:

The UML is not

A visual programming language, but a visual modelling language

o A programming language communicates im implementation or solution.

o A modelling language communicates a model (or conceptualisation or specification).

A tool or repository specification, but a modelling language specification

o A tool or repository specification specifies tools or repository's interface, storage, run-

time behaviour and so forth.

o A modelling language specification specifies modelling elements, notation, and usage

guidelines.

A process, but enables processes.

Page 381: C++ Book

o A process provides guidance regarding the order of activities, specification of

artifacts to be developed, direction of individual developer and team tasks (or

activities) and monitoring and measuring criteria of project artifacts and activities.

o Processes are organization, culture, and domain specific and dependent.

o The UML enables and promotes (but does not require nor mandate) a use-case.driven,

architecture-centric, iterative, and incremental process that is object oriented and

component based.

UML Constituents:

UML consists of following things:

The UML Definition:

The UML is defined by a set of documents as shown in follow Fig. 2 from Rational Software

Corporation and the Object Management Group.

The UML Definition

The UML definition

Is expressed by the following documents (the UML-defining artifacts)

UML varients User-Defined UML Extensions

UML Extension for Objectory Process for Software Engineering UML Extension for Business modelling

UML Notation Guide :UML Semantics

Objects Constraint Language Specification

Page 382: C++ Book

UML Semantics

UML Notation Guide

UML Introduction

UML Extension for the Objectory Process for Software Engineering

UML Extension for Business Modelling.

Uses the Object Constraint Language (OCL) defined by the Object Constraint Language

specification document.

May be obtained from Rational Software Corporation or the Object Management Group via

the World Wide Web (see the www.omg.org)

The UML Semantics Document:

The UML semantics document constitutes the single, common, definitive, formal, comprehensive

and precise specification of the UML (called the inside view). The UML semantics document.

Is primarily used by tool vendors; however, it maybe used by practitioners since it is the

definitive definition of the UML.

Specifies the UML has layered architecture, organization (using packages) and defined

modelling elements.

Includes the following inside-view information for a given UML package:

o Overview: General introduction

o Abstract syntax: Concept definitions, relationships, and constraints expressed using

the UML's graphical notation and English prose.

o Well-formed ness rules: Rules and constraints expressed using English prose and the

OCL. Semantics: Meanings expressed using English prose.

o Standard elements: Applicable standard extension mechanisms.

o Notes: Other commentary

Also contains appendices on the standard elements and the UML glossary.

Enables the development of complex systems, consistent usage of the UML, and tool interchange

The UML Notation Guide:

Page 383: C++ Book

The UML Notation Guide constitutes the notational or visual representation of the UML and

provides examples (called the outside view). The UML Notation Guide

o Is primarily used by practitioners applying the UML

o Specifies the UML's diagrams and their modelling elements

o Includes the following outside-view information for each modelling element:

o Semantics: Summarizes the UML semantics.

o Notation (concrete syntax) : Explains the notational representation (forward mapping to

notation).

o Presentation options: Describe option in presenting modelling information.

o Style guidelines: Suggest stylistic markers and options.

o Examples: Provide notation samples.

o Mapping: Explains the mapping of the notation to the semantics document (reverse mapping

from notation).

o Enables the use of the UML

.

The UML Extension Documents:

The UML extension documents provide user-defined extensions (using extension mechanisms).

These documents

UML Introduction

o Extend the UML to the objectory process for software engineering.

o Extend the UML to business modelling.

A UML extension is a set of extensions (stereotypes, tagged values, and constraints) that extend,

customize, or tailor the UML for a specific domain or process.

A UML variant is a semantically well-defined language (expressed as a metamodel) based on (and

built on top of) the UML metamodeI. It specialized the UML but does not change the UML terms or

redefine their meanings.

Page 384: C++ Book

The Object Constraint Language:

The Object Constraint Language (OCL) is a formal, easily readable and writable, non. programming,

implementation-independent language. The OCL

o Is used for expressing typed, pure, side-effect-free (precise and unambiguous) constraints and

Expressions

o Is used for attaching constraints and other expressions to the UML models and modelling

elements (or objects)

o Is used to specify the well-formedness rules of the UML within the UML semantics

document

o Is formally specified in the Object Constraint Language specification document, which

provides the following information: Connection with the UML semantics, basic values and

types, objects and properties, collection operations, predefined OCL types, and the grammar

for the OCL.

Scope and Purpose of UML as a Modelling Language:

The UML is a language for

. Visualizing

. Specifying

. Constructing

. Documenting

the artifacts of a software-intensive system.

The UML is a Language:

A language provides a vocabulary and the rules for combining words in that vocabulary for the

purpose of communication. A modelling language is a language whose vocabulary and rules focus

Page 385: C++ Book

on the conceptual and physical representation of a system. A modelling language such as the UML is

thus a standard language for software blueprints.

Modelling yields an understanding of a system. No one model is ever sufficient. Rather, you often

need multiple models that are connected to one another in order to understand anything but the most

trivial system. For software-intensive systems, this requires a language that addresses the different

views of a system's architecture as it evolves throughout the software development life cycle.

The vocabulary and rules of a language such as the UML tell you how to create and read wellformed

models, but they do not tell you what models you should create and when you should create them.

That is the role of the software development process. A well-defined process will guide you in

deciding what artifacts to produce, what activities and what workers to use to create them and

manage them, and how to use those artifacts to-measure and control the project as a whole.

The UML is a Language for Visualizing:

For many programmers, the distance between thinking of an implementation and then pounding lout

in code is close to zero. You think it, you code it. In fact, some things are best cast directly in code.

Text is a wonderfully minimal and direct way to write expression and algorithms.

In such cases, the programmer is still doing some modelling, albeit entirely mentally. He or she )ay

even sketch out a few ideas on white board or on a napkin. However, there are several problems than

this. First, communicating those conceptual models to others is error-prone unless everyone

envolved speaks the same language. Typically, projects and organizations develop their own

language and it is difficult to understand what is going on if you are an outsider or new to the group.

Second,

there are some things about a software system you cannot understand unless you build models that

transcend the textual programming language. For example, the meaning of a class hierarchy can be

il1ferred, but not directly grasped, by starting at the. code for all the classes in the hierarchy.

Similarly,the physical distribution and possible migration of the objects in a Web-based system can

be inferred, but not directly grasped, by studying the system's code. Third, if the developer who cut

the code never l\\Tote down the models that are in his or her head, that information would be lost

forever or at best only partially recreatable from the implementation, once that developer moved on.

Writing models in the UML addresses the third issue: An explicit model facilitates

communication.

Some things are best modelled textually; others are best modelled graphically. Indeed, in all

interesting systems there are structures that transcend what can be represented in a programming

Page 386: C++ Book

language. The UML is such a graphical language. This addresses the second problem described

earlier.

The UML is more than just a bunch of graphical symbols. Rather, behind each symbol in the

UML notation is a well-defined semantics. In this manner, one developer can write a model in the

UML and another developer or even another tool can interpret that model unambiguously. This

address the first issue described earlier.

The UML is a Language for Specifying:

In this context, specifying means building models that are precise, unambiguous and complete. In

particular, the UML address the specification of all the important analysis design and

implementation decisions that must be made in developing and deploying a software-intensive

system.

The UML is a Language for Constructing:

The UML is not a visual programming language but its models can be directly connected to a variety

of programming languages. This means that it is possible to map from a model in the UML to

programming language such as Java, C++, or Visual Basic, or even to tables in a relational database

or the persistent store of an object-oriented database. Things that are best expressed graphically are

done so graphically in the UML, whereas things that are best expressed textually are done so in the

programming language.

This mapping permits forward engineering: The generation of code from a UML model into' a

programming language. The reverse is also possible: You can reconstruct a. model from an

implementation back into the UML. Reverse engineering is not magic. Unless you encode that

information in the implementation, information is lost when moving forward from models to code.

Reverse engineering thus requires tool support with human intervention. Combining these two paths

of forward code generation and reverse engineering yields round-trip engineering, meaning the

ability to work in either a graphical or a textual view, while tools keep the two views consistent.

In addition to this direct mapping, the UML is sufficiently expressive and unambiguous to

permit the direct execution of models, the simulation of systems and the instrumentation of running

systems.

The UML is a Language for Documenting:

Page 387: C++ Book

A healthy software organization produces all sorts of artifacts in addition to raw executable code.

These artifacts include (but are not limited to)

. Requirements . Architecture Design

. Source code . Project plans tests

. Prototypes . Releases

Depending on the development culture, some of these artifacts are treated more or less

formalIy than others. Such artifacts are not only the deliverables of a project, they are also critical in

controlling,. measuring and communicating about a system during its development and after its

deployment.

The UML addresses the documentation of a system's architecture and all of its details. The UML

also provides a language for expressing requirements and for tests. Finally, the UML provides a

language for modelling the activities of project planning and release management.

UML Applications:

The UML is intended primarily for software intensive systems. It has been used effectively for such

domains as :

Management information systems . Banking and financial services

Business Information systems . Telecommunications

Transportation . Defence/aerospace.

Retail . Medical electronics

Scientific . Distributed Web-based services

The UML is not limited to modelling software. In fact, it is expressive enough to model non--

software systems, such as workflow in the legal system, the structure, and behavior of a patient

health care system and the design of hardware.

.

.

.

A conceptual Model of UML :

Page 388: C++ Book

To understand the UML, you need to form a conceptual model of the language, and this requires

learning three major elements: the UML's basic building blocks, the rules that dictate how those

building blocks may be put together and some common mechanisms that apply throughout the UML.

Once you have grasped these ideas, you will be able to read UML models and create some basic

ones. As you gain more experience in applying the UML, you can build on this conceptual model

using more advanced features of the language.

Building Blocks of the UML :

The vocabulary of the UML encompasses three kinds of building blocks:

UML Introduction

Things

Relationships

Diagrams

Things are the abstractions that are first-class citizens in a model; relationships tie these things

together; diagrams group interesting collections of things.

Things Included in the UML :

There are Four Kinds of Things in the UML as follows:

Structural things

Behavioural things

Grouping things

Annotational things

These things are the basic object-oriented building blocks of the UML. You can use them to

Page 389: C++ Book

write well-formed models. .

Structural Things are the nouns of UML models. These are the mostly static parts of a model,

representing elements that are either conceptual or physical. In all, there are seven kinds of structural

things.

A class is a description of a set of objects that share the same attributes, operations, relationships,

and semantics. A class is used to implement one or more interfaces. Graphically a class is rendered

as a rectangle usually including its name, attributes, and operations. Class is shown in Fig.

Window

ongmsizeopen ( )close ( )move ( )display ( )Fig.: Classes

An interface is a collection of operations that specify a service of a class or component. An interface

describes the externally visible behavior of that element. An interface can represent the complete

behavior of a class or component or only a part of that behavior.

An interface defines a set of operation specifications (that is, their signatures) but never a set of

operation implementations. Graphically an interface is rendered as a circle together with its name.

An interface rarely stands alone. Rather it is typically attached to the class or component that realizes

the interface as shown in Fig

Ispelling

Fig. Interfaces

Collaboration defines an interaction and is a society of roles and other elements that work together to

provide some co-operative behavior that is bigger than the sum of all the elements.

Collaborations have structural as well as behavioural dimensions. A given class might participate in

several collaborations. These collaborations therefore represent the implementation of patterns that

Page 390: C++ Book

make up a system. Graphically collaboration is rendered as an ellipse with dashed lines usually

including only its name as shown in Fig.

Fig. Collaborations

A use case is a description of set of sequence of actions that a system performs that yields an

observable result of value to a particular actor. A use case is used to structure the behavioral things

in a model. A use case is realized by collaboration. Graphically a use case is rendered as an ellipse

with solid lines usually including only its name as shown in Fig.

Fig.: Use Cases

The remaining three things active classes, components, and nodes are all class-like because they also

describe a set of objects that share the same attributes, operations, relationships, and semantics.

However, these three are different enough and are necessary for modeling certain aspects of an

object oriented system and so they warrant special treatment.

An active class is a class whose objects own one or more processes or threads and therefore can

initiate control activity.

An active class is just like a class except that its objects represent elements whose behavior is

concurrent with other elements. Graphically an active class is rendered just like a class but with

heavy lines usually including its name attributes and operations as shown in Fig.

Chain of resposibility

Place order

Page 391: C++ Book

Fig.: Active Classes

The remaining two elements. component and nodes are also different. They represent physical things

whereas the previous five things represent conceptual or logical things.

A component is a physical and replaceable part of a system that conforms to and provides the

realization of a set of interfaces. In a system, you will encounter different kinds of deployment

components, such as COM+ components or Java Beans as well as components that are artifacts of

the development process such as source code files.

- A component typically represents the physical packaging' of other Wise logical elements such as

classes interfaces and collaborations. Graphically a. component is rendered as a rectangle with tabs

usually including only its name as shown in Fig. .

Fig : Components

Event Manager

Suspend()Flush()

orderform.java

Page 392: C++ Book

A node is a physical element that exists at run time and represents a computational resource,

generally having at least some memory and often processing capability. A set of components may

reside on a node and may migrate from node to node. Graphically a node is rendered as a cube

usually including only its name as in shown Fig

Fig. Nodes

These seven elements classes, interfaces, collaborations, use cases, active classes, components

and nodes are the basic structural things that you can include in a UML model. There are also

variations

.on these seven such as actors signals and utilities (kinds of classes) processes and threads (kinds of

active classes) and applications documents files libraries pages and table (kinds of components).

Behavioral Things are the dynamic parts of UML models. These are the verbs of a model,

representing behavioral over time and space. In all, there are two primary kinds of behavioral

things.

An interaction is a behavior that comprises a set of messages exchange among a set of objects within

a particular context to accomplish a specific purpose. The behavior of a society of objects or have an

individual operation may specify with an interaction.

An interaction involves a number of other elements, including messages, action sequences (the

behaviour invoked by a message) and links (the connection between objects). Graphically a message

is rendered as a directed line usually including the name of its operation as shown in Fig.

server

Page 393: C++ Book

display.

Fig. : Messages

A state machine is a behavior that specifies the sequences of states an object or an interaction goes

through during its lifetime in response to events, together with its responses to those events. The

behavior of individual class or a collaboration of classes may be specified with a state machine. A

state machine involves a number of other elements, including states, transitions (the flow from state

to state), events(things that trigger a transition) and activities (the response to a transition).

Graphically a state is rendered as a rounded rectangle, usually including its name and its substates, if

any as shown in Fig.

These two elements interactions and state machines are the basic behavioural things that you may

include in a UML model. Semantically, these elements are usually connected to various structural

elements, primarily classes, collaborations and objects.

Grouping Things are the organizational parts of UML models. A model can be decomposed into

these boxes. In all there is one primary kind of grouping thing namely packages.

States

A package is a general-purpose mechanism for organizing elements into groups. Structural things,

behavioural things and even other grouping things may be placed in a package. Unlike components,

(which exist at run time) a package is purely conceptual (meaning that it exists only at development

time). Graphically a package is rendered as a tabbed folder usually including only its name and

sometimes its contents as shown in Fig.

waiting

Page 394: C++ Book

Fig.: Packages

Packages are the basic grouping things with which you can organize a UML model. There are also

variations such as frameworks models and subsystems (kinds of packages).

Annotational Things are the explanatory parts of UML models. These are the comments you may

apply to describe, illuminate, and remark about any element in a model. There is one primary kind of

annotational thing, called a note. A note is simply a symbol for rendering constraints and comments

attached to an element or a collection of elements. Graphically a note is rendered as a rectangle with

a dog-eared comer together with a textual or graphical comment as shown in Fig.

Fig. : Notes

This element is the one basic annotational thing you may include in a UML model. You will

typically use notes to adorn your diagrams with constraints or comments that are the best expressed

in informal or formal text. There are also variations on this element, such as requirements (which

specify some desired behavior from the perspective of outside of model).

Summary

The Unified Modelling Language (UML) is a general-purpose visual modelling language.

UML is used to' specify, visualize, construct, and document the artifacts of a software system

UML is not a programming language. Some CASE Tools such as Rational Rose can provide

code generators from UML into a variety of programming languages, as well as construct

reverse engineered models from existing programs.

Page 395: C++ Book

The UML is a Language: Who provides a vocabulary and the rules for combining words in

that vocabulary for the purpose of communication. A modelling language is a language

whose vocabulary and rules focus on the conceptual and physical representation of a system.

A modelling language such as the UML is thus a standard language for software blueprints.

There are Four Kinds of Things in the UML as follows:

Structural things

Behavioural things

Grouping things

Annotational things

Question

1. Explain the concept of UML?

2. Explain Its scope and Goal

3. Discuss UML things

Page 396: C++ Book

UNIT V

LESSON 42

UML IIObjective

UML diagrams

UML relationships

Object Oriented Software Engineering

UML Diagrams

This part introduces you to the 9 standard diagrams in the UML 1.4 specification. These diagrams

can be divided into two groups: Structural diagrams, which model the organization of the solution,

and Behavioral diagrams, which model the functionality of the solution.

Structural Diagrams

Class Diagram

Object Diagram

Component Diagram

Deployment Diagram

Behavioral Diagrams

Use Case Diagram

Sequence Diagram

Collaboration Diagram

Statechart Diagram

Page 397: C++ Book

Activity Diagram

Class Diagrams

Class diagrams identify the class structure of a system, including the properties and methods of each

class. Also depicted are the various relationships that can exist between classes, such as an

inheritance relationship. The Class diagram is one of the most widely used diagrams from the UML

specification. Part of the popularity of Class diagrams stems from the fact that many CASE tools,

such as Rational XDE, will auto-generate code in a variety of languages, including Java, C++, and

C#, from these models. These tools can synchronize models and code, reducing your workload, and

can also generate Class diagrams from object-oriented code, for those "code-then-design"

maintenance projects.

Notation

UML Notation

There are many different types of UML notation.  For this short presentation, a few types of notation

will be covered.  For a more complete description of the UML notation, you can refer to the UML

1.1 Notation Guide.  When beginning to use the UML, it is helpful to start with some basic notation

(e.g., class diagrams) and, then,  as you become more proficient, advanced UML notation can be

used.

The elements on a Class diagram are classes and the relationships between them Class

Classes are the building blocks in object-oriented programming. A Class is depicted using a

rectangle divided into three sections. The top section is the name of the Class. The middle section

defines the properties of the Class. The bottom section lists the methods of the class.

Association An Association is a generic relationship between two classes, and is modeled by a line

connecting the two classes. This line can be qualified with the type of relationship, and can also

feature multiplicity rules (eg. one-to-one, one-to-many, many-to-many) for the relationship.

Page 398: C++ Book

Composition If a class cannot exist by itself, and instead must be a member of another class, then

that class has a Composition relationship with the containing class. A Composition relationship is

indicated by a line with a filled diamond.

Dependency When a class uses another class, perhaps as a member variable or a parameter, and so

"depends" on that class, a Dependency relationship is formed. A Dependency relationship is

indicated by a dotted arrow.

Aggregation Aggregations indicate a whole-part relationship, and are known as "has-a" relationships. An Aggregation relationship is indicated by a line with a hollow diamond.

Generalization A Generalization relationship is the equivalent of an inheritance relationship in

object-oriented terms (an "is-a" relationship). A Generalization relationship is indicated by an arrow

with a hollow arrowhead pointing to the base, or "parent", class.

Consider the example of a veterinary system. Animals served, such as dogs and birds, are tracked along with their owners. The following diagram models a potential solution. Since dogs and birds are "a kind of" animal, we use a Generalization relationship.

To validate your model, you can apply real-world data into instances of the classes. In fact, there is a

diagram for precisely this task, the Object Diagram.

Class Diagram

Class diagrams represent the static structure of the classes and their relationships (e.g., inheritance, aggregation) in a system. A class icon is divided into three components—class name, attributes, and operations.

Page 399: C++ Book

The access modifier symbols  +, -, and # correspond respectively to public, private, and protected

access modifiers.

Realizes relationship from a class to an interface indicates that the class implements the operations

specified in the interface.

Associations represent relationships between instances of classes.  Each association has two roles;

each role is a direction on the association.

A role has multiplicity (an indication of how many objects may participate in a given relationship). 

Examples of multiplicity indicators are: 1 (Exactly one), * (0 to any positive integer), 1..* (1 to any

positive integer), 0..1 (0 or 1).

Constraint specifies conditions among model elements that must be maintained as true. Constraints

are shown using text enclosed in braces.

Generalization relationship is an association with a small triangle next to the class being inherited

from whereas an aggregation relationship is an association with a diamond next to the class

representing the aggregate.

 

 

Class diagrams can be used to document a Business Object Model and are widely used in both high-

level and low-level design documents.

From a Java perspective, it may not be effective to include each and every operation and attribute of

a class in a class diagram because this leads to maintenance issues (e.g., if a method or attribute

changes in the code then the model needs to be updated); rather, javadoc can be used to document an

implementation.

To maintain consistency with Java coding style, class names should begin with an uppercase letter

while operations and attributes should begin with a lowercase letter.

Generalization relationships can be mapped to the Java extends relationship while the realizes

relationship can be mapped to the Java implements relationship.

Page 400: C++ Book

Package Diagram

Package diagrams provide a mechanism for dividing and grouping model elements (e.g., classes, use

cases). In UML, a package is represented as a folder.

In effect, a package provides a namespace such that two different elements in two different packages

can have the same name.

Packages may be nested within other packages.

Dependencies between two packages reflect dependencies between any two classes in the packages.

For example, if a class in Package A uses the services of a class in Package B, Package A is

dependent on Package B.  An important design consideration is the minimization of dependencies

between packages.

 

 

Page 401: C++ Book

 

Package diagrams can be used in a high-level design or architecture document to describe a system’s

overall structure, can support project planning and also be used as a unit to perform testing.

A package can be considered logically equivalent to a Java package and dependencies between

packages can be mapped to Java import statements.

Use Case Diagram

Use cases are used to obtain system requirements from a user's perspective. A use case can be

described as a interaction that a user has with a system to achieve a goal.    It is helpful to provide a

template that can be used to document use cases.  Note that a use case template is not part of the

UML notation   A typical use case can be documented using the following template:

 

A use case diagram provides an overview of the system's use cases and their actors; it places use

cases in context.  In UML, an actor is represented as a stickman while a use case is represented as an

oval.

An actor is a role that a user plays with respect to the system.

Two types of relationships are used in use case diagrams.

The extends relationship is used when one use case is similar to another use case but does a bit more

or to describe optional behavior (e.g., forward a mail message).

The uses relationship occurs when you have common behavior that exists in multiple use cases that

can be factored out into a separate use case (e.g., login use case).  Note that actors have relationships

to use cases that are being extended whereas there is often no actor associated with a common use

case.

 

Page 402: C++ Book

 

 

 

Use case diagrams can be used in product specifications, software architecture documents, and

system test documents to provide an overview of the system requirements.

Use cases can specify prioritization that can support a phased delivery of a system.

Use cases can also be used to develop test plans and user guides.

Interaction Diagrams: Sequence and Collaboration

Interaction diagrams show how objects interact with one another. There are two types of interaction

diagrams: Collaboration Diagram and Sequence Diagram.

Page 403: C++ Book

Collaboration diagrams can be used to show how objects in a system interact over multiple use

cases. Collaboration diagrams are helpful during the exploratory phases of a development process

(i.e., trying to search for objects and their relationships). Since there is no explicit representation of

time in Collaboration Diagrams, the messages are numbered to denote the sending order.

 

 

 

A Sequence diagram is typically used to show object interactions in a single use case and it is easier

to see the order in which activities occur. The emphasis of sequence diagrams is on the order of

message invocation. The vertical axis of a sequence diagram represents time whereas the horizontal

axis represents objects.

 

 

Page 404: C++ Book

 

Interaction diagrams can be used during the high-level design (e.g., for business object model

development) as well as for low-level design activities (e.g., developing an implementation for a use

case). Interaction diagrams are helpful for showing the collaborations between objects but fall short

in terms of a complete definition of the behavior.

Activity Diagrams

Activity diagrams show behavior with control structure. Activity diagrams can be used to show

behaviors over many use case, model business workflows, or describe complicated methods.

Activities in a diagram may or may not correspond to methods.

Specific notation found in this type of diagram includes guards which are logical expressions that

evaluate to true or false.

A synchronization bar indicates that the outbound trigger occurs only after all inbound triggers have occurred.

Page 405: C++ Book

Swimlanes (using a swimming pool analogy) allow you to vertically partition an activity diagram so

that the activities in each lane represent the responsibilities of a particular class or department.

 

 

Activity diagrams are helpful early in the modeling of a process to help you understand the overall

process.   Useful when you want to show parallel processes or  for multithreaded programs.

Page 406: C++ Book

Disadvantage of activity diagrams is that they do not make explicit which objects execute which

activities, and the way that the messaging works between them.

Relationships in UML

Dependency

The most general is called a dependency relationship and applies uniformly to all the model

elements. Association and generalization apply to all types, in particular classes and use cases. The

last two relationships – transitions and links – apply to certain model elements pertaining to

behavior.

This section is limited to the description of static relationships between classes, shown in the

diagram below. Links and transitions are discussed later on in this chapter.

Simplified metamodelà ‚ — representation of relationships between classes

Association

An association specifies a bi-directional, semantic connection between types. An association has at

least two roles, which describe the part played by the types that participate in the association.

Page 407: C++ Book

Each role comprises the following attributes:

Multiplicity – specifies the number of instances that participate in the relationship

Navigability – specifies if links (association instances) may be navigated along in the direction of

the role being considered.

Aggregation indicator – specifies if the instances of the type associated to the role correspond to

the whole in a (whole, part) relationship. Only one of the roles of an association may have an

aggregation indicator set to True. If the multiplicity is larger than 1, several instances play the role

of the whole and share the parts.

Changeability – specifies if the semantics of the association are preserved when an instance of the

type that participates in the role is replaced by another instance

Ordering – applies when the multiplicity value is greater than 1, to mean that the instances are

ordered

An association role may also include a set of attributes whose values implement a partition of the set

of objects of the associated class.

Generalization

Generalization specifies a classification relationship in which an instance of a subtype may be

substituted for an instance of a supertype. A supertype may have several subtypes, and a subtype

may have several supertypes.

Page 408: C++ Book

Simplified metamodel—representation of the generalization relationship and of

elements prone to generalization.

Any element that may be generalized includes the following Boolean attributes:

Abstract – the value True specifies that the element cannot be instantiated directly

Leaf – the value True specifies that the element may not have subtypes

Root – the value True specifies that the element may not have supertypes

UML defines three kinds of generalizable elements:

Stereotypes allow the classification of a model element and, eventually, the definition of a particular

graphical representation. A stereotype cannot have a subtype.

Packages provide a general mechanism for grouping elements (both model and visual elements). A

package cannot have supertypes.

Types specify a definition domain and the operations applicable to that domain.

Dependency

Dependency is a unidirectional usage relationship between elements (both model and visual). The

dependency relationship connects elements within the same model.

Simplified metamodel—representation of dependency relationships

Page 409: C++ Book

UML also provides a 'trace' relationship between elements that belong to different models. Notably,

the trace may be used to represent the history of current constructions in various models. This trace

relationship is a stereotyped dependency relationship.

Simplified metamodel—the trace relationship is a stereotyped dependency relationship.

UML is a consistent language for denoting the artifacts of a system. System architects can use it to

specify, visualize, construct and document designs. The language is most commonly used to denote

the artifacts of software systems, as a part of the software development process.

The Unified Modeling Language includes:

Model elements, that capture the fundamental modeling concepts and semantics.

A notation, for visual rendering of model elements.

Rules, that describes idioms of usage.

It also provides extensibility and specialization mechanisms to extend the core concepts.

UML does not provide, define nor dictate:

A Programming Language. UML has a semantics model that maps well to a family of OO

languages, but in itself does not require the use of a specific language tools. UML neither specifies

the design of CASE tools, nor specifies the use of them. However, it is natural to expect that CASE

tools supporting UML follows the UML semantics closely.

A development process. Defining a standard process was not a goal of UML, and UML has

intentionally been made process independent.

Page 410: C++ Book

Object oriented software engineering

Object-Oriented Concepts And Princlples

we live in a world of objects. these objects exist in nature, in humanmade entities, in business, and in

the products that we use. they can be categorized, described, organized, combined, manipulated, and

created. therefore, it is no surprise that an object-oriented view would be proposed for the creation of

computer software-an abstraction that enables us to model the world in ways that help us to better

understand and navigate it.

an object-oriented approach to the development of software was first proposed in the late 1960s.

however, it took almost 20 years for object technologies to become widely used. throughout the

1990s, object-oriented software engineering became the paradigm of choice for many software

product builders and a growing number of information systems and engineering professionals. as

time passes, object technologies are replacing classical software development approaches. an

important question is why?

the answer (like many answers to questions about software engineering) is not a simple one. some

people would argue that software professionals simply yearned for a "new" approach, but that view

is overly simplistic. object technologies do lead to a number of inherent benefits that provide

advantage at both the management and technical levels.

what is it? there are many ways to look at a problem to be

solved using a software-based

solution. One widely used approach to problem solving takes an object-oriented viewpoint. The

problem domain is characterized as a set of objects that have specific attributes and behaviors. The

objects are manipulated with a collection of func

tions (called methods, operations, or services) and communicate with one another through a mes-

saging protocol. Objects are categorized into classes and subclasses.

Who does It? The definition of objects encompasses a description of attributes, behaviors,

operations, and messages. This activity is performed by a sOftware engineer.

Why is it important? An object encapsulates both data and the processing that is applied to the data.

This important characteristic enables classes of objects to be built and inherently leads to libraries of

Page 411: C++ Book

reusable classes and objects. Because reuse is a critically important attribute of modern software

engineering, the object-oriented paradigm is attractive to many software development organizations.

In addition, the software components derived using the object-oriented paradigm exhibit design

characteristics (e.g., functional independence, information hiding) that are associated with high-

quality software.

What are the steps? Object-orientect software engineering follows the same steps as conventional

approaches. Analysis identifies objects and classesdomain; design provides the architecture,

interface, and component-level detail; that are relevant to the problem implementation (using an

object-oriented language) transforms design into code; and testing exercises the object-oriented

architecture, interfaces and components.

What is the work product? A set of object oriented models is produced. These models describe the

requirements, design. code. and test process a system or product.

How do I ensure that I've done It right? At each stage, object-oriented work products are reviewed

for clarity, correctness, completeness. and corm tency with customer requirements and with one

another.

Object technologies lead to reuse, and reuse (of program components) leads to faster software

development and higher-quality programs. Object-oriented software is easier to maintain because its

structure is inherently decoupled. This leads to fewer side effects when changes have to be made and

less frustration for the software engineer and the customer. In addition, object-oriented systems are

easier to adapt and easier to scale (ie., large systems can be created by assembling reusable sub sys

tems).

Page 412: C++ Book

Three important concepts differentiate the OO approach from conventional software engineering.

Encapsulation packages data and the operation that manipulate the data into single

named object.

Inheritance enables the attribute and operations to be inherited by all subclasses and

the objects that are instantiated from them.

Polymorphism enables a number of different operations to have the same name,

reducing the number of lines of code required to implement a system and facilitating

changes when they are made.

Object oriented product and systems are engineered using and evolutionary model, sometimes called

a recursive/ parallel model. OO software evolves iteratively and must be managed with the

recognition that the final product will be developed over a series of increments

Summary

UML is a modeling language for specifying, visualizing, constructing, and documenting the

artifacts of a system-intensive process.

UML represents a unification of the concepts and notations of Booch, Rumbaugh, and

Jacobson.

Notation plays an important role in modeling and the goal of the UML is to become a

universal notation for creating models of object-oriented (OO) software.

UML gives 9 standard diagrams These diagrams can be divided into two groups: Structural

diagrams, which model the organization of the solution, and Behavioral diagrams, which

model the functionality of the solution.

Questions

1. What is UML?

2. Explain different types of UML diagram. Give details of different notatios

used .

3. Discuss concept OO software Engineering

Page 413: C++ Book

UNIT V

Lession 43

Group Discussion on the concept of analysis ans design method and

UML concepts in Detail.

Page 414: C++ Book

References :

1. Object Oriented Progarmming With C++ - E Balguruswami

2. Let’s C++ - Y. Kanetkar

3. Object Oriented Modelling & Design- S.D. Joshi

4. C++ How To Program – Deitel & Deitel