0% found this document useful (0 votes)
210 views110 pages

I MSC CS Ooad

Uploaded by

kavijay3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
210 views110 pages

I MSC CS Ooad

Uploaded by

kavijay3
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 110

OBJECT ORIENTED ANALYSIS AND DESIGN & C++

(For M.Sc (CS), Semester-I)


UNIT – I..................................................................................................................................... 1
1.1 THE OBJECT MODEL ................................................................................................... 1
1.2 THE EVALUATION OF THE OBJECT MODEL ......................................................... 1
1.3 FOUNDATION OF THE OBJECT MODEL.................................................................. 8
1.4 ELEMENTS OF THE OBJECT MODEL ..................................................................... 11
1.5 APPLYING THE OBJECT MODEL ............................................................................ 16
1.6 CLASSES AND OBJECTS ........................................................................................... 17
1.6.1 THE NATURE OF AN OBJECT ........................................................................... 17
1.6.2 RELATIONSHIP AMONG OBJECTS .................................................................. 19
UNIT – II ................................................................................................................................. 21
2.1 THE NATURE OF A CLASS ....................................................................................... 21
2.2 RELATIONSHIP AMONG CLASSES......................................................................... 21
2.3 THE INTERPLAY OF CLASS AND OBJECTS ......................................................... 23
2.4 ON BUILDING QUALITY CLASSES AND OBJECTS ........................................... 23
2.5 CLASSIFICATION ....................................................................................................... 26
2.5.1 THE IMPORTANCE OF PROPER CLASSIFICATIONS .................................... 26
2.5.2 IDENTIFYING CLASSES AND OBJECTS ......................................................... 27
2.5.3 KEY ABSTRACTION AND MECHANISM ........................................................ 28
UNIT III ................................................................................................................................... 33
3.1 C++ INTRODUCTION ................................................................................................. 33
3.2 INPUT/OUTPUT STATEMENTS IN C++ .................................................................. 34
3.2.1 I/O LIBRARY HEADER FILES ............................................................................ 34
3.2.2 STANDARD OUTPUT STREAM (COUT) .......................................................... 35
3.2.3 STANDARD INPUT STREAM (CIN) .................................................................. 35
3.2.4 THE STANDARD ERROR STREAM (CERR) .................................................... 36
3.3 CONTROL STRUCTURE ............................................................................................ 37
3.3.1 SIMPLE IF STATEMENT ................................................................................... 38
3.4 C++ FUNCTIONS ......................................................................................................... 39
UNIT-IV .................................................................................................................................. 42
4.1 CLASSES AND OBJECTS ........................................................................................... 42
4.2 CONSTRUCTORS AND DESTRUCTORS ................................................................. 55
4.3 OPERATOR OVERLOADING AND TYPE CONVERSIONS ................................... 65
4.4 DEFINING OPERATOR OVERLOADING ................................................................ 66
4.5 OVERLOADING UNARY OPERATORS ................................................................... 67
4.6 OVERLOADING BINARY OPERATORS .................................................................. 68
4.7 OVERLOADING BINARY OPERATOR USING FRIENDS ..................................... 69
4.8 MANIPULATION OF STRINGS USING OPERATORS............................................ 70
4.9 RULES FOR OVERLOADING OPERATORS ............................................................ 70
4.10 ONE CLASS TO ANOTHER CLASS TYPE ............................................................. 72
4.11 INHERITANCE........................................................................................................... 73
4.11.1 DERIVED CLASSES ........................................................................................... 74
4.11.2 SINGLE INHERITANCE .................................................................................... 75
4.11.3 MULTILEVEL INHERITANCE ......................................................................... 76
4.11.4 MULTIPLE INHERITANCE ............................................................................... 77
4.11.5 HIERARCHICAL INHERITANCE ..................................................................... 80
4.11.6 HYBRID INHERITANCE ................................................................................... 81
4.12 POINTERS AND ARRAYS........................................................................................ 84
UNIT-V .................................................................................................................................... 86
5.1 MEMORY MANAGEMENT OPERATORS ............................................................... 86
5.1.1 MEMORY MANAGEMENT OPERATORS ........................................................ 86
5.1.2 NEW OPERATOR ................................................................................................. 86
5.1.3 DELETE OPERATOR ........................................................................................... 88
5.2 POLYMORPHISM ........................................................................................................ 89
5.3 VIRTUAL FUNCTIONS............................................................................................... 93
5.3.1 PURE VIRTUAL FUNCTIONS ............................................................................ 95
5.4 C++ Files........................................................................................................................ 95
5.5 C++ Exception Handling ............................................................................................... 97
5.6 C++ TEMPLATES ........................................................................................................ 99
MODEL QUESTION PAPER ........................................................................................... 102
OBJECTIVE QUESTIONS ............................................................................................... 104

SYLLABUS
Unit – I
Basics of Python Programming: History of Python-Features of Python-Literal-
Constants-Variables - Identifiers–Keywords-Built-in Data Types-Output Statements
– Input Statements-Comments – Indentation- Operators-Expressions-Type
conversions. Python Arrays: Defining and Processing Arrays – Array methods.
Unit – II
Control Statements: Selection/Conditional Branching statements: if, if-else,
nested if and if-elif-else statements. Iterative Statements: while loop, for loop, else
suite in loop and nested loops. Jump Statements: break, continue and pass
statements.
Unit – III
Functions: Function Definition – Function Call – Variable Scope and its
Lifetime-Return Statement. Function Arguments: Required Arguments, Keyword
Arguments, Default Arguments and Variable Length Arguments- Recursion. Python
Strings: String operations- Immutable Strings - Built-in String Methods and
Functions - String Comparison. Modules: import statement- The Python module –
dir() function – Modules and Namespace – Defining our own modules.
Unit – IV
Lists: Creating a list -Access values in List-Updating values in Lists-Nested
lists -Basic list operations-List Methods. Tuples: Creating, Accessing, Updating and
Deleting Elements in a tuple – Nested tuples– Difference between lists and tuples.
Dictionaries: Creating, Accessing, Updating and Deleting Elements in a Dictionary –
Dictionary Functions and Methods - Difference between Lists and Dictionaries.
Unit – V
Python File Handling: Types of files in Python - Opening and Closing files-
Reading and Writing files: write() and writelines() methods- append() method –
read() and readlines() methods – with keyword – Splitting words – File methods -
File Positions- Renaming and deleting files.

Text Book
1. Reema Thareja, “Python Programming using problem solving approach”, First Edition,
2017, Oxford University Press.
2. Dr. R. Nageswara Rao, “Core Python Programming”, First Edition, 2017, Dream tech
Publishers.
Reference Book
1. VamsiKurama, “Python Programming: A Modern Approach”, Pearson Education.
2. Mark Lutz, ”Learning Python”, Orielly.
3. Adam Stewarts, “Python Programming”, Online.
4. Fabio Nelli, “Python Data Analytics”, APress.
5. Kenneth A. Lambert, “Fundamentals of Python – First Programs”, CENGAGE
Publication.
UNIT – I

1.1 THE OBJECT MODEL

Object-oriented technology is built upon a sound engineering foundation, whose


elements we collectively call the object model. The object model encompasses the principles
of abstraction, encapsulation, modularity, hierarchy, typing, concurrency, and persistence. By
themselves, none of these principles are new. What is important about the object model is
that these elements are brought together in a synergistic way.
Let there be no doubt that object-oriented analysis and design is fundamentally
different than traditional structured design approaches: it requires a different way of thinking
about decomposition, and it produces software architectures that are largely outside the realm
of the structured design culture. These differences arise from the fact that structured design
methods build upon structured programming, whereas object-oriented design builds upon
object-oriented programming. Unfortunately, object-oriented programming means different
things to different people.

1.2 THE EVALUATION OF THE OBJECT MODEL

Trends in Software Engineering


The Generations of Programming Languages As we look back upon the relatively
brief yet colorful history of software engineering, we cannot help but notice two sweeping
trends:
• The shift in focus from programming-in-the-small to programming-in-the-large
• The evolution of high-order programming languages
Most new industrial-strength software systems are larger and more complex than their
predecessors were even just a few years ago. This growth in complexity has prompted a
significant amount of useful applied research in software engineering, particularly with
regard to decomposition, abstraction, and hierarchy.
The development of more expressive programming languages has complemented these
advances. The trend has been a move away from languages that tell the computer what to do
(imperative languages) toward languages that describe the key abstractions in the problem
domain (declarative languages).

1
Wegner has classified some of the more popular high-order programming languages in
generations arranged according to the language features they first introduced:
• First-Generation Languages (1954-1958)
o FORTRANI Mathematical expressions
o ALGOL 58 Mathematical expressions
o Flowmatic Mathematical expressions
o IPL V Mathematical expressions
• Second-Generation Languages (1959~1961)
o FORTRANII Subroutines, separate compilation
o ALGOL 60 Block structure, data types
o COBOL Data description, file handling
o Lisp List processing, pointers, garbage collection
• Third-Generation Languages (1962-1970)
o PL/1 FORTRAN + ALGOL + COBOL
o ALGOL 68 Rigorous successor to ALGOL 60
o Pascal Simple successor to ALGOL 60
o Simula Classes, data abstraction
• The Generation Gap (1970-1980)
Many different languages were invented, but few endured.
In successive generations, the kind of abstraction mechanism each language supported
changed.
First-generation languages were used primarily for scientific and engineering
applications, and the vocabulary of this problem domain was almost entirely mathematics.
Languages such as FORTRAN 1 were thus developed to allow the programmer to write
mathematical formulas, thereby freeing the programmer from some of the intricacies of
assembly or machine language.
This first generation of high-order programming languages therefore represented a
step closer to the problem space, and a step further away from the underlying machine.
Among second-generation languages, the emphasis was upon algorithmic abstractions. By
this time, machines were becoming more and more powerful, and the economics of the
computer industry meant that more kinds of problems could be automated, especially for
business applications.
Now, the focus was largely upon telling the machine what to do: read these personnel
records first, sort them next, and then print this report. Again, this new generation of high-

2
order programming languages moved us a step closer to the problem space, and further away
from the underlying machine. By the late 1960s, especially with the advent of transistors and
then integrated circuit technology, the cost of computer hardware had dropped dramatically,
yet processing capacity had grown almost exponentially.
Larger problems could now be solved, but these demanded the manipulation of more
kinds of data, Thus, languages such as ALGOL 60 and, later, Pascal evolved with support for
data abstraction. Now a programmer could describe the meaning of related kinds of data
(their type) and let the programming language enforce these design decisions. This generation
of high-order programming languages again moved our software a step closer to the problem
domain, and further away from the underlying machine.
The 1970s provided us with a frenzy of activity in programming language research,
resulting in the creation of literally a couple of thousand different programming languages
and their dialects. To a large extent, the drive to write larger and larger programs highlighted
the inadequacies of earlier languages; thus, many new language mechanisms were developed
to address these limitations.

Figure 2.1.The Topology of First- and Early Second-Generation Programming Languages


CLOS (which evolved from Lisp, LOOPS, and Flavors), C++ (derived from a
marriage of C and Simula), and Eiffel (derived from Simula and Ada). What is of the greatest
interest to us is the class of languages we call object-based and object-oriented. Object-based
and object oriented programming languages best support the object-oriented decomposition
of software.
The Topology of First- and Early Second-Generation Programming Languages to
show precisely what we mean, let's study the structure of each generation of programming
languages. we see the topology of most first-and early second-generation programming
languages. By topology, we mean the basic physical building blocks of the language and how

3
those parts can be connected. In this figure, we see that for languages such as FORTRAN and
COBOL, the basic physical building block of all applications is the subprogram (or the
paragraph, for those who speak COBOL).
Applications written in these languages exhibit a relatively flat physical structure,
consisting only of global data and subprograms. The arrows in this figure indicate
dependencies of the subprograms on various data. During design, one can logically separate
different kinds of data from one another, but there is little in these languages that can enforce
these design decisions.
An error in one part of a program can have a devastating ripple effect across the rest
of the system, because the global data structures are exposed for all subprograms to see.
When modifications are made to a large system, it is difficult to maintain the integrity of the
original design.
The Topology of Late Second- and Early Third-Generation Programming Languages
By the mid-1960s, programs were finally being recognized as important intermediate points
between the problem and the computer. As Shaw points out, "The first software abstraction,
now called the 'procedural' abstraction, grew directly out of this pragmatic view of software .
Subprograms were invented prior to 1950, but were not fully appreciated as abstractions at
the time. Instead, they were

Originally seen as labor-saving devices. Very quickly though, subprograms were


appreciated as a way to abstract program functions".
The realization that subprograms could serve as an abstraction mechanism had three
important consequences.
First, languages were invented that supported a variety of parameter passing
mechanisms. Second, the foundations of structured programming were laid, manifesting

4
themselves in language support for the nesting of subprograms and the development of
theories regarding control structures and the scope and visibility of declarations.
Third, structured design methods emerged, offering guidance to designers trying to
build large systems using subprograms as basic physical building blocks. Thus, it is not
surprising, as Figure 2-2 shows, that the topology of late second- and early third generation
languages is largely a variation on the theme of earlier generations.
The Topology of Late Third-Generation Programming Languages Starting with
FORTRAN II, and appearing in most late third-generation program languages, another
important structuring mechanism evolved to address the growing issues of programming-in
the- large.

Larger programming projects meant larger development teams, and thus the need to
develop different parts of the same program independently. The answer to this need was the
separately compiled module, which in its early conception was little more than an arbitrary
container for data and subprograms, as Figure 2-3 shows.
Modules were rarely recognized as an important abstraction mechanism; in practice
they were used simply to group subprograms that were most likely to change together. Most
languages of this generation, while supporting some sort of modular structure, had few rules
that required semantic consistency among module interfaces.
A developer writing a subprogram for one module might assume that it would be
called with three different parameters: a floating-point number, an array of ten elements, and
an integer representing a Boolean flag.

5
In another module, a call to this subprogram might incorrectly use actual parameters
that: violated these assumptions: an integer, an array of five elements, and a negative number.
Similarly, one module might use a block of common data which it assumed as its own, and
another module might violate these assumptions by directly manipulating this data.
Unfortunately, because most of these languages had dismal support for data abstraction and
strong typing, such errors could be detected only during execution of the program.
The Topology of Object-Based and Object-Oriented Programming Languages The
importance of data abstraction to mastering complexity is clearly stated by Shankar: "The
nature of abstractions that may be achieved through the use of procedures is well suited to the
description of abstract operations, but is not particularly well suited to the description of
abstract objects. This is a serious drawback, for in many applications, the complexity of the
data objects to be manipulated contributes substantially to the overall complexity of the
problem. This realization had two important consequences.

First, data-driven design methods emerged, which provided a disciplined approach to


the problems of doing data abstraction in algorithmically oriented languages. Second,
theories regarding the concept of a type appeared which eventually found their realization in
languages such as Pascal.
The natural conclusion of these ideas first appeared in the language Simula and was
improved upon during the period of the language generation gap, resulting in the relatively
recent development of several languages such as -Smalltalk, Object Pascal, C++, CLOS, Ada,
and Eiffel. For reasons that we will explain shortly, these languages are called object-based or

6
object-oriented. Figure 2-4 illustrates the topology of these languages for small- to moderate
sized applications.
The physical building block in these languages is the module, which represents a
logical collection of classes and objects instead of subprograms, as in earlier languages. To
state it another way, "lf procedures and functions are verbs and pieces of data are nouns, a
procedure-oriented program is organized around verbs while an object-oriented program is
organized around nouns". For this reason, the physical structure of a small to moderate-sized
object-oriented application appears as a graph, not as a tree, which is typical of
algorithmically oriented languages. Additionally, there is little or no global data.

Instead, data and operations are united in such a way that the fundamental logical
building blocks of our systems are no longer algorithms, but instead are classes and objects.
By now we have progressed beyond programming-in-the-large and must cope with
programming-in-the-colossal. For very complex systems, we find that classes, objects, and
modules provide an essential yet insufficient means of abstraction. Fortunately, the object
model scales up.
In large systems, we find clusters of abstractions built in layers on top of one another.
At any given level of abstraction, we find meaningful collections of objects that collaborate

7
to achieve some higher-level behavior. If we look inside any given cluster to view its
implementation, we unveil yet another set of cooperative abstractions.

1.3 FOUNDATION OF THE OBJECT MODEL

Structured design methods evolved to guide developers who were trying to build
complex systems using algorithms as their fundamental building blocks.
Similarly, object-oriented design methods have evolved to help developers exploit
the expressive power of object-based and object-oriented programming languages, using the
class and object as basic building blocks.
Actually, the object model has been influenced by a number of factors, not just object-
oriented programming. Indeed, as the sidebar further discusses, the object model has proven
to be a unifying concept in computer science, applicable not just to programming languages,
but also to the design of user interfaces, databases, and even computer architectures.
The reason for this widespread appeal is simply that an object orientation helps us to
cope with the complexity inherent in many different kinds of systems.
Object-oriented analysis and design thus represents an evolutionary development, not a
revolutionary one; it does not break with advances from the past, but builds upon proven
ones. Unfortunately, most programmers today are formally and informally trained only in the
principles of structured design. Certainly, many good engineers have developed and deployed
countless useful software systems using these techniques. However, there are limits to the
amount of complexity we can handle using only algorithmic decomposition; thus we must
turn to object-oriented decomposition. Furthermore, if we try to use languages such as C++
and Ada as if they were only traditional, algorithmically oriented languages, we not only miss
the power available to us, but we usually end up worse off than if we had used an older
language such as C or Pascal.
Give a power drill to a carpenter who knows nothing about electricity, and he would
use it as a hammer. He will end up bending quite a few nails and smashing several fingers,
for a power drill makes a lousy hammer.
OOP, OOD, and OOA
Because the object model derives from so many- disparate sources, it has
unfortunately been accompanied by a muddle of terminology.

8
A Smalltalk programmer uses methods, a C++ programmer uses virtual member
functions, and a CLOS programmer uses generic functions. An Object Pascal programmer
talks of a type coercion; an Ada programmer calls the same thing a type conversion.
To minimize the confusion, let's define what is object-oriented and what is not. The
glossary provides a summary of all the terms described here, plus many others.
Bhaskar has observed that the phrase object-oriented "has been bandied about with
carefree abandon with much the same reverence accorded 'brotherhood,' 'apple pie,' and
'structured programming'. What we can agree upon is that the concept of an object is central
to anything object-oriented. In the previous chapter, we informally defined an object as a
tangible entity that exhibits some well-defined behavior.
Stefik and Bobrow define objects as "entities that combine the properties of
procedures and data since they perform computations and save local state". Defining objects
as entities begs the question somewhat, but the basic concept here is that objects serve to
unify the ideas of algorithmic and data abstraction. Jones further clarifies this term by noting
that "in the object model, emphasis is placed on crisply characterizing the components of the
physical or abstract system to be modeled by a programmed system. . . . Objects have a
certain 'integrity' which should not – in fact, cannot - be violated.
An object can only change state, behave, be manipulated, or stand in relation to other
objects in ways appropriate to that object. Stated differently, there exist invariant properties
that characterize an object and its behavior. An elevator, for example, is characterized by
invariant properties including [that] it only travels up and down inside its shaft. . . . Any
elevator simulation must incorporate these invariants, for they are integral to the notion of an
elevator”.
Object-Oriented Programming What then, is object-oriented programming (or OOP,
as it is sometimes written)? We define it as follows:
Object-oriented programming is a method of implementation in which programs are
organized as cooperative collections of objects, each of which represents an instance of some
class, and whose classes are all members of a hierarchy of classes united via inheritance
relationships.
There are three important parts to this definition: object-oriented programming
o Uses objects, not algorithms, as its fundamental logical building blocks
o Each object is an instance of some class; and
o Classes are related to one another via inheritance relationships

9
A program may appear to be object-oriented, but if any of these elements is missing,
it is not an object-oriented program. Specifically, programming without inheritance 'is
distinctly not object-oriented; we call it programming with abstract data types.
By this definition, some languages are object-oriented, and some are not. Stroustrup
suggests that: "if the term 'object-oriented language' means anything, it must mean a language
that has mechanisms that support the object-oriented style of programming well....
A language supports a programming style well if it provides facilities that make it
convenient to use that style. A language does not support a technique if it takes exceptional
effort or skill to write such programs; in that case, the language merely enables programmers
to use the techniques". From a theoretical perspective, one can fake object oriented
programming in non-object oriented programming languages like Pascal and even COBOL or
assembly language, but it is horribly ungainly to do so. Cardelli and Wegner thus say "that a
language is object-oriented if and only if it satisfies the following requirements:
• It supports objects that are data abstractions with an interface of named operations
and a hidden local state.
• Objects have an associated type [class].
• Types [classes] may inherit attributes from super types [super classes]".
For a language to support inheritance means that it is possible to express "is a"
relationships among types, for example, a red rose is a kind of flower, and a flower is a kind
of plant. If a language does not provide direct support for inheritance, then it is not object-
oriented. Cardelli and Wegner distinguish such languages by calling them object-based rather
than object-oriented.
Under this definition, Smalltalk, Object Pascal, C++, Eiffel, and CLOS are all object-
oriented, and Ada is object-based. However, since objects and classes are elements of both
kinds of languages, it is both possible and highly desirable for us to use object-oriented
design methods for both object-based and object-oriented programming languages.
Object-Oriented Design The emphasis in programming methods is primarily on the
proper and effective use of particular language mechanisms.
By contrast, design methods emphasize the proper and effective structuring of a
complex system. What then is object-oriented design? We suggest that Object-oriented
design is a method of design encompassing the process of object-oriented decomposition and
a notation for depicting logical and physical as well as static and dynamic models of the
system under design.

10
There are two important parts to this definition: object-oriented design (1) leads to an
object oriented decomposition and (2) uses different notations to express different models of
the logical (class and object structure) and physical (module and process architecture) design
of a system, in addition to the static and dynamic aspects of the system.
The support: for object-oriented decomposition is what makes object-oriented design
quite different from structured design: the former uses class and object abstractions to
logically structure systems, and the latter uses algorithmic abstractions.
We will use the term object oriented design to refer to any method that leads to an
object-oriented decomposition. We will occasionally use the acronym OOD to designate the
particular method of object-oriented design described in this book.
Object-Oriented Analysis The object model has influenced even earlier phases of the
software development life cycle.
Object-oriented analysis is a method of analysis that examines requirements from the
perspective of the classes and objects found in the vocabulary of the problem domain.
How are OOA, OOD, and OOP related? Basically, the products of object oriented
analysis serve as the models from which we may start an object-oriented design; the products
of object-oriented design can then be used as blueprints for completely implementing a
system using object-oriented programming methods.

1.4 ELEMENTS OF THE OBJECT MODEL

Kinds of Programming Paradigms Jenkins and Glasgow observe that "most


programmers work in one language and use only one programming style. They program in a
paradigm enforced by the language they use.
Frequently, they have not been exposed to alternate ways of thinking about a problem,
and hence have difficulty in seeing the ad-vantage of choosing a style more appropriate to the
problem at hand,’ Bobrow and Stefik define a programming style as "a way of organizing
programs on the basis of some conceptual model of programming and an appropriate
language to make programs written in the style clear”. They further suggest that there are five
main kinds of programming styles, here listed with the kinds of abstractions they employ:
• Procedure-oriented Algorithms
• Object-oriented Classes and objects
• Logic-oriented Goals, often expressed in a predicate calculus
• Rule-oriented If-then rules

11
• Constraint-oriented Invariant relationships
There is no single programming style that is best for all kinds of applications. For
example, rule-oriented programming would be best for the design of a knowledge base, and
procedure-oriented programming would be best suited for the design of computation-intense
operations. From our experience, the object-oriented style is best suited to the broadest set of
applications; indeed, this programming paradigm often serves as the architectural framework
in which we employ other paradigms.
Each of these styles of programming is based upon its own conceptual framework.
Each requires a different mindset, a different way of thinking about the problem. For all
things object-oriented, the conceptual framework is the object model. There are four major
elements of this model:
• Abstraction
• Encapsulation
• Modularity
• Hierarchy
By major, we mean that a model without any one of these elements is not object-
oriented. There are three minor elements of the object model:
• Typing
• Concurrency
• Persistence
By minor, we mean that each of these elements is a useful, but not essential, part of
the object model.
Without this conceptual framework, you may be programming in a language such as
Smalltalk, Object Pascal, C++, CLOS, Eiffel, or Ada, but your design is going to smell like a
FORTRAN, Pascal, or C application. You will have missed out on or otherwise abused the
expressive power of the object-oriented language you are using for implementation. More
importantly, you are not likely to have mastered the complexity of the problem at hand
Abstraction
The Meaning of Abstraction: Abstraction is one of the fundamental ways that we as
humans cope with complexity. Hoare suggests that "abstraction arises from recognition of
similarities between certain objects, situations, or processes in the real world, and the
decision to concentrate upon these similarities and to ignore for the time being the
differences".

12
Abstraction focuses upon the essential characteristics of some object, relative to the
perspective of the viewer.
Kinds of abstractions include the following:
Entity abstraction
An object that represents a useful model of a problem domain or solution-domain
entity
Action abstraction
An object that provides a generalized set of operations, all of which perform the same
kind of function
Virtual machine abstraction
An object that groups together operations that are all used by some superior level of
control, or operations that all use some junior-level set of operations
Coincidental abstraction
An object that: packages a set of operations that have no relation to each other We
strive to build entity abstractions, because they directly parallel the vocabulary of a given
problem domain.
Encapsulation
Encapsulation hides the details of the implementation of an object.
Abstraction and encapsulation are complementary concepts: abstraction focuses upon the
observable behavior of an object, whereas encapsulation focuses upon the implementation
that gives rise to this behavior.
Encapsulation is most often achieved through information biding, which is the
process of hiding all the secrets of an object that do not contribute to its essential
characteristics; typically, the structure of an object is hidden, as well as the ,implementation
of its methods.
Encapsulation provides explicit barriers among different abstractions and thus leads to
a clear separation of concerns.
Modularity
The Meaning of Modularity as Myers observes, "The act of partitioning a program
into individual components can reduce its complexity to some degree although partitioning a
program is helpful for this reason, a more powerful justification for partitioning a program is
that it creates a number of well defined, documented boundaries within the program.
These boundaries, or interfaces, are invaluable in the comprehension of the program".
Modularity packages abstractions into discrete units.

13
Modularity is the property of a system that has been decomposed into a set of
cohesive and loosely coupled modules.
Thus, the principles of abstraction, encapsulation, and modularity are An object
provides a crisp boundary around a single abstraction, and both encapsulation and modularity
provide barriers around this abstraction.
Hierarchy
The Meaning of Hierarchy Abstraction is a good thing, but in all except the most
trivial applications, we may find many more different abstractions than we can comprehend
at one time.
Encapsulation helps manage this complexity by hiding the inside view of our
abstractions. Modularity helps also, by giving us a way to cluster logically related
abstractions. Still, this is not enough.
A set of abstractions often forms a hierarchy, and by identifying these hierarchies in
our ,design, we greatly simplify our understanding of the problem. We define hierarchy as
follows: The most important hierarchies in a complex system are its class structure e "is a"
hierarchy) and its object structure (the "part of' hierarchy).
Typing
Meaning of Typing: The concept of a type derives primarily from the theories of
abstract data types. As Deutsch suggests, "A type is a precise characterization of structural or
behavioral properties which a collection of entities all share". For our purposes, we will use
the terms type and class interchangeably9. Although the concepts of a type and a class are
similar, we include typing as a separate element of the object model because the concept of a
type places a very different emphasis upon the meaning of abstraction. Specifically, we state
the following:
Typing is the enforcement of the class of an object, such that objects of different types
may not be interchanged, or at the most, they may be interchanged only in very restricted
ways.
Strong typing prevents mixing abstractions.
Typing lets we express our abstractions so that the programming language in which
we implement them can be made to enforce design decisions. Wegner observes that this kind
of enforcement is essential for programming-in-the-large. The idea of conformance is central
to the notion of typing. For example, consider units of measurement in physics. When we
divide distance by time, we expect some value denoting speed, not weight. Similarly,
multiplying temperature by a unit of force doesn't make sense, but multiplying mass by force

14
does. These are both examples of strong typing, wherein the rules of our domain prescribe
and enforce certain legal combinations of abstractions.
Concurrency
The Meaning of Concurrency For certain kinds of problems, an automated system
may have to handle many different events simultaneously. Other problems may involve so
much computation that they exceed the capacity of any single processor. In each of these
cases, it is natural to consider using a distributed set of computers for the target
implementation or to use processors capable of multitasking.
A single process - also known as a thread of control is the root from which
independent dynamic action occurs within a system. Every program has at least one thread of
control, but a system involving concurrency may have many such threads: some that are
transitory, and others that last the entire lifetime of the system's execution. Systems executing
across multiple CPUs allow for truly concurrent threads of control, whereas systems running
on a single CPU can only achieve the illusion of concurrent threads of control, usually by
means of sometime-slicing algorithm. Concurrency allows different objects to act at the same
time.
Persistence
An object in software takes up some amount of space and exists for a particular
amount of time. Atkinson et al. suggest that there is a continuum of object existence, ranging
from transitory objects that arise within the evaluation of an expression, to objects in a
database that outlive the execution of a single program. This spectrum of object persistence
encompasses the following:
• “Transient results in expression evaluation
• Local variables in procedure activations
• Own variables [as in ALGOL 60], global variables, and heap items whose extent is
different from their scope
• Data that exists between executions of a program
• Data that exists between various versions of a program
• Data that outlives the program"
Traditional programming languages usually address only the first three kinds of object
persistence; persistence of the last three kinds is typically the domain of database technology.
Persistence saves the state and class of an object across time or space. This leads to a clash of
cultures that sometimes results in very strange architectures: programmers end up crafting ad

15
hoc schemes for storing objects whose state must be preserved between program executions,
and database designers misapply their technology to cope with transient objects.

1.5 APPLYING THE OBJECT MODEL

Benefits of the Object Model


As we have shown, the object model is fundamentally different from the models
embraced by the more traditional methods of structured analysis, structured design, and
structured programming.
This does not mean that the object model abandons all of the sound principles and
experiences of these older methods. Rather, it introduces several novel elements that build
upon these earlier models.
Thus, the object model offers a number of significant benefits that other models
simply do not provide. Most importantly, the use of the object model leads us to construct
systems that embody the five attributes of well-structured complex systems.
In our experience, there are five other practical benefits to be derived from the
application of the object model.
First, the use of the object model helps us to exploit the expressive power of object-
based and object-oriented programming languages.
As Stroustrup points out, "lt is not always clear how best to take advantage of a
language such as C++. Significant improvements in productivity and code quality have
consistently been achieved using C++ as 'a better C’ with a bit of data abstraction thrown in
where it is clearly useful. However, further and noticeably larger improvements have been
achieved by taking advantage of class hierarchies in the design process.
This is often called object-oriented design and this is where the greatest benefits of
using C++ have been found". Our experience has been that, without the application of the
elements of the object model, the more powerful features of languages such as Smalltalk,
Object Pascal, C++, CLOS, and Ada are either ignored or greatly misused.
Next, the use of the object model encourages the reuse not only of software but of
entire designs, leading to the creation of reusable application frame-works. We have found
that object-oriented systems are often smaller than equivalent non-object-oriented
implementations. Not only does this mean less code to write and maintain, but greater reuse
of software also translates into cost and schedule benefits.

16
Third, the use of the object model produces systems that are built upon stable
intermediate forms, which are more resilient to change. This also means that such systems
can be allowed to evolve over time, rather than be abandoned or completely redesigned in
response to the first major change in requirements.
Applications of the Object Model
The object model has proven applicable to a wide variety of problem domains. Figure
2-6 lists many of the domains for which systems exist that may properly be called object-
oriented. The Bibliography provides an extensive list of references to these and other
applications.
Object-oriented analysis and design may be the only method we have today that can
be employed to attack the complexity inherent in very large systems. In all fairness, however,
the use of object-oriented development may be ill-advised for some domains, not for any
technical reasons, but for nontechnical ones, such as the absence of a suitably trained staff or
a good development environment.

1.6 CLASSES AND OBJECTS

Both the engineer and the artist must be intimately familiar with the materials of their
trade. When we use object-oriented methods to analyze or design a complex software system,
our basic building blocks are classes and objects.
Since we have thus far provided only informal definitions of these two elements, in
this chapter we turn to a detailed study of the nature of classes, objects, and their
relationships, and along the way provide several rules of thumb for crafting quality
abstractions and mechanisms.

1.6.1 THE NATURE OF AN OBJECT

What Is and What Isnt an Object


The ability to recognize physical objects is a skill that humans learn at a very early
age. A brightly colored ball will attract an infant's attention, but typically, if you hide the ball,
the child will not try to look for it; when the object leaves her field of vision, as far as she can
determine, it ceases to exist. It is not until near the age of one that a child normally develops
what is called the object concept, a skill that is of critical importance to future cognitive
development.

17
Show a ball to a one-year-old and then hide it, and she will usually search for it even
though it is not visible. Through the object concept, a child comes to realize that objects have
a permanence and identity apart from any operations upon them.
From the perspective of human cognition, an object is any of the following:
• A tangible and/or visible thing
• Something that may be apprehended intellectually
• Something toward which thought or action is directed
An object has state, exhibits some weii-defined behavior, and has a unique identity.
Some objects may be tangible, yet have fuzzy physical boundaries.
Objects such as rivers, fog, and crowds of people fit this definition13. Just as the
person holding a hammer tends to see everything in the world as a nail, so the developer with
an object-oriented mindset begins to think that everything in the world is an object.
This perspective is a little naive, because there are some things that are distinctly not
objects. For example, attributes such as time, beauty, or color are not objects, nor are
emotions such as love and anger. On the other hand, these things are all potentially properties
of other objects. For example, we might say that a man (an object) loves his wife (another
object), or that a particular cat (yet another object) is gray.
Thus, it is useful to say that an object is something that has crisply defined
boundaries, but this is not enough to guide us in distinguishing one object from another, nor
does it allow us to judge the quality of our abstractions. Our experience therefore suggests the
following definition:
An object has state, behavior, and identity; the structure and behavior of similar objects
are defined in their common class; the terms instance and object are interchangeable.
StateThe state of an object encompasses all of the (usually static) properties of the object plus
the current (usually dynamic) values of each of these properties.
Behavior
The Meaning of Behavior No object exists in isolation. Rather, objects are acted upon,
and themselves act upon other objects. Thus, we may say that Behavior is how an object acts
and reacts, in terms of its state changes and message passing.
Identity
Semantics Khoshafian and Copeland offer the following definition:
“Identity is that property of an object which distinguishes it from all other objects”

18
1.6.2 RELATIONSHIP AMONG OBJECTS

Kinds of Relationships
An object by itself is intensely uninteresting. Objects contribute to the behavior of a
system by collaborating with one another.
As Ingalls suggests, "Instead of a bit-grinding processor raping and plundering data
structures, we have a universe of well-behaved objects that courteously ask each other to
carry out their various desires". For example, consider the object structure of an airplane,
which has been defined as "a collection of parts having an inherent tendency to fall to earth,
and requiring constant effort and supervision to stave off that outcome". Only the
collaborative efforts of all the component objects of an airplane enable it to fly.
The relationship between any two objects encompasses the assumptions that each
makes about the other, including what operations can be performed and what behavior
results. We have found that two kinds of object hierarchies are of particular interest in object-
oriented analysis and design, namely:
• Links
• Aggregation
Links
The term link derives from Rumbaugh, who defines it as a "physical or conceptual
connection between objects".
An object collaborates with other objects through its links to these objects. Stated
another way, a link denotes the specific association through which one object (the client)
applies the services of another object (the supplier), or through which one object may
navigate to another.
As a participant in a link, an object may play one of three roles:
• Actor: An object that can operate upon other objects but is never operated upon by
other objects; in some contexts, the terms active object and actor are interchangeable
• Server: An object that never operates upon other objects; it is only operated upon by
other objects
• Agent: An object that can both operate upon other objects and be operated upon by
other objects; an agent is usually created to do some work on behalf of an actor or
another agent

19
Aggregation
• Sequential: The semantics of the passive object are guaranteed only in the presence of
a single active object at a time.
• Guarded: The semantics of the passive object are guaranteed in the presence of
multiple threads of control, but the active clients must collaborate to achieve mutual
exclusion.
• Synchronous: The semantics of the passive object are guaranteed in the presence of
multiple threads of control, and the supplier guarantees mutual exclusion.
Aggregation is sometimes better because it encapsulates parts as secrets of the whole.
Links are sometimes better because they permit looser coupling among objects. Intelligent
engineering decisions require careful weighing of these two factors.
By implication, an object that is an attribute of another has a link to its aggregate. Across
this link, the aggregate may send messages to its parts.

20
UNIT – II

2.1 THE NATURE OF A CLASS

What Is and What lsn't a Class


The concepts of a class and an object are tightly interwoven, for we cannot talk about
an object without regard for its class. However, there are important differences between these
two terms.
Whereas an object is a concrete entity that exists in time and space, a class represents
only an abstraction, the “essence" of an object, as it was. Thus, we may speak of the class
Mammal, which represents the characteristics common to all mammals. To identify a
particular mammal in this class, we must speak of "this mammal” or "that mammal."In
everyday terms, we may define a class as "a group, set, or kind marked by common attributes
or a common attribute; a group division, distinction, or rating based on quality, degree of
competence, or condition". In the context of object-oriented analysis and design, we define a
class as follows:
A class is a set of objects that share a common structure and a common behavior.A
single object is simply an instance of a class.A class represents a set of objects that share a
common structure and a common behavior.
What isn't a class? An object is not a class, although, curiously, as we will describe
later, a class may be an object. Objects that share no common structure and behavior cannot
be grouped in a class because, by definition, they are unrelated except by their general nature
as objects.

2.2 RELATIONSHIP AMONG CLASSES

Kinds of Relationships
Consider for a moment the similarities and differences among the following classes of
objects: flowers, daisies, red roses, yellow roses, petals, and ladybugs. We can make the
following observations:
• A daisy is a kind of flower.
• A rose is a (different) kind of flower.
• Red roses and yellow roses are both kinds of roses.
• A petal is a part of both kinds of flowers.

21
• Ladybugs eat certain pests such as aphids, which may be infesting certain kinds of
flowers.From this simple example we conclude that classes, like objects, do not exist
in isolation. Rather, for a particular problem domain, the key abstractions are usually
related in a variety of interesting ways, forming the class structure of our design.We
establish relationships between two classes for one of two reasons.
First, a class relationship might indicate some sort of sharing. For example, daisies
and roses are both kinds of flowers, meaning that both have brightly colored petals, both emit
a fragrance, and so on. Second, a class relationship might indicate some kind of semantic
connection.
Thus, we say that red roses and yellow roses are more alike than are daisies and roses,
and daisies and roses are more closely related than are petals and flowers. Similarly, there is a
symbiotic connection between ladybugs and flowers: ladybugs protect flowers from certain
pests, which in tum serve as a food source for the ladybug
In all, there are three basic kinds of class relationships. The first of these is
generalization/specialization, denoting an "is a" relationship. For instance, a rose is a kind of
flower, meaning that a rose is a specialized subclass of the more general class, flower.
The second is whole/part, which denotes a "part of" relationship. Thus, a petal is not a
kind of a flower; it is a part of a flower. The third is association, which denotes some
semantic dependency among otherwise unrelated classes, such as between ladybugs and
flowers. As another example, roses and candles are largely independent classes, but they both
represent things that we might use to decorate a dinner table.
Several common approaches have evolved in programming languages to capture
Generalization/specialization, whole/part, and association relationships. Specifically, most
object-oriented languages provide direct support for some combination of the following
relationships:
• Association
• Inheritance
• Aggregation
• Using
• Instantiation
• Metaclass

22
2.3 THE INTERPLAY OF CLASS AND OBJECTS

Relationships between Classes and Objects


Classes and object are separate yet intimately related concepts. Specifically, every
object is the instance of some class, and every class has zero or more instances. For
practically all applications, classes are static; therefore, their existence, semantics, and
relationships are fixed prior to the execution of a program. Similarly, the class of most
objects is static, meaning that once an object is created, its class is fixed. In sharp contrast,
however, objects are typically created and destroyed at a furious rate during the li time of an
application.
For example, consider the classes and objects in the implementation of a traffic
control system. Some of the more important abstractions include planes, flight plans,
runways, and air spaces. By their very definition, the meanings of these classes of objects are
relatively static.
They must be static, for otherwise one could not build an application that embodied
knowledge of such commonsense facts as that planes can take off, fly, and then land, and that
two planes should not occupy the same space at the same time. Conversely, the instances of
these classes are dynamic.
At a fairly slow rate, new runways are built, and old ones are deactivated. Faster yet,
new flight plans are filed, and old ones are filed away. With great frequency, new planes
enter a particular air space, and old ones leave.
Role of Classes and Objects in Analysis and DesignDuring analysis and the early stages of
design, the developer has two primary tasks:
• Identify the classes and objects that form the vocabulary of the problem domain.
• Invent the structures whereby sets of objects work together to provide the behaviors
that satisfy the requirements of the problem.Collectively, we call such classes and
objects the key abstractions of the problem, and we call these cooperative structures
the mechanisms of the implementation.

2.4 ON BUILDING QUALITY CLASSES AND OBJECTS

Measuring the Quality of an Abstraction


Ingalls suggests that "a system should be built with a minimum set of unchangeable
parts; those parts should be as general as possible; and all parts of the system should be held

23
in a uniform framework". With object-oriented development, these parts are the classes and
objects that make up the key abstractions of the system, and the framework is provided by its
mechanisms.
In our experience, the design of classes and objects is an incremental, iterative
process. Frankly, except for the most trivial abstractions, we have never been able to define a
class exactly right the first time. Of course, there is a cost to refining these abstractions, in
terms of recompilation, understandability, and the integrity of the fabric of our system design.
Therefore, we want to come as close as we can to being right the first time.How can one
know if a given class or object is well designed? We suggest five meaningful metrics:
• Coupling
• Cohesion
• Sufficiency
• Completeness
• Primitiveness
Coupling is a notion borrowed from structured design, but with a liberal interpretation
it also applies to object-oriented design.
Stevens, Myers, and Constantine define coupling as "the measure of the strength of
association established by a connection from one module to another. Strong coupling
complicates a system since a module is harder to understand, change, or correct by itself if it
is highly interrelated with other modules. Complexity can be reduced by designing systems
with the weakest possible coupling between modules".
A counterexample to good coupling is given by Page-Jones, in his description of a
modular stereo system in which the power supply is located in one of the speaker cabinets.
Coupling with regard to modules is still applicable to object-oriented analysis and design, but
coupling with regard to classes and objects is equally important. However, there is tension
between the concepts of coupling and inheritance, because inheritance introduces significant
coupling. On the one hand, weakly coupled classes are desirable; on the other hand,
inheritance- which tightly couples superclasses and their subclasses- helps us to exploit the
commonality among abstractions.
The idea of cohesion also comes from structured design. Simply stated, cohesion
measures the degree of connectivity among the elements of a single module (and for object-
oriented design, a single class or object).
The least desirable form of cohesion is coincidental cohesion, in which entirely
unrelated abstractions are thrown into the same class or module. For example, consider a

24
class comprising the abstractions of dogs and spacecraft, whose behaviors are quite unrelated.
The most desirable form of cohesion is functional cohesion, in which the elements of a class
or module all work together to provide some well-bounded behavior.
Thus, the class Dog is functionally cohesive if its semantics embrace the behavior of a
dog, the whole dog, and nothing but the dog.
Closely related to the ideas of coupling and cohesion are the criteria that a class or module
should be sufficient, complete, and primitive. By sufficient, we mean that the class or module
captures enough characteristics of the abstraction to permit meaningful and efficient
interaction.
To do otherwise renders the component useless. For example, if we are designing the
class Set, it is wise to include an operation that removes an item from the set, but our wisdom
is futile if we neglect an operation that adds an item. In practice, violations of this
characteristic are detected very early; such shortcomings rise up almost every time we build a
client that must use this abstraction. By complete, we mean that the interface of the class or
module captures all of the meaningful characteristics of the abstraction.
Whereas sufficiency implies a minimal interface, a complete interface is one that
covers all aspects of the abstraction. A complete class or module is thus one whose interface
is general enough to be commonly usable to any client. Completeness is a subjective matter,
and it can be overdone.
Providing all meaningful operations for a particular abstraction overwhelms the user
and is generally unnecessary, since many high-level operations can be composed from low-
level ones. For this reason, we also suggest that classes and modules be primitive. Primitive
operations are those that can be efficiently implemented only if given access to the
underlying representation of the abstraction. Thus, adding an item to a set is primitive,
because to implement this operation Add, the underlying representation must be visible.
On the other hand, an operation that adds four items to a set is not primitive, because
it can be implemented just as efficiently upon the more primitive Add operation, without
having access to the underlying representation. Of course, efficiency is also a subjective
measure.
An operation is indisputably primitive if we can implement it only through access to
the underlying representation. An operation that could be implemented on top of existing
primitive operations, but at the cost of significantly more computational resources, is also a
candidate for inclusion as a primitive operation.

25
2.5 CLASSIFICATION

Classification is the means whereby we order knowledge. In object-oriented design,


recognizing the sameness among things allows us to expose the commonality within key
abstractions and mechanisms, and eventually leads us to smaller and simpler architectures.
Unfortunately, there is no golden path to classification.
To the reader accustomed to finding cookbook answers, we unequivocally state that
there are no simple recipes for identifying classes and objects. There is no such thing as the
"perfect" class structure, nor the "right" set of objects. As in any engineering discipline, our
design choices are a compromise shaped by many competing factors

2.5.1 THE IMPORTANCE OF PROPER CLASSIFICATIONS

Classification and Object-Oriented Development


The identification of classes and objects is the hardest part of object-oriented analysis
and design. Our experience shows that identification involves both discovery and invention.
Through discovery, we come to recognize the key abstractions and mechanisms that
form the vocabulary of our problem domain. Through invention, we devise generalized
abstractions as well as new mechanisms that specify how objects collaborate. Ultimately,
discovery and invention are both problems of classification, and classification is
fundamentally a problem of finding sameness. When we classify, we seek to group things
that have a common structure or exhibit a common behavior.
Intelligent classification is actually a part of all good science. As Michalski and Stepp
observe, "An omnipresent problem in science is to construct meaningful classifications of
observed objects or situations. Such classifications facilitate human comprehension of the
observations and the subsequent development of a scientific theory".
The same philosophy applies to engineering. In the domain of building architecture
and city planning, Alexander notes that, for the architect, "his act of design, whether humble,
or gigantically complex, is governed entirely by the patterns he has in his mind at that
moment, and his ability to combine these patterns to form a new design". Not surprisingly,
then, classification is relevant to every aspect of object-oriented design.
Classification helps us to identify generalization, specialization, and aggregation
hierarchies among classes. By recognizing the common patterns of interaction among objects,
we come to invent the mechanisms that serve as the soul of our implementation.

26
Classification also guides us in making decisions about modularization. We may choose to
place certain classes and objects together in the same module or in different modules,
depending upon the sameness we find among these declarations; coupling and cohesion are
simply measures of this sameness.
Classification also plays a role in allocating processes to processors. We place certain
processes together in the same processor or different processors, depending upon packaging,
performance, or reliability concerns.

2.5.2 IDENTIFYING CLASSES AND OBJECTS

Classical and Modern Approaches


The problem of classification has been the concern of countless philosophers,
linguists, cognitive scientists, and mathematicians, even since before the time of Plato. It is
reasonable to study their experiences and apply what we learn to object-oriented design.
Historically, there have only been three general approaches to classification:
• Classical categorization
• Conceptual clustering
• Prototype theory
Classical Categorization: In the classical approach to categorization, "All the entities
that have a given property or collections of properties in common form a category. Such
properties are necessary and sufficient to define the category". For example, married people
constitute a category: one is either married or not, and the value of this property is sufficient
to decide to which group a particular person belongs. On the other hand, tall people do not
form a category, unless we can agree to some absolute criteria for what distinguishes the
property of tall from short.
Classical categorization comes to us first from Plato, and then from Aristotle through
his classification of plants and animals, in which he uses a technique much akin to the
contemporary children's game of Twenty Questions (Is it an animal, mineral, or vegetable?
Does it have fur or feathers? Can it fly? Does is smell?). Later philosophers, most notably
Aquinas, Descartes, and Locke, adopted this approach. As Aquinas stated, "We can name a
thing according to the knowledge we have of its nature from its properties and effects".
A Problem of Classification
Conceptual Clustering: Conceptual clustering is a more modern variation of the
classical approach, and largely derives from attempts to explain how knowledge is

27
represented. As Stepp and Michalski state, "In this approach, classes (clusters of entities) are
generated by first formulating conceptual descriptions of these classes and then classifying
the entities according to the descriptions".
For example, we may state a concept such as "a love song." This is a concept more than a
property, for the "love songness" of any song is not something that may be measured
empirically. However, if we decide that a certain song is more of a love song than not, we
place it in this category. Thus, conceptual clustering represents more of a probabilistic
clustering of objects.
Conceptual clustering is closely related to fuzzy (multivalue) set theory, in which
objects may belong to one or more groups, in varying degrees of fitness. Conceptual
clustering makes absolute judgments of classification by focusing upon the "best fit."
Prototype Theory: Classical categorization and conceptual clustering are sufficiently
expressive to account for most of the classifications we ever need in the design of complex
software systems. However, there are still some situations in which these approaches are
inadequate. This leads us to the more recent approach to classification, called prototype
theory, which derives primarily from the work of Rosch and her colleagues in the field of
cognitive psychology.
There are some abstractions that have neither clearly bounded properties nor concepts.
As Lakoff explains the problem, "Wittgenstein pointed out that a category like game does not
fit the classical mold, since there are no common properties shared by all games. . . . Though
there is no single collection of properties that all games share, the category of games is united
by what Wingenstein calls family resemblances. . . . Wingenstein also observed that there
was no fixed boundary to the category game. The category could be extended and new kinds
of games introduced, provided that they resembled previous games in appropriate ways".
This is why the approach is called prototype theory: a class of objects is represented
by a prototypical object, and an object is considered to be a member of this class if and only
if it resembles this prototype in significant ways.

2.5.3 KEY ABSTRACTION AND MECHANISM

Identifying Key Abstractions


Finding Key Abstractions A key abstraction is a class or object that forms part of the
vocabulary of the problem domain. The primary value of identifying such abstractions is that
they give boundaries to our problem; they highlight the things that are in the system and

28
therefore relevant to our design, and suppress the things that are outside the system and
therefore superfluous. The identification of key abstractions is highly domain-specific.
As Goldberg states, the "appropriate choice of objects depends, of course, on the
purposes to which the application will be put and the granularity of information to be
manipulated".
As we mentioned earlier, the identification of key abstractions involves two
processes:
Discovery and invention. Through discovery, we come to recognize the abstractions
used by domain experts; if the domain expert talks about it, then the abstraction is usually
important. Through invention, we create new classes and objects that are not necessarily part
of the problem domain, but are useful artifacts in the design or implementation.
For example, a customer using an automated teller speaks in terms of accounts,
deposits, and withdrawals; these words are part of the vocabulary of the problem domain. A
developer of such a system uses these same abstractions, but must also introduce new ones,
such as databases, screen managers, lists, queues, and so on. These key abstractions are
artifacts of the particular design, not of the problem domain.
Perhaps the most powerful way to identify key abstractions is to look at the problem
or design and see if there are any abstractions that are similar to the classes and objects that
already exist. As we will discuss further in Chapter 6, in the absence of such reusable
abstractions, we recommend the use of scenarios to drive the process of identifying classes
and objects.
Refining Key Abstractions Once we identify a certain key abstraction as a candidate,
we must evaluate it according to the metrics described in the previous chapter. As Stroustrup
suggests, "Often this means that the programmer must focus on the questions: how are
objects of this class created? can objects of this class be copied and/or destroyed? What
operations can be done on such objects? If there are no good answers to such questions, the
concept probably wasn't 'clean' in the first place, and it might be a good idea to think a bit
more about the problem and the proposed solution instead of immediately starting to 'code
around' the problems".
Given a new abstraction, we must place it in the context of the existing class and
object hierarchies we have designed. Practically speaking, this isneither a top-down nor a
bottom-up activity.
As Halbert and O'Brien observe, "You do not always design types in a type hierarchy
by starting with a supertype and then creating the subtypes. Frequently, you create several

29
seemingly disparate types, realize they are related, and then factor out their common
characteristics into one or more supertypes . several passes up and down are usually required
to produce a complete and correct program design".
This is not a license to hack, but an observation, based upon experience, that
objectoriented design is both incremental and iterative. Stroustrup makes a similar
observation when he notes that "the most common reorganizations of a class hierarchy are
factoring the common part of two classes into a new class and splitting a class into two new
ones".
Classes and objects should be at the right level of abstraction: neither too high nor too
low.Placing classes and objects at the right levels of abstraction is difficult. Sometimes we
may find a general subclass, and so may choose to move it up in the class structure, thus
increasing the degree of sharing.
This is called class promotion. Similarly, we may find a class to be too general, thus
making inheritance by a subclass difficult because of the large semantic gap. This is called a
grain size conflict. In either case, we strive to identify cohesive and loosely coupled
abstractions, so as to mitigate these two situations.
Naming things properly - so that they reflect their semantics - is often treated lightly
by most developers, yet is important in capturing the essence of the abstractions we are
describing. Software should be written as carefully as English prose, with consideration given
to the reader as well as to the computer. Consider for a moment all the names we may need
just to identify a single object:
we have the name of the object itself, the name of its class, and the name of the module in
which that class is declared. Multiply this by thousands of objects and possibly hundreds of
classes, and you have a very real problem.
We offer the following suggestions:
• Objects should be named with proper noun phrases, such as theSensor or just simply
shape.
• Classes should be named with common noun phrases, such as Sensors or Shapes.
• Modifier operations should be named with active verb phrases, such as draw or
moveLeft.
• Selector operations should imply a query or be named with verbs the form "to be,"
such as extentOf or is0pen.

30
• The use of underscores and styles of capitalization are largely matters of personal
taste. No matter which cosmetic style you use, at least have your programs be self
consistent.
Finding Mechanisms
In the previous chapter, we used the term mechanism to describe any structure
whereby objects collaborate to provide some behavior that satisfies a requirement of the
problem. Whereas the design of a class embodies the knowledge of how individual objects
behave, a mechanism is a design decision about how collections of objects cooperate.
For example, consider a system requirement for an automobile: pushing the
accelerator should cause the engine to run faster, and releasing the accelerator should cause
the engine to run slower. How this actually comes about is absolutely immaterial to the
driver. Any mechanism may be employed as long as it delivers the required behavior, and
thus which mechanism is selected is largely a matter of design choice. More specifically, any
of the following designs might be considered:
A mechanical linkage from the accelerator to the carburetor (the most common
mechanism).
An electronic linkage from a pressure sensor below the accelerator to a computer that
controls the carburetor (a drive-by-wire mechanism).
No linkage exists; the gas tank is placed on the roof of the car, and gravity causes
fuel to flow to the engine. Its rate of flow is regulated by a clip around the fuel line; pushing
on the accelerator pedal eases tension on the clip, causing the fuel to flow faster (a low-cost
mechanism).
Mechanisms are the means whereby objects collaborate to provide some higher-level
behavior. Which mechanism a developer chooses from a set of alternatives is most often a
result of other factors, such as cost, reliability, manufacturability, and safety.
Just as it is rude for a client to violate the interface of another object, so it is socially
unacceptable for objects to step outside the boundaries of the rules of behavior dictated by a
particular mechanism. Indeed, it would be surprising for a driver if stepping -on-an
accelerator turned on the car's lights instead of causing the engine to run faster.
Whereas key abstractions-reflect the vocabulary of the problem domain, mechanisms
are the soul of the design. During the design process, the developer must consider not only
the design of individual classes, but also how instances of these classes work together.

31
Again, the use of scenarios drives this analysis process. Once a developer decides
upon a particular pattern of collaboration, the work is distributed among many objects by
defining suitable methods in the appropriate classes.
Ultimately, the protocol of an individual class encompasses all the operations
required to implement all the behavior and all the mechanisms associated with each of its
instances.
Mechanisms thus represent strategic design decisions, as does the design of a class
structure. In contrast, however, the interface of an individual class is more of a tactical design
decision. These strategic decisions must be made explicitly; otherwise we will end up with a
mob of relatively uncooperative objects, all pushing and shoving to do their work with little
regard for other objects. The most elegant, lean, and fast programs embody carefully
engineered mechanisms.
Mechanisms are actually one in a spectrum of patterns we find in well-structured
software systems. At the low end of the food chain, we have idioms. An idiom is an
expression peculiar to a certain programming language or application culture, representing a
generally accepted convention for use of the language41. For example, in CLOS, no
programmer would use underscores in function or variable names, although this is common
practice in Ada.
Part of the effort in learning a programming language is learning its idioms, which are
usually passed down as folklore from programmer to programmer. However, as Coplien
points out, idioms play an important role in codifying low-level patterns.
He notes that, "many common programming tasks [are] idiomatic and therefore
identifying such idioms allows "using C++ constructs to express functionality outside the
language proper, while giving the illusion of being part of the language".
At the high end of the food chain, we have frameworks. A framework is collection of
classes that provide a set of services for a particular domain; a frame---work thus exports a
number 41 One defining characteristic of an idiom is that ignoring or violating the idiom has
immediate social consequences: you are branded as a yahoo or, worse, an outsider, unworthy
of respect.
Whereas idioms are part of a programming culture, frameworks are often the product
of commercial ventures. For example, Apple's MacApp (and its successor, Bedrock) are both
application frameworks, written in C++, for building applications that conform to Macintosh
user interface standards.

32
UNIT III

3.1 C++ INTRODUCTION

What is C++?
C++ is a cross-platform language that can be used to create high-performance
applications.
C++ was developed by Bjarne Stroustrup, as an extension to the C language.
C++ gives programmers a high level of control over system resources and memory.
The language was updated 4 major times in 2011, 2014, 2017, and 2020 to C++11,
C++14, C++17, C++20.
Why Use C++
C++ is one of the world's most popular programming languages.
C++ can be found in today's operating systems, Graphical User Interfaces, and
embedded systems.
C++ is an object-oriented programming language which gives a clear structure to
programs and allows code to be reused, lowering development costs.
C++ is portable and can be used to develop applications that can be adapted to
multiple platforms.
C++ is fun and easy to learn
As C++ is close to C, C# and Java, it makes it easy for programmers to switch to C++
or vice versa.
Difference between C and C++
C++ was developed as an extension of C, and both languages have almost the same
syntax.
The main difference between C and C++ is that C++ support classes and objects,
while C does not.
C++ Get Started
To start using C++, you need two things
A text editor, like Notepad, to write C++ code.
A compiler, like GCC, to translate the C++ code into a language that the computer
will understand.
myfirstprogram.cpp

33
Code:
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!";
return 0;
}

Result:

Hello World!

3.2 INPUT/OUTPUT STATEMENTS IN C++

C++ I/O operation is using the stream concept. Stream is the sequence of bytes or
flow of data. It makes the performance fast.
If bytes flow from main memory to device like printer, display screen, or a network
connection, etc, this is called as output operation.
If bytes flow from device like printer, display screen, or a network connection, etc to
main memory, this is called as input operation
.
3.2.1 I/O LIBRARY HEADER FILES

Let us see the common header files used in C++ programming are:

34
3.2.2 STANDARD OUTPUT STREAM (COUT)

The cout is a predefined object of ostream class. It is connected with the standard
output device, which is usually a display screen. The cout is used in conjunction with stream
insertion operator (<<) to display the output on a console
Let's see the simple example of standard output stream (cout):
#include <iostream>
using namespace std;
int main( ) {
char ary[] = "Welcome to C++ tutorial";
cout << "Value of ary is: " << ary << endl;
}
Output
Value of ary is: Welcome to C++ tutorial

3.2.3 STANDARD INPUT STREAM (CIN)

The cin is a predefined object of istream class. It is connected with the standard input
device, which is usually a keyboard. The cin is used in conjunction with stream extraction
operator (>>) to read the input from a console.
Let's see the simple example of standard input stream (cin):
#include <iostream>
using namespace std;
int main( ) {
int age;
cout << "Enter your age: ";
cin >> age;
cout << "Your age is: " << age << endl; }
Output:
Enter your age: 22
Your age is: 22

35
3.2.4 THE STANDARD ERROR STREAM (CERR)

The predefined object cerr is an instance of ostream class. The cerr object is said to be
attached to the standard error device, which is also a display screen but the object cerr is un-
buffered and each stream insertion to cerr causes its output to appear immediately.
The cerr is also used in conjunction with the stream insertion operator as shown in the
following example.
#include <iostream>
using namespace std;
int main() {
char str[] = "Unable to read....";
cerr << "Error message : " << str << endl;
}

When the above code is compiled and executed, it produces the following result −
Error message : Unable to read....
The Standard Log Stream (clog)
The predefined object clog is an instance of ostream class. The clog object is said to
be attached to the standard error device, which is also a display screen but the object clog is
buffered. This means that each insertion to clog could cause its output to be held in a buffer
until the buffer is filled or until the buffer is flushed.
The clog is also used in conjunction with the stream insertion operator as shown in the
following example.

#include <iostream>
using namespace std;
int main() {
char str[] = "Unable to read....";
clog << "Error message : " << str << endl;
}

When the above code is compiled and executed, it produces the following result −
Error message : Unable to read....

36
You would not be able to see any difference in cout, cerr and clog with these small
examples, but while writing and executing big programs the difference becomes obvious. So
it is good practice to display error messages using cerr stream and while displaying other log
messages then clog should be used.

3.3 CONTROL STRUCTURE

A large number of functions are used that pass messages and process the data
contained in objects. At the time easy to debugging and trace of the execution statements.
The control structure as follows:

Control structure

Selection
Sequence
Loop
Switch
IF.else

Do-while For, while


The following control structures.
• sequence structures(straight line)
• selection structure (branching)
• loop structure (iteration or repetition )
If statement types
The different forms are
• Simple if statement
• If…..else statement
• Nested if..else statement
• Else…..if ladder
• Switch statement

37
3.3.1 SIMPLE IF STATEMENT

The general form of a Simple IF statement is

if (test expression)
{
statement-block;
}
statement-x;

Where the statement –block may be a single statement or a group of statements. If


the test expression is true, the statement-block will be executed; otherwise the
statement- block will be skipped and the execution will jump to the statement-x. Note:
when the condition is true both the statement block and the statement-x are executed.
EXAMPLE 1:
A=10; B=5;
if (A>B)
cout<<“ A is the largest number”;
If the given condition is satisfied then computer will print the message ―A is the
largest number‖ and if not simply skip this statement.
b.The if…else statement:
The if…else statement is an extension of the simple if statement. The general
format is
if(condition)
{
Statements;
}

Else statements
If the test expression is true, then the true-block statement(s), immediately
following the if statements are executed; otherwise ,the false-block statement(s) are
executed. In both the case, the control is transferred subsequently to the statements -x.

38
3.4 C++ FUNCTIONS

A function is a block of code which only runs when it is called. You can pass data,
known as parameters, into a function. Functions are used to perform certain actions, and they
are important for reusing code: Define the code once, and use it many times.
Create a Function
C++ provides some pre-defined functions, such as main(), which is used to execute
code. But you can also create your own functions to perform certain actions.
To create (often referred to as declare) a function, specify the name of the function,
followed by parentheses ():

Syntax
void myFunction() {
// code to be executed
}

Example Explained
myFunction() is the name of the function
void means that the function does not have a return value. You will learn more about return
values later in the next chapter
inside the function (the body), add code that defines what the function should do
Call a Function
Declared functions are not executed immediately. They are "saved for later use", and
will be executed later, when they are called.
To call a function, write the function's name followed by two parentheses () and a
semicolon ;
In the following example, myFunction() is used to print a text (the action), when it is
called:
Example

39
Inside main, call myFunction():
// Create a function
void myFunction() {
cout << "I just got executed!";
}
I nt main() {
myFunction(); // call the function
return 0;
}
// Outputs "I just got executed!"

A function can be called multiple times:


Example

void myFunction() {
cout << "I just got executed!\n"; }
int main() {
myFunction();
myFunction();
myFunction();
return 0; }
// I just got executed!
// I just got executed!
// I just got executed!

A C++ function consist of two parts


Declaration: the return type, the name of the function, and parameters (if any)
Definition: the body of the function (code to be executed)
void myFunction() { // declaration
// the body of the function (definition)
}

40
Note: If a user-defined function, such as myFunction() is declared after the main()
function, an error will occur:
Example
int main() {
myFunction();
return 0;
}
void myFunction() {
cout << "I just got executed!";
}
// Error

However, it is possible to separate the declaration and the definition of the function -
for code optimization.
You will often see C++ programs that have function declaration above main(), and
function definition below main(). This will make the code better organized and easier to read:
Example
// Function declaration
void myFunction();
// The main method
int main() {
myFunction(); // call the function
return 0;
}
// Function definition
void myFunction() {
cout << "I just got executed!";
}

41
UNIT-IV

4.1 CLASSES AND OBJECTS

CLASS
A class is a way to bind the data and its associated functions together. A class
specification has two parts.
1. Class declaration
2. Class function definitions
The general form of a class declaration is as follows.

Class class-name
{
Private:
Variable declarations; Function declarations;
Public:
Variable declarations; Function declarations;
};

The class declaration is similar to a struct declaration. The keyword class specifiethat
what follows is an abstract data of type class-name. The body of a class is enclosed within
braces and terminated by a semicolon. The class body contains the eclaration variables and
functions. These function and variables are collectively called members. They are grouped
under two sections, namely, private and public to denote which of them are public. The
keywords private and public are known as visibility labels. The keywords followed by colon.
The members that have been declared as private can be accessed only from within the
class. The public members can be accessed from outside the class also. The variables
declared inside the class are known as data members and the function are known as member
function, only member functions can have access to the private data members and private
functions. However, the public members can be accessed from outside the class.

42
Creating objects
In c++, the class variables are known as objects. Therefore, x is called an object is
called an object of type item. We may also declare more than one object in one statement
example.
Item a, b,c;
The declaration of an object is similar to that of a variable of any basic type. The class
definitions as follows.
Class item
{
………….
……….....
} a, b, c;
We are create the object a, b, and c of type item.

Accessing class members:


The following is the format for calling member function

Object-name. Function-name (actual arguments);

For example,
x.getdata (100, 75.5);
The above statement is valid and the assigns the value 100to number and 75.5 to cost
of the object x by implementation the getdata ( ) function.. Similarly the statement,
x.putdata ( ) would be display the values of data members.
MEMBER FUNCTIONS
Member function can be defined in two places:
o outside the class definitions
o inside the class definitions
a. Outside the class definitions
The general forms of a member function definitions is as follows

43
Return type class-name:: function-name (argument declarations)
{
Function-body;
}

The membership label class-name:: tells the compiler that the function function- name
belongs to the class class-name. That is , the scope of the function is restricted to the class-
name specified in the header line. The symbol:: is called scope resolution operator. They may
be coded as follows.

Void item:: getdata (int a,float b);


{
Number =a;
Cost =b;
}
Void item:: putdata(void)
{
Cout<<‖number‖; Cout<<‖cost‖;
}

The member functions have some special characteristics as follows,Several different


classes can use the same function name. Member function can access the private data of the
class. A member function can call another function directly, with out using dot operator.
b.Inside the class definitions:
For example ,we could define the item class as follows.

44
Class item
{
Int number; Float cost;
Public:
Void getdata(int a ,float b); Void putdata(void)
{
Cout<<number; Cout<<cost;
}
};

When a function is define inside a class it is treated as inline function.

Program with class


#include<iostream.h> class number
{
private:
int a,b; public:
void get_ab()
{
cout<<‖Enter values for a and b \n‖;
cin>>a; cin>>b;
}
void add(); void mul();
};
void number :: add()
{
int c; c=a+b;
cout<<‖THE SUM IS ―<<c;
}
void number :: mul()
{
int d; d=a*b;
cout<<‖THE PRODUCT IS ―<<d;

45
}
void main()
{
number ob1; ob1.get_ab();
ob1.add();
ob1.mul();
}
Output of the Program Enter values for a and b 5 6
THE SUM IS 11
THE PRODUCT IS 30

Making an outside inline


We can define a member function outside the class definition and still make it inline
by just using the qualifier in the header line of the function. For example
Class item
{
……….
……….
Public:
Void getdata (int a, float b);
};
Inline void item:: getdata (int a ,float b)
{
Number =a;
Cost =b;
}

Nesting of member functions


A member function can be called by using its name inside another member function
of the same class. For example
#include <iostream.h> Class set
{
Int m, n;
Public:

46
Void input (void);
Void display (void); Int largest (void);
};
Int set:: largest(void)
{
If (m>=n) Return (m);
Else
Return (n);
}
Void set::input (void)
{
Cout<<‖input values of m and n‖; Cin>>m>>n;
}
Void set:: display (void)
{
Cout<<‖largest value=‖<<largest ();
}
Main ()
{
Set A.;
A.input ();
A.display ();
}
Sample input and out put as follows:
Input values of m and n is 75, 25 :
The output value is 75 (biggest number)

Private member functions


A private member functions van only be called by another function that is a member
of its class. Even an object cannot invoke a private function using the dot operator .consider
the following example.

47
Class sample
{
int m;
Void read (void); Public:
Void update (void); Void write (void);
};
If s1 is a object of sample, then
S1.read ( ); //object cannot access private
The function read () can be called by the function update ( ) to update
the value of m.
Void sample:: update(void)
{
Read ( ); //simple call only
}

ARRAYS WITH IN A CLASS


The arrays can be used as member variable in a class. Consider the following example
Const int size =10; Class array
{
Int a[size];
Public:
Void setval (void); Void display (void);
};

The array variable a [] declared as a private member of the class array can be used in
the member function like any other variable .the above definitions, the member function
setval ( ) sets the values of elements of the array a [] and display () function displays the
values.
MEMORY ALLOCATION FOR OBJECTS
The memory space for objects is allocated when they are declared. The member
function are created and placed in the memory space only once when they are defined as a
part of a class specification.

48
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.
STATIC DATA MEMBERS
A data member of a class can be qualified as static. A static variable has certain
special characteristics:
It is initialized to zero when the first object of its classis created. No other
initialization is permitted.
Only one copy of that member is created for the entire class and is shared by all the
objects of that class, no matter how many objects are created.
It is a visible only within the class , but its lifetime is the entire program
A static data member can be used as a counter that records the occurrences of all the objects.
#include <iostream.h> Class item
{
Static int count ; Int number ; Public:
Void getdata (int a)
{
Number=a;
Count ++;
}
Void getcount (void)
{
Cout<<‖count‖; Cout<<count<<‖\n‖;
}
};
Int item ::count ;
Main()
{}
Item a,b,c; a.getcount();
b.getcount();
c.getcount(); a.getdata(100); b.getdata(200); c.getdata(300);
cout<<‖after reading data‖; a.getcount();
b.getcount();
c.getcount();

49
STATIC MEMBER FUNCTION
Like static variable, we can also have static member functions.The static members
function as following properties.
A static function can have access to only other static members (functions or
variables) declared in the same class.
A static member function can be called using the class name. example , class- name ::
function-name;
Example program:
#includes<iostream.> Class test
{
int code;
Static int count;
Public:
Void setcode(void)
{
Code= ++count;
}
Void showcode(void)
{
Cout<<‖object number ―<< code;
}
Static void showcount(void)
{
Cout<<‖count=‖<<count;
}
};
Int test ::count; main ()
{
Test t1, t2; T1.setcode (); T2.setccode (); Test:: show count(); Test t3;
T3.setcode ( ); Test::showcount ( ); T1.showcode ( ); T2.showcode ( );
T3.showcode ( );
}

50
The static function showcount ( ) displays the number of objects created till that
movement. A count of number of objects created is maintained by the static variable count.
ARRAYS OF OBJECTS
An array can be of any data type including struct. Similarly, we can also have arrays
of variables that are of the type class. Such a variable are called arrays of objects. Consider
the following .
#include<iostream.h> #include<conio.h> class student
{
private:
int rollno; char name[20]; char add[10];
public:
void getdata()
{
cout<<"enter the rollno:"<<endl; cout<<"enter the name:"<<endl;
cout<<"enter the address:"<<endl; cin>>rollno;
cin>>name; cin>>add;
}
void putdata()
{
cout<<"student roll no is:"<<rollno<<endl;
cout<<"student name is:"<<name<<endl; cout<<"student address
is:"<<add<<endl;
} };
int main()
{
int i;
student obj[5]; for(i=0;i<4;i++) obj[i].getdata(); for(i=0;i<4;i++)
obj[i].putdata(); getch();
return 0;
}

OBJECTS AS FUNCTION ARGUMENTS


An object may be used as a function argument. This can be done in two ways

51
A copy of ht e entire object is passed to the function Only the address to 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. This means that any changes made to
the object inside the function will reflect in the actual object.
Example program:

#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‖;
}
Void sum (time, time); }; Void time:: sum(time t1,timet2)
{
}
main()
{
Minutes =t1.minutes +t2.minutes; Hours =minutes/60;
Minutes =minutes%60; Hours=hours + t1.hours +t2.hours;
time t1,t2,t3; t1.gettime(2,45); t2.gettime(3,30); t3.sum(t1,t2); cout<<‖t1=‖;
t1.puttime( );
cout<<‖t2=‖; t2.puttime( ); cout<<‖t3=‖; t3.puttime( );
}

52
The above program, it performs the addition of time in the hour and minutes format.
Since the member function sum ( ) is invoked by the object t3, with the objects t1and t2 as
arguments. it can directly access the hours and minutes variable of t3. The member of t1and
t2 can be accessed only by using the dot operator.
FRIENDLY FUNCTION
The private members cannot be accessed from outside the class. That is, a non-
member function cannot have an access to the private data f a class We have to simply
declare this function as a friend of the class as follows.
Class ABC
{
…………..
…………. Public:
…………..
………….
Friend void xyz (void); //declaration
};

The function declaration should be preceded by the keyword friend. The functions
that are declared with the keyword friend are known as friend function.
A friend function possesses certain special characteristics. It is not in the scope of the
class to which it has declared as friend. Since it is not in the scope of the class, it cannot be
called using the object of that class.
Unlike member function, it cannot access the member names directly and has to use
an object name and dot membership operator with each member name. ex , A.x
It can be declared either in the public or the private part of a class without affecting
its meaning.
Example program:

53
#include<iostream.h> class sample
{
int a; int b;
public:
void setvalue ( )
{
a=25; b=40;
}
Friend mean (sample s)
{
Return float (s. a+ s .b ) / 2.0;
}
Main ( )
{
Sample x; x.setvalue ( );
cout<<‖mean value=‖<<mean(x);
}

RETURNING OBJECTS
A function can not only receive objects as arguments but also can return them.
Example:
class abc
{
public:
friend abc print(abc);
};
abc print(abc b)
{...}

CONST MEMBER FUNCTION


The const member functions as follows; void mul (int , int) const;
double get_balance ( ) const; The const is appended to the function prototypes.

54
POINTER TO MEMBERS
The address of a member of a class and assign it to a pointer. The address of a
member can be obtained by applying the operator & to a ―fully qualified‖ class member
name. a class member pointer can be declared using the operator ::* with the class name For
example
Class A
{
Private:
int m; Public:
Void show ( );
};

We can define a pointer to the member m as follows. int A ::*ip=&A::m; The ip


pointer created thus acts like a class member in that it must be invoked with a class object.
the phrase A::* means ―pointer-to-member of A class‖. The phrase &A::m means the
―address of the m member of A class‖ we are following the code.
ap=&a; cout<<ap->*ip; cout<<ap->m;
The dereferencing operator ->*is used to access a member when we use pointer to
both the object and member.

4.2 CONSTRUCTORS AND DESTRUCTORS

INTRODUCTION
C++ provides a special member function called the constructor which enables an
object to initialize itself when it is created. This is known as automatic initialization of
objects. It also provides another member function called the destructor that destroys the
object when they are no longer required.

#include <iostream.h > class number


{
int a; public:
number( ); //constructor void show( );

55
};
number::number( )
{
cout << ―In constructor\n‖; a=100;
}
void number::show( )
{
cout << a;
}
void main( )
{
number ob; ob.show( );
}

CONSTRUCTORS
A constructors is a ―special ―member function whose task is to initialize the object
of its class. it is special because its name is the same as the the class name. it is also called as
constructor because , it construct the values of data member of the class. The constructor are
defined and declared as follows
Output of the Program
In constructor 100
The constructor functions have some special characteristics:
o They should be declared in the public section.
o They are invoked automatically when the objects are created.
They do not have return types, not even void and therefore, they cannot return values.
They cannot be inherited, through a derived class can call the base class constructor. Like
other C++ functions, they can have default arguments. Constructor cannot be virtual. We
cannot refer to their address. An object with a constructor or destructor cannot be used as a
member of a union.
Parameterized constructors
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. The constructor integer ( ) may be modified to take arguments as
follows.

56
# include < iostream.h > class number
{
int a; public:
number(int x void show( );
};
number::number(int x)
{
cout << ―In constructor\n‖; a=x;
}
void number::show( )
{
cout <<‖Value of a is ―<< a<<―\n‖;
}
int main( )
{
number ob(4); ob.show( ); return 0;
}
Output of the Program
In constructor Value of a is 4

The constructor can be done in two ways.


• By calling the constructor explicitly.
• By calling the constructor implicitly.

57
Example program:
#include<iostream.h> class integer
{
int m,n; public:
integer (int,int); //constructor declared void display(void)
{
cout<<‖m=‖<<m; cout<<‖n‖<<n;
}
};
integer :: integer(int x,int y) //constructor defined
{
m=x;n=y;
}
Main ( )
{
integer int1 (0,100); //implicit call integer int 2=inteiger(25,75); //
explicit call cout<<‖object1‖;
int1.display( ); cout<< object2‖; int2.display ( );
}

Multiple constructors in a class


The multiple constructors, we have used two kind of operations as follows. integer ( ); //
no arguments
integer( in tint)// two arguments from the above statement , the first case is , the
constructors 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( ).consider the
following example.

58
class integer
{
int m,n;
public:
integer ( )
{
m=0;n=0; // constructor1
}
integer (int a, int b)
{
m=a; n=b; //constructor 2
}
integer ( integer &i)
{
m=i.m; n=i.n; //constructor 3
}
};

The above program contain three constructor 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 arguments. For exampleinteger a1;
The above statement would automatically invoke the first contractor and set both m
and n of a1 to zero.
intieger a2 (30, 40)
The above statement would call the second constructors which initialize the data
member‘s m and n of a2 to 30 and 40 respectively.
integer a3(a2)
The above statement would invoke the third constructor which copies the values of a2
into a3. That is, it sets the value of every element of a3 to the value of the corresponding data
element of a2. This process is called as copy constructor.

59
Example program:
#include <iostream.h> class fixed-deposit
{
long int p-amount; //principal amount
int years; // period of the investment
float rate; // interest rate
float r-value; //return value of amount Public:
fixed-deposit() { }
fixed-deposit (long int p , int y , float r= 0.12); fixed-deposit(long int p , int y , int
r);
void display(void);
};
fixed –deposit :: fixed-deposit(long int p, int y, float r)
{
p-amount = p; years =y;
rate =r;
r=value= p-amount; for(int i=1;i<=y;i++)
r-value =r-value * (1.0 + r);
}
fixed –deposit :: fixed-deposit(long int p, int y, int r)
{
p-amount = p; years =y;
rate =r;
r=value= p-amount; for(int i=1;i<=y;i++)
r-value =r-value * (1.0 + float ( r )/100);
}
Void fixed –deposit:: display(void)
{
cout<<‖\n‖<<‖principal amount =‖<<p-amount<<‖\n‖<<‖rerurn-value=‖<<r-
value‖;
}
main()
{

60
fixed-deposit fd1,fd2,fd3; long int p;
int y; float r; int r;
cout<<‖ Enter the amount , period , interest, rate(in percent)‖<<‖\n‖;
cin>>p>>y>>r;
fd1=fixed-deposit(p,y,r);
cout<<‖ Enter the amount , period , interest, rate(decimal form)‖<<‖\n‖;
cin>>p>>y>>r;
fd2=fixed-deposit(p,y,r);
cout<<‖ enter the amount and period ―<<‖\n‖; cin>>p>>y;
fd3=fixed-deposit(p,y); cout<<‖deposit 1‖; fd1.display(); cout<<‖deposit 2‖;
fd2.display(); cout<<‖deposit 3‖; fd3.display();
}

Constructor with default arguments


It is possible to define constrictors with default arguments. Consider the following
example
Complex (float real, float imag =0);
From the above statement, the default value of the arguments imag is zero. Then the
statementComplex C (5.0); Assigns the value 5.0 to the real variable and 0.0 to imag (by
default) however, the statementComplex C (5.0, 6.0); The above statement assigns 5.0 to real
and 6.0 to imag.
Dynamic initialization of objects
Class objects can be initialized dynamically too. i.e. the initial value of an object may
be provided during run time .one advantage of dynamic initialization is that we can provide
various initialization formats , using overloaded constructors.
For example, consider the long term deposit schemes working in the commercial
banks. The banks provide different interest rates for different schemes as well as for different
periods of investments.
The above programs consist of three overloaded constructor .the parameter values to
these constructor are provided at run time. The user can provide input in one of the following
forms.

61
Example
# include < iostream.h > class number
{
int a; public:
number(int x);
number(number & x) //copy constructer void show( );
};
number::number(int x)
{
cout << ―In constructor\n‖; a=x;
}
number :: number(number& x)
{
cout<<‖Copy Constructor\n‖; a=x.a
}
void number::show( )
{
cout <<‖Value of a is ―<< a<<―\n‖;}
int main( )
{
number ob(4); ob.show( );
number ob1(ob); //invokes copy constructer ob1.show();
return 0;
}
Output of the Program
In constructor Value of a is 4 Copy Constructor Value of a is 4

o Amount ,period and interest in decimal form


o Amount, period and interest in percent form.
o Amount and period.
since the constructor are overloaded with the appropriate parameters , the one that
matches the input values is invoked.

62
Copy constructor
A copy constructor is used to declare and initialize an object from another object.For
exampleInteger l2 (l1);
We would define the object l2 and at the same time initialize it to the values of
l1.Another form of this statement is integerl2=l1;the process of initializing through a copy
constructor is known as copy initialization.the following statement is invalidl2=l1;
Will not invoke the copy constructor. However, if l1 and l2 are objects, this statement
is legal and simply assigns the values of l1 and l2, member-by-member.
Dynamic constructors
The constructors can also be used to allocate memory while creating objects. This will
enable the system to allocate the right amount of memory for each object when the objects
are not of the same size, thus resulting in the saving of memory. Allocation of memory to
object at the time of their construction is known as dynamic construction of objects.
Constructing two-dimensional arrays
We can construct matrix variables using the class type object

Example program:
#include <iostream.n> class matrix
{
int ** p; int d1,d2; public:
matrix (int x, int y);
void get-element(int I,int j,int value);
{ p[i][j]=value;}
int & put-element(int 1,int j)
{
return p[i][j];
}
};
matrix :: matrix (int x, int y)
{
d1=x; d2=y;
p=new int *[d1];
for (int i=0;i<d1;i++) p[i]=new int [d2];
}

63
main()
{
int m,n;
cout<<‖Enter the size of memory‖; cin>>m>>n;
matrix A(m,n);
cou<< ―Enter the matrix elements row by row:‖; int i,j,value;
for(i=0;i<m; i++)
for(j=0;j<n;j++)
{
cin>>value;
a.get- element(i .j,value);
}
cout<<‖\n‖;
cout<<‖a.put-element(1,2);
};

From the above table, the construct first creates a vector pointer to an int of size d1.
An int type vector of size d2 by each element p[i]. Thus the space, for the elements of a d1 *
d2 matrix is allocated from free space.
Destructors
A destructor is used to destroy the objects that have been created by a constructor.
The destructor is a member function whose name is the same as the class name but is
preceded by a tilde.
The destructor function has the following characteristics.
o A destructor function never takes any arguments.
o A destructor function will not return any values.
o Destructors cannot be overloaded
o Destructors can be made virtual.
The following program illustrates the use of destructors.
# include <iostream.h >
class number
{
int a; public:
number( ); //constructor

64
~number( ); //destructor void show( );
};
number::number( )
{
cout << ―In constructor\n‖; a=100;
}
number::~number( )
{
cout << ― In Destructor...\n‖;
}
void number :: show()
{
cout<<‖a is ―<<a<<‖\n‖;
}
void main()
{
number ob; ob.show();
}
Output of the Program
In constructor A is 100

A class‘s destructor is called when an object is destroyed. Local objects are destroyed
when they go out of scope. Global objects are destroyed when the program ends.

4.3 OPERATOR OVERLOADING AND TYPE CONVERSIONS

INTRODUCTION
Operator overloading is one of the many existing features if C++ language. C++
permits us to add two variables of user-defined types with the same syntax that is applied to
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. The operator overloading provides a flexible option for the creation of new

65
definitions for most of the C++ operators. We can overload all the C++ operators except the
following.
• Class member access operator (.,.*)
• scope resolution operator(: : )
• size operator(sizeof)
• Conditional operator (?:)
We cannot change its syntax. The grammatical rules that govern its use such as the
number of operands, precedence and associatively.

4.4 DEFINING OPERATOR OVERLOADING

To define an additional task to an operator, we must specify what it means in relation


to the class to which the operator is applied. The general form of an operator function is. The
return type of an operator function is often the class for which it is defined. The operator
being overloaded is substituted for #. For example, if the operator +is being overloaded, the
operator function name would be operator +.
The contents of arg-list vary depending upon how the operator function is
implemented and the type of operator being overloaded where return type is the type
of value returned by the specified operation and op is the operator being overload. The op is
preceded by the keyword operator. Operator is the function name. The functions body must
be either member functions or friend functions. Argument may be passed either by the value
or by reference.
The process of overloading involves the following steps
• First, create a class that defines the data type that is to be used in the
overloading operations.
• Declare the operator function operator op ( ) in the public part of the class. It
may be either member functions or a friend functions.
• Define the operator functions to implement the required operations.
Overloaded operator functions can be invoked by the expression.
• op x or x op
For unary operators and x op y for the binary operator op x (or x op ) would be
interpreted as operator op(x). For friend functions,
Similarly the expression x op y would be interpreted as either x.operator op(y) In case of
function, or operator op(x,y)

66
4.5 OVERLOADING UNARY OPERATORS

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. Consider the
following program.
Example program:
#include <iostream.h> Class space
{
int x; int y; int z; public:
void getdata(int a, int b, int c); void display (void);
void operator-( );
};
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;
}
Void space:: operator-()
{
a = - x;
b = - y;
c = - z;
}
main()
{
space s; s.getdata(10,-20,30); cout<<‖s‖; s.display();
-s; cout<<‖s:‖; s.display();
}
The program produces the following output: S:10 -20 30
S:-10 20 -30

67
4.6 OVERLOADING BINARY OPERATORS

The unary operator overloading same mechanism can be used to overload a binary
operator.
#include <iostream.h> class complex
{
int real; float imag;
public: complex()
{
real=imag=0;
}
complex (int r,float i)
{
real = r; imag=i;
}
complex operator +(complex); void display()
{
cout<<‖The Result is ―; cout<<real << ― +j ― <<imag ;
}
};
complex complex :: operator + (complex c1)
{
complex temp; temp.real=real +c1.real; temp.imag=imag + c1.imag; return
temp;
}
void main()
{
complex c1,c2,c3; int a; float b;
cout<<‖ENTER REAL AND IMAG PART OF COMPLEX
NUMBER1‖<<endl; cin>>a>>b; c1=complex(a,b);
cout<<‖ENTER REAL AND IMAG PART OF COMPLEX

NUMBER2‖<<endl; cin>>a>>b; c2=complex(a,b); c3=c1 + c2 ; c3.display();

68
}
Output of the Program
ENTER REAL AND IMAG PART OF COMPLEX NUMBER1 5 7.1
ENTER REAL AND IMAG PART OF COMPLEX NUMBER2 3 8.3
The Result is 8 + j 15.3

4.7 OVERLOADING BINARY OPERATOR USING FRIENDS

The friend functions may be used in the place of member functions for overloading a
binary operator. The only difference being that a friend function requires two arguments to be
explicitly passed to it while a member function requires only one.
o Replace the member function declaration by the friend function declaration
o Redefine the operator function as follows
The statement C3 = C1 +C2; is equivalent to C3 = operator + (C1, C2);
#include <iostream.h>
class point
{
int x, y; public: point( )
{x = 0; y = 0;}
point(int i, int j)
{
x = i; y = j;
}
void display()
{
cout << ―X IS : ― << x << ―, Y IS : ― << y <<―\n‖;
} friend point operator+(point ob1, point ob2);
};
point operator+(point ob1, point ob2)
{
point temp;
temp.x = ob1.x + ob2.x;
temp.y = ob1.y + ob2.y; return temp;
}

69
int main( )
{
point o1(10, 10), o2(5, 3), o3; o3 = o1 + o2;
o3.display(); return 0;
}
Output of the Program
X IS : 15 ,Y IS : 13

4.8 MANIPULATION OF STRINGS USING OPERATORS

One of the main drawbacks of string manipulators in C is that whenever a string is to


be copied, the programmer must first determine its length and allocate the required amount of
memory. The C++ permits us to create our own definitions of operators that can be used to
manipulate the strings very much similar to the decimal numbers. Consider the example.
• String 3 = string 1 + string 2;
• If (string 1 > string 2) string = string 1;
We use new to allocate memory for each string and a pointer variable to point to the
string array. We must create string objects that can hold these two pieces of information,
namely, length and location which are necessary for string manipulations.

4.9 RULES FOR OVERLOADING OPERATORS

The following rules for overloading operators. Only existing operators can be
overloaded, new operators cannot create. The overloaded operator must have at least one
operand that this of user-defined type. We cannot change the basic meaning of an operator.
ie, we cannot redefine the plus (+) operator to subtract one value from the other. Overloaded
operator follow the syntax rules of the original operators. There are some operators that
cannot be overloaded. Binary arithmetic operator such as +, - , *, and / must explicitly return
a value. They must not attempt to change their own arguments. When using binary operators
overloaded through a member function m the left- hand operand must be an object of the
relevant class.
TYPE CONVERSION
Type conversion or typecasting refers to changing an entity of one data type into
another. This is done to take advantage of certain features of type hierarchies. For instance,

70
values from a more limited set, such as integers, can be stored in a more compact format and
later converted to a different format enabling operations not previously possible, such as
division with several decimal places worth of accuracy. The constants and variables of
different types are mixed in an expression. The type pf data to the right on assignment
operators is automatically converted to the type of the variable on the left.
For example
int m;
Float x=3.14159; m=x;
This function converts a class type to specified type name. For example operator int()
converts the class object to integer data type. Conditions for a casting operator function
o It must be a class member.
o It must not specify a return type.
o It must not have any arguments.
The following example cast the object of type ―time‖ to basic data types (int and
float)
class time
{
int min,sec; public: time(int n)
{
min = n/60; sec=n%60;
}
operator int()
{
int x;
x= min * 60 + sec; return sec;
}
operator float()
{
float y;
y = min + sec/60; return y;
}
};
void main()
{

71
time t1(160); int n = t1; float x = t1;
}

4.10 ONE CLASS TO ANOTHER CLASS TYPE

The Constructors helped us to define the conversion from a basic data type to class
type and the overloaded casting operator helped to define the conversion from a class type to
basic data type. Now to convert from one class type to another class type these both help us
to do.
The following program converts the class type length1 to type length2
class length2; //forward declaration class
length1
{
int m,cm; public:
length1(int n)
{
m=n/100; cm=n%100;
}
operator length2() //from length1 type to
length2 type
{
int x= m*100 + cm; length2 tempobj(x); return
tempobj;
}
} class length2
{
int cm; public:
length2(int n)
{
cm=n;
}
operator length1() //from length2 type to
length1 type

72
{
length1 tempobj(cm); return tempobj;
}
}
void main()
{
int x= 125; length2 obj1(x);
length1 obj2= obj1;
}

4.11 INHERITANCE

EXTENDING CLASS
C++ strongly supports the concept of reusability. The C++ classes can be reused in
several ways. Inheritance is a feature by which new classes are derived from the existing
classes.
Inheritance allows re-using code without having to rewrite from scratch. The parent
class(Original existing class) is said to be the base class the new made class from
it is called a derived class A class that is derived from parent class will posses all the
properties of the base class apart from that it also has its own unique properties. However the
derived class will not inherit constructers, destructors, friend functions and assignment
operators further derived classes cannot remove any data member present in the base
class.C++ supports various types of inheritance scheme. They are
o Single inheritance
o Multiple inheritance
o Multilevel inheritance
o Hierarchical inheritance
o Hybrid inheritance

73
4.11.1 DERIVED CLASSES

The colon indicates that the derived-class-name id derived from the base-class- name. The
visibility mode is optional and, if present, may be either private or public. The default
visibility-mode is private.
Example:
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 };

74
4.11.2 SINGLE INHERITANCE

A derived class with only one base class is called single inheritance
Here the class B is derived from only one class i.e A. The definition of class B would be as,
Example:
class base
{ int x;
public:
void setx(int n) { x= n ;}
void showx( ) {cout << x << "\n" ; }
};
Inherit as public:
class derived : public base
{ int y;
public :
void sety( int n) { y = n; }
void showy( ) {cout << y << "\n" ; }
};
int main( )
{
derived ob;
ob.setx(10); // access member of base class ob.sety(20); // access member of derived
ob.showx( ); // access member of base class ob.showy( ); // access member of derived
return o;
}

As this program illustrates, because base is inherited as public, the public members of
base - setx( ) and showx( ) - become public members of derived and are accessible by any
other part of the program. The derived class doesn't need these functions because there
already exist in base class.

75
4.11.3 MULTILEVEL INHERITANCE

The mechanism of deriving a class from another derived class is known as multilevel
Derived class
The class A serves as a base class for 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:
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
class person
{
protected:
int age; char *name; public: void get1( )
};
class emp : public person
{
protected: int basic,hra; public:
void get2()
};
class manager : public emp
{
private:
int deptcode; public:
void get3( ); void display( );
};
void person :: get1( )
{
cout<<‖Enter your Age‖<<endl; cin >> age;
cout<<‖Enter your name‖<<endl; cin>> name;
}
void emp :: get2( )
{

76
cout<<‖Enter your Basic and HRA‖<<endl; cin>>basic>>hra;
}
void manager :: get3()
{
cout<<‖Enter your Dept Code‖<<endl; cin >> deptcode;
}
void manager :: display( ) {
cout<<‖Name is ―<<name; cout<<‖Age is ―<<age;
cout<<‖Basic and HRA ‖<<basic<<‖\t‖<<hra; cout<<‖Dept Code ‖<<deptode;
}
void main( ) {
manager obj; obj.get1( );
obj.get2( );
obj.get3( ); obj.display( ); }
Output of the Program
Enter your Age 28
Enter your name
John
Enter your Basic and HRA 20000 1500
Enter your Dept Code 200
Name is John Age is 28
Basic and HRA 20000 1500
Dept Code 200

4.11.4 MULTIPLE INHERITANCE

A derived class with several base classes is called multiple inheritanceHere class C is
derived from A and B. So C can access both the members of Aand B.
class derived classname : access mode base1, access mode base2,…..access mode base n
{
//body of the derived class
}

77
When a class inherits multiple base classes that have constructors that require arguments,
the derived class passes the necessary arguments to them by using the expanded form of
derived class.
When a base class and a derived class both have constructor and destructor functions, the
constructor functions are executed in order of derivation. The destructor functions are
executed in the reverse order.
If there is a need to pass an argument to the constructor of the base class a chain of
argument passing is established. First all necessary arguments to both the base class and
derived class are passed to derived class's constructor. Using an expanded form of the
derived class's constructor declaration, we then pass the appropriate arguments along to the
base class.
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
class Expdet
{
protected: char *name; int tot_exp;
public: void expr( )
{
cout<<‖Enter your name‖<<endl; cin>>name;
cout<<‖Enter Total Experience‖<<endl; cin>>tot_exp;
}
};
class Saldet
{
protected: int salary;
public:
void salary( )
{
cout<<‖Enter your Salary‖<<endl; cin >>salary;
}
};
class Edudet
{

78
protected: char *degree;
public:
void eduqua( )
{
cout<<‖Enter your Degree‖<<endl; cin>>degree;
}
};
class Promotion : public Expdet ,public Saldet, public Edudet
{
public:
void promote( )
{
if(tot_exp> 10 && sal>=20000 && (strcmp(degree,‖PG‖)= =0)) cout<< ―PROMOTED FOR
HIGHER GRADE‖;
else
cout<<‖CANNOT BE PROMOTED ―;
}
};
void main( )
{
Promotion obj; obj . expr( );
obj . salary( );
obj . eduqua( ); obj . promote( );
}
Output of the Program
Enter your name John
Enter Total Experience 25
Enter your Salary 23000
Enter your Degree PG
PROMOTED FOR HIGHER GRADE

79
4.11.5 HIERARCHICAL INHERITANCE

The traits of one class may be inherited by more than one class is known as Hierarchical
inheritance
#include<iostream.h>
#include<string.h>
class A
{
protected: int x, y; public:
void get ( )
{
cout<<‖Enter two values‖<<endl; cin>> x>>y;
}
};
class B : public A
{
private: int m; public:
void add( )
{
m= x + y;
cout<<‖The Sum is ―<<m;
}
};
class C : public A
{
private: int n; public:
void mul( )
{
n= x * y;
cout << ―The Product is ―<<n;
}
};
class D : public A
{

80
private: float l; public:
void division( )
{
l = x / y;
cout <<‖The Quotient is ―<< l;
}
};
void main( )
{
B obj1; C obj2; D obj3; B .get( );
B .add( );
C .get( );
C .mul( );
D .get( );
D .division( );
}
Output of the Program
Enter two values 12 6
The Sum is 18 The Product is 72
The Quotient is 2.0
Here we can note that objects

4.11.6 HYBRID INHERITANCE

A hybrid inheritance scheme is the combination of all the inheritance schemes


discussed earlier. In figure a class result is produced by deriving the properties of class test
(derived class of student) and class sports. So the result will have both multilevel and
multiple inheritances and its declaration would be as,
class results : public test, public sports
{
....
}
where test itself is a derived class from student. That is, class test : public student
{...}

81
#include<iostream.h>
class emp_det
{
protected:
int emp_id; public:
void get_id()
{
cout<<‖ENTER EMPID‖<<endl; cin>>emp_id;
}
void disp_id()
{
cout<<‖ EMPID IS ‖<<emp_id<<endl;
}
};
class norm_pay :public emp_det
{
protected:
float bpay; public:
void get_bpay()
{
cout<<‖ENTER BASIC PAY‖<<endl; cin>>bpay;
}
void disp_bpay()
{
cout<<‖ BASIC PAY IS = ‖<<bpay<<endl;
}
};
class add_pay
{
protected:
int hrs; int rp; int ap; public:
void get_addpay()
{
cout<<‖ENTER OVERTIME HOURS‖<<endl; cin>>hrs;

82
cout<<‖ENTER HOW MUCH RUPEES PER
HOUR‖<<endl; cin>>rp
}
void disp_addpay()
{
ap=hrs * rp;
cout<<‖TOTAL OVERTIME HOURS‖<<hrs<<endl; cout<<‖ADDITIONAL PAY = ‖<< ap
<<endl;
}
};
class net_pay :public norm_pay,public add_pay
{
int netpay; public:
void display()
{
netpay=ap+bpay;
cout<<‖NET PAY IS ―<<netpay;
}
};
void main()
{
net_pay obj; obj.get_id(); obj.get_bpay(); obj.get_addpay(); obj.disp_id(); obj.disp_bpay();
obj.disp_addpay(); obj.display();
}
Output of the Program
ENTER EMPID 1101
ENTER BASIC PAY 10000
ENTER OVERTIME HOURS 10
ENTER HOW MUCH RUPEES PER HOUR 50
EMPID IS 1101
BASIC PAY IS = 10000
TOTAL OVERTIME HOURS 10 ADDITIONAL PAY = 500
NET PAY IS 10500

83
VIRTUAL BASE CLASSES
Consider the situation shown in figure, with a base class, GrantParent; two derived classes
Parent1 and Parent2; and a fourth class, Grant child derived from Parent1 and Parent2In this
arrangement a problem can arise if a member function in the child class wants to access data
or functions in the Grand Parent class.
class Grandparent
{
protected: int basedata;
};
class Parent1: public Grandparent
{ };
class Parent2 : public Grandparent
{ };
class Child : public Parent1, public Parent2
{ public : int getdata( )
{ return basedata;} // error
};

ABSTRACT CLASSES
An abstract class is a class that is designed to be specifically used as a base class. For an
abstract class no objects can be created. Objects can only be generated from derived classes.
An abstract class contains atleast one pure virtual function. As mentioned earlier a pure
virtual function is declared by adding ―= 0‖ to the function declaration.
Any (non-virtual) class that is derived from an abstract class must implement all pure
virtual functions of the base class. Otherwise it is a virtual class itself. The following is the
example of an abstract class.

4.12 POINTERS AND ARRAYS

You learned from the previous chapter, that we can get the memory address of a variable
by using the & operator:
Example
string food = "Pizza"; // A food variable of type string
cout << food; // Outputs the value of food (Pizza)

84
cout << &food; // Outputs the memory address of food (0x6dfed4)
A pointer however, is a variable that stores the memory address as its value. A pointer
variable points to a data type (like int or string) of the same type, and is created with the *
operator. The address of the variable you're working with is assigned to the pointer:

85
UNIT-V

5.1 MEMORY MANAGEMENT OPERATORS

What is Memory Management?


Memory management is a process of managing computer memory, assigning the
memory space to the programs to improve the overall system performance.
Why is memory management required?
As we know that arrays store the homogeneous data, so most of the time, memory is
allocated to the array at the declaration time. Sometimes the situation arises when the exact
memory is not determined until runtime. To avoid such a situation, we declare an array with a
maximum size, but some memory will be unused. To avoid the wastage of memory, we use
the new operator to allocate the memory dynamically at the run time.

5.1.1 MEMORY MANAGEMENT OPERATORS

In C language, we use the malloc() or calloc() functions to allocate the memory


dynamically at run time, and free() function is used to deallocate the dynamically allocated
memory. C++ also supports these functions, but C++ also defines unary operators such as
new and delete to perform the same tasks, i.e., allocating and freeing the memory.

5.1.2 NEW OPERATOR

A new operator is used to create the object while a delete operator is used to delete the
object. When the object is created by using the new operator, then the object will exist until
we explicitly use the delete operator to delete the object. Therefore, we can say that the
lifetime of the object is not related to the block structure of the program.
Syntax
pointer_variable = new data-type
The above syntax is used to create the object using the new operator. In the above
syntax, 'pointer_variable' is the name of the pointer variable, 'new' is the operator, and 'data-
type' defines the type of the data.
Example 1:
int *p;

86
p = new int;
In the above example, 'p' is a pointer of type int.
Example 2:
float *q;
q = new float;
In the above example, 'q' is a pointer of type float.
In the above case, the declaration of pointers and their assignments are done
separately. We can also combine these two statements as follows:int *p = new int;
float *q = new float;
Assigning a value to the newly created object
Two ways of assigning values to the newly created object:
We can assign the value to the newly created object by simply using the assignment
operator. In the above case, we have created two pointers 'p' and 'q' of type int and float,
respectively. Now, we assign the values as follows:
*p = 45;
*q = 9.8;
We assign 45 to the newly created int object and 9.8 to the newly created float object.
We can also assign the values by using new operator which can be done as follows:
pointer_variable = new data-type(value);
Let's look at some examples.
int *p = new int(45);
float *p = new float(9.8);
How to create a single dimensional array
As we know that new operator is used to create memory space for any data-type or
even user-defined data type such as an array, structures, unions, etc., so the syntax for
creating a one-dimensional array is given below:
pointer-variable = new data-type[size];
Examples:
int *a1 = new int[8];
In the above statement, we have created an array of type int having a size equal to 8
where p[0] refers first element, p[1] refers the first element, and so on.

87
5.1.3 DELETE OPERATOR

When memory is no longer required, then it needs to be deallocated so that the


memory can be used for another purpose. This can be achieved by using the delete operator,
as shown below:
delete pointer_variable;
In the above statement, 'delete' is the operator used to delete the existing object, and
'pointer_variable' is the name of the pointer variable.
In the previous case, we have created two pointers 'p' and 'q' by using the new
operator, and can be deleted by using the following statements:
• delete p;
• delete q;
The dynamically allocated array can also be removed from the memory space by
using the following syntax:
delete [size] pointer_variable;
In the above statement, we need to specify the size that defines the number of
elements that are required to be freed. The drawback of this syntax is that we need to
remember the size of the array. But, in recent versions of C++, we do not need to mention the
size as follows:
delete [ ] pointer_variable;
In the above code, we have created an array using the new operator. The above
program will take the user input for the size of an array at the run time. When the program
completes all the operations, then it deletes the object by using the statement delete arr.
Output
C++ Memory Management
Advantages of the new operator
o The following are the advantages of the new operator over malloc() function:
o It does not use the sizeof() operator as it automatically computes the size of the data
object.
o It automatically returns the correct data type pointer, so it does not need to use the
typecasting.
o Like other operators, the new and delete operator can also be overloaded.
o It also allows you to initialize the data object while creating the memory space for the
object.

88
5.2 POLYMORPHISM

It simply means one name, multiple forms‘. Polymorphism is another important feature
of object oriented programming. The word ―Poly‖means many, and―Morphism―
means structure or forms, thus in C++ polymorphism refers to an object that possess many
form. Polymorphism can be classified into compile time polymorphism and runtime
polymorphism.In addition to compile time polymorphism (function and operator overloading)
C++ also provides run time polymorphism with virtual functions and abstract classes. These
can be used to generate common interfaces to different classes
POINTER
A pointer can point to an object created by a class. Consider the following example.
Item x; Where item is a class and x is an object defined to be of type item. Similarly we can
define a pointer it-ptr of type item as follows:
Item * it-ptr;
Consider the class item defined as follows.

89
Class item ;
{
int code; float price;
Public:
Void getdata(int a , float b)
{
Code =a;
Price=b;
}
Void show (void)
{
cout<<‖Code=:‖<<code; cout<<‖Price=‖<<price;
}
};

POINTER TO OBJECTS
We can refer to the member function of item in two ways, one by using the dot
operator and the object, and another by using the arrow operator and the object pointer.
The statement
x.getdata (100, 75.50); x.show ();
Are equivalent to
Ptr->getdata (100, 75.50); Ptr->show ();
We can also create the objects using pointers and new operator as follows.
Item *ptr =new item;
This statement allocates enough memory for the data members in the object structure
and assign the address of the memory space to ptr. Then the ptr can be used to refer to the
members as shown below.
ptr->show();

90
Example program:// Array of pointer to objects
#include<iostream.h>
class city
{
protected:
char *name; int len;
public:
city()
{
len =0;
name =new char[len+1];
}
void getname (void)
{
char *s;
cout<<‖Enter the city name:‖; cin>>s;
len= strlen(s);
name = new char[len+1]; strcpy(name,s);
}
void printname(void)
{
cout<<name;
}
};
main ()
{
city *cptr[10]; int n=1;
int option; do
{

91
cptr[n]=new city; cptr[n]-.getname(); n++;
cout<<‖Do you want to enter one more name:?‖; cout<<‖Enter 1 for yes 0 for
no:‖;
cin>>option;
}
while(option); cout<<‖\n\n‖;
for( int i=1;i<=n;i++) cptr[i]->printname();
}

The output of the above program is


Enter the city name: Salem
Do you want to enter one or more name? Enter 1 for yes 0 for no: 1
Enter the city name: Chennai
Do you want to enter one or more name? Enter 1 for yes 0 for no: 1
Enter the city name: Erode
Do you want to enter one or more name? Enter 1 for yes 0 for no: 0
Salem Chennai Erode
THIS POINTER
A unique keyword called this to represent an object that invokes a member function. The
starting address is the same as the address of the first variable in the class structure. One
important application of the pointer this is to return the object it points to. For example
return *this;
Inside a member function will return the object that invoked the function . this statement
assumes importance when we want to compare two or more objects inside a member function
and return the involving object as a result.
Example program:
#include<iostream.h> #include<string.h> class person
{
char name[20]; float age; public:
person(char *s, float a)
{
strcpy (name ,s); age = a;
}
person & person :: greater (person & x)

92
{
if(x.age > = age)
return x;
Else
}
return * this;
Void display(void)
{
cout<<‖Name:‖<<name; cout<<‖Age :‖<<age;
}
};
Main ()
{
Person p1(―kannan‖,37.50); p2(―ravi‖,29.0);
p3 (―Krishnan‖,40.25); Person p( ‗\0‘,0);
p=p1.greater (p3);//p3 . greater (p1) cout<<‖Enter person is :\n‖;
p.display();
p=p1.greater (p2);//p2.greater(p1) cout<<‖Enter person is :\n‖;
p.display();
}

5.3 VIRTUAL FUNCTIONS

A virtual function is simply declared by putting the keyword virtual before the
function declaration. Overloading virtual functions is called as overriding. The argument list
and return-type of the function in derived classes must be the same as in the base class
otherwise it is only overloaded, not overridden. Any pointer to a class that contains virtual
functions is provided with additional information about what it points to. When a virtual
function is called through such a pointer, then the pointer knows what object it points to. This
is dynamic binding.
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. the
class hierarchy diagram for the book shop as follows.

93
Example program:
#include<iostream.h> class base
{
public:
virtual void display()
{
cout<<‖I AM IN BASE‖;
}
};
class derived : public base
{
public:
void display()
{
cout<<‖I AM IN DERIVED‖;
}};
void main()
{
base b,*ptr; derived d; ptr= &b;
ptr->display(); ptr=&d;
ptr->display();
}

Output of the Program


I AM IN BASE
I AM IN DERIVED
Rules for virtual functions
We should observe some basic rules that satisfy the compiler requirements: The
virtual functions must be members of some class.
o They cannot be static members
o They are accessed by using object pointers
o A virtual function can be a friend of another class.
o A virtual function in a base class must be defined, even though it may not be used.
o We cannot have virtual constructors, but we can have virtual destructor.

94
o While a base pointer can point to any type of the derived object, the reverse is not
true.
o 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.

5.3.1 PURE VIRTUAL FUNCTIONS

To declare a function virtual inside the base class and redefine it in the derived
classes. The function inside the base class is seldom (rarely) used for performing any task. for
example ,we have not defined any object of class media and therefore the function display
()in the base class has been defined ‗empty ‗ . Such functions are called;
Such functions are called pure virtual functions. A class containing pure virtual
functions cannot be used to declare any object of its own .such classes are called as abstract
base classes

5.4 C++ Files

The fstream library allows us to work with files.


To use the fstream library, include both the standard <iostream> AND the <fstream>
header file:
#include <iostream>
#include <fstream>

Example
There are three classes included in the fstream library, which are used to create, write
or read files:
Class Description
Ofstream - Creates and writes to files
Ifstream - Reads from files
Fstream - A combination of ofstream and ifstream: creates, reads, and writes to files

Create and Write To a File


To create a file, use either the ofstream or fstream class, and specify the name of the
file.

95
To write to the file, use the insertion operator (<<).
Example
#include <iostream>
#include <fstream>
using namespace std;
int main() {
// Create and open a text file
ofstream MyFile("filename.txt");
// Write to the file
MyFile << "Files can be tricky, but it is fun enough!";

// Close the file


MyFile.close();
}

Why do we close the file?


It is considered good practice, and it can clean up unnecessary memory space.
Read a File
To read from a file, use either the ifstream or fstream class, and the name of the file.
Example
// Create a text string, which is used to output the text file
string myText;
// Read from the text file
ifstream MyReadFile("filename.txt");
// Use a while loop together with the getline() function to read the file line by line
while (getline (MyReadFile, myText)) {
// Output the text from the file
cout << myText;}
// Close the file
MyReadFile.close();

5.5 C++ Exception Handling

96
Exception Handling in C++ is a process to handle runtime errors. We perform
exception handling so the normal flow of the application can be maintained even after
runtime errors. In C++, exception is an event or object which is thrown at runtime. All
exceptions are derived from std::exception class. It is a runtime error which can be handled.
If we don't handle the exception, it prints exception message and terminates the program.
Advantage
It maintains the normal flow of the application. In such case, rest of the code is executed
even after exception.
C++ Exception Classes
In C++ standard exceptions are defined in <exception> class that we can use inside our
programs. The arrangement of parent-child class hierarchy is shown below:

l the exception classes in C++ are derived from std::exception class. Let's see the list of
C++ common exception classes. All the exception classes in C++ are derived from
std::exception class. Let's see the list of C++ common exception classes.

97
++ Exception Handling Keywords
In C++, we use 3 keywords to perform exception handling:
Try, catch, and throw

int main() {
double numerator, denominator, divide;
cout << "Enter numerator: ";
cin >> numerator;
cout << "Enter denominator: ";
cin >> denominator;
try {
// throw an exception if denominator is 0
if (denominator == 0)
throw 0;
// not executed if denominator is 0
divide = numerator / denominator;
cout << numerator << " / " << denominator << " = " << divide << endl;
}
catch (int num_exception) {
cout << "Error: Cannot divide by " << num_exception << endl;
}

98
return 0;
}
Output 1
Enter numerator: 72
Enter denominator: 0
Error: Cannot divide by 0
Output 2
Enter numerator: 72
Enter denominator: 3
72 / 3 = 24

5.6 C++ TEMPLATES

Templates are the foundation of generic programming, which involves writing


code in a way that is independent of any particular type.
A template is a blueprint or formula for creating a generic class or a function. The library
containers like iterators and algorithms are examples of generic programming and have been
developed using template concept.
There is a single definition of each container, such as vector, but we can define many
different kinds of vectors for example, vector <int> or vector <string>.
You can use templates to define functions as well as classes, let us see how they work.
Function Template
The general form of a template function definition is shown here −
template <class type> ret-type func-name(parameter list) {
// body of function
}
Here, type is a placeholder name for a data type used by the function. This name can be used
within the function definition.
The following is the example of a function template that returns the maximum of two values .
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b) {

99
return a < b ? b:a;
}
int main () {
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
If we compile and run above code, this would produce the following result −
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World

Class Template
Just as we can define function templates, we can also define class templates. The general
form of a generic class declaration is shown here − template <class type> class class-name {
.
.
.
}
Here, type is the placeholder type name, which will be specified when a class is
instantiated. You can define more than one generic data type by using a comma-separated
list.
Following is the example to define class Stack<> and implement generic methods to push
and pop the elements from the stack.
// C++ program to demonstrate the use of class templates
#include <iostream>
using namespace std;

100
// Class template
template <class T>
class Number {
private:
// Variable of type T
T num;
public:
Number(T n) : num(n) {} // constructor
T getNum() {
return num;
}
};
int main() {
// create object with int type
Number<int> numberInt(7);

// create object with double type


Number<double> numberDouble(7.7);
cout << "int Number = " << numberInt.getNum() << endl;
cout << "double Number = " << numberDouble.getNum() << endl;
return 0;
}
Output
int Number = 7
double Number = 7.7

101
MODEL QUESTION PAPER
SALEM CHRISTIAN COLLEGE OF ARTS AND SCIENCE
I_MSC (CS) DEGREE EXAMINATION
OBJECT ORIENTED ANALYSIS AND DESIGN& C++
Max.Marks: 75 Time: 3 Hours

SECTION - A (15X1=15)
Answer ALL the Questions.
1. Int occupiesBytes
a) 2 b) 4 c) 1 d) 8
2. C++‘ is often called a ------
a) Object oriented language b) High level language
c) Assembly language d) Machine level language
3. The loop in which the statements within the loop are executed at least once is called
a) do- while b)while c)for d)goto
4. Which bitwise operator is suitable for turning on a particular bit in a number?
a) && operator b)& operator c) || operator d)| operator
5. By default a real number is treated as a
a) Float b) Double c) Long double d) Far double
6. Class=________
a)Methods b)Members c)Methods+Members d) None
7. In Constructor__________
a) Class name and function should be same) b) It is defined in public section
c) It is need not be called d)All the above
8. The keyword try is used in
a) Files b) Templates c) Exception handling d) All of the above
9. In which stage the following code #include<iostream.h> gets replaced by the contents of
the file iostream.h?
a) During editing b) During Linking c)During Executiond)During Processing
10. Example for runtime error
a) Divide by zero b)Missing of semicolon c)0 d) None of the above
11. Which command is used to display the operating system name ?
a)os b) unix c) kernel d) uname
12. Which command gives the first byte where the difference is in the file1 & file2?

102
a) Diff b) cmp c) comm d) LS-a
13. Which Linux command is used to copy files through the command line?
a) cp b) copy c) fcp d)filecopy
14. Which Linux command is used to move files through the command line?
a) move b) mv c) ren d)loc
15. What command is used to print a file?
a) lp b) pg c) prn d) print
SECTION - B (2X5=10)
Answer Any Two Questions.
Explain in brief about the basic concepts of OOPS?
Explain in detail about Control statements in C++.
Explain in detailed about constructors.
Explain in brief about random file handling in C++.
Explain in detail about Exception handling?
SECTION –C (5X10=50 )
Answer ALL Questions.
21. a) Explain in brief structure of C++ programming?
(or)
b) Differentiate between relational and logical operators used in C?
22. a) Explain syntax and use of Do-While statement
(or)
b) Expalin friend function with an example
23. a) Explain the rules for operator overloading?
(or)
b) What is the the need for virtual bas class?
24.a) Explain any two manipulators in detail
(or)
b) What is sequential file? Explain with suitable example
25.a) Explain about Input/Output operation on files.
(or)
b) Explain in detailed about function template .

103
OBJECTIVE QUESTIONS
SALEM CHRISTIAN COLLEGE OF ARTS AND SCIENCE
I_MSC (CS)DEGREE EXAMINATION
OBJECT ORIENTED ANALYSIS AND DESIGN& C++
1. Int occupies --------------- Bytes
a) 2 b) 4 c) 1 d) 8
2. ‗C++‘ is often called a ------
a) Object oriented language b) High level language
c) Assembly language d) Machine level language
3. The loop in which the statements within the loop are executed at least
once is called
a) do- while b)while c)for d)goto
4. Which bitwise operator is suitable for turning on a particular bit in a number?
a) && operator b)& operator c) || operator d)| operator
5. By default a real number is treated as a
a) Float b) Double c) Long double d) Far double
6. Class=
a) Methods b)Members
b) c)Methods+Members d) None
7. In Constructor
a) Class name and function should be same) b) It is defined in public section
c) It is need not be called d)All the above
8. The keyword try is used in
a) Files b) Templates c) Exception handling d) All of the above
9. In which stage the following code #include<iostream.h> gets replaced
by the contents of the file iostream.h?
a) During editing b) During Linking
b) During Executio d)During Processing
10. Example for runtime error
a) Divide by zero b)Missing of semicolon
c)0 d) None of the above

104

You might also like