Você está na página 1de 87

OOPS Concepts using C++

C++ as better C ................................................................................................................... 2


Keys to Object..................................................................................................................... 6
Defining a class in C++ .................................................................................................... 10
Objects and Encapsulation................................................................................................ 16
Messages and Polymorphism............................................................................................ 17
Data Abstraction ............................................................................................................... 19
Natural Building Blocks ................................................................................................... 20
Polymorphism in an application ....................................................................................... 61
Program Using Polymorphism.......................................................................................... 74

L & T Infotech Page 1 of 87


OOPS Concepts using C++
C++ as better C

C++ as better C
C has been in use for over 25 years. Therefore, there is a huge amount of legacy C code in
place. However, once people learn C++, they find its features more powerful than those of C, so
they choose to move to C++.
C++ is a hybrid language, so it is possible to program in either a C-style, an object-oriented style,
or both. Most programmers take advantage of rich collections of existing classes and functions in
C++ classes and the ANSI C standard function library (which C++ borrows from ANSI C).

Therefore, there are two parts to learning C++:


• learning C++ itself
• learning how to use the classes in various C++ class libraries and the functions in the
ANSI C standard library

If you want to mix C and C++ code in a program,


• your C++ compiler should direct the linking process (so it can access its special libraries)
• your C and C++ compilers probably need to come from the same vendor and have
compatible versions (so they have the same calling conventions)

You can include a standard C header file in your C++ code.

 Using C functions in C++


Let's now consider using C functions in C++. It is possible to call functions written and compiled
with a C compiler from a C++ program. However, C++ specially encodes function names for type-
safe linkage while C doesn't encode its function names. So a function compiled in C will not be
recognized when an attempt is made to link C code with C++ code because the C++ code
expects a specially encoded function name.


This function name encoding is often referred to as name mangling

C++ enables you to provide linkage specifications to


• inform the compiler that a function was compiled on a C compiler
• prevent the function name from being encoded by the C++ compiler


Linkage specifications are particularly useful when large libraries of specialized functions have
been developed. They are useful also when another programmer doesn't have access to the
source code of those library functions for recompilation into C++ or time to convert them from C to
C++.
To tell a C++ compiler that one or several functions have been compiled in C, precede the
function prototypes with storage class specifier extern.

L & T Infotech Page 2 of 87


OOPS Concepts using C++
C++ as better C

y
extern "C" function prototype //Single function

extern "C" //Multiple functions


{
function prototypes
}

Using extern means


• name encoding (or name mangling) won't be performed on the functions listed in the
linkage specification

• the specified functions can be linked properly with the program

y
extern "C" function prototype //Single function

extern "C" //Multiple functions


{
function prototypes
}


C++ compilers normally include the standard C libraries, so no need to use linkage specifications
for those functions.

 Object-Oriented Technology
Object oriented programming is essentially building a program around self-contained collections
of data and code to modify that data; this programming model is in contrast to a model that uses
function that act on data scattered throughout a program. Object-oriented programming (or
coding, as programming is commonly referred to) is an organizational style, but it helps
programmers create reusable code because the code to do a specific thing is entirely contained
within a single section of code, and to use the code to perform tasks - for instance, creating a
menu - involves using only a small number of functions to access the internals of the class.

y
A black box that can be easily carried from place to place, and that performs complex actions
simply at the press of a button: for instance, a microwave lets you heat food for a specified time
limit - say, two minutes - by typing in the time and pressing the heat button. You do not need to
know how the microwave operates or why the physics works.

In the same way that self-contained appliances simplify life for the consumer, object-oriented
programming simplifies the transfer of source code from one program to another program by
encapsulating it - putting it all in one place.

Object-oriented technology is both immense and far-reaching. End users of computer systems
and computer-based systems notice the effects of object-oriented technology in the form of
increasingly easy-to-use software applications and operating systems and in more flexible
services being provided by such industries as banking, telecommunications, and cable television.

L & T Infotech Page 3 of 87


OOPS Concepts using C++
C++ as better C
For the software engineer, object-oriented technology encompasses object-oriented programming
languages, object-oriented development methodologies, management of object-oriented projects,
object-oriented computer hardware, and object-oriented computer aided software engineering,
among others.
It is not surprising, therefore, that there is some confusion regarding object-oriented terms and
concepts. Many of the terms commonly used in object-oriented technology were originally used to
describe object-oriented programming (coding) concepts. Specifically, although the terms were
borrowed from a non-computer-software perspective, they were first used extensively to describe
concepts embodied in object-oriented programming languages, such as Smalltalk, C++, and
Eiffel. However, these terms are quite useful even if one never intends to write any software at all.

 The progress of abstraction


All programming languages provide abstractions. It can be argued that the complexity of the
problems you’re able to solve is directly related to the kind and quality of abstraction. Assembly
language is a small abstraction of the underlying machine. Many so-called “imperative” languages
that followed (such as Fortran, BASIC, and C) were abstractions of assembly language. These
languages are big improvements over assembly language, but their primary abstraction still
requires you to think in terms of the structure of the computer rather than the structure of the
problem you are trying to solve. The programmer must establish the association between the
machine model (in the “solution space,” which is the place where you’re modeling that problem,
such as a computer) and the model of the problem that is actually being solved (in the “problem
space,” which is the place where the problem exists). The effort required to perform this mapping,
and the fact that it is extrinsic to the programming language, produces programs that are difficult
to write and expensive to maintain, and as a side effect created the entire “programming
methods” industry.
The alternative to modeling the machine is to model the problem you’re trying to solve. Early
languages such as LISP and APL chose particular views of the world (“All problems are ultimately
lists” or “All problems are algorithmic”). PROLOG casts all problems into chains of decisions.
Languages have been created for constraint-based programming and for programming
exclusively by manipulating graphical symbols. (The latter proved to be too restrictive.) Each of
these approaches is a good solution to the particular class of problem they’re designed to solve,
but when you step outside of that domain they become awkward.
The object-oriented approach goes a step farther by providing tools for the programmer to
represent elements in the problem space. This representation is general enough that the
programmer is not constrained to any particular type of problem. We refer to the elements in the
problem space and their representations in the solution space as “objects.” (Of course, you will
also need other objects that don’t have problem-space analogs.) The idea is that the program is
allowed to adapt itself to the lingo of the problem by adding new types of objects, so when you
read the code describing the solution, you’re reading words that also express the problem. This is
a more flexible and powerful language abstraction than what we’ve had before. Thus, OOP allows
you to describe the problem in terms of the problem, rather than in terms of the computer where
the solution will run. There’s still a connection back to the computer, though. Each object looks
quite a bit like a little computer; it has a state, and it has operations that you can ask it to perform.
However, this doesn’t seem like such a bad analogy to objects in the real world; they all have
characteristics and behaviors.
Some language designers have decided that object-oriented programming by itself is not
adequate to easily solve all programming problems, and advocate the combination of various
approaches into multiparadigm programming languages.[4]
Alan Kay summarized five basic characteristics of Smalltalk, the first successful object-oriented
language and one of the languages upon which C++ is based.

These characteristics represent a pure approach to object-oriented programming:

L & T Infotech Page 4 of 87


OOPS Concepts using C++
C++ as better C
1. Everything is an object.

Think of an object as a fancy variable; it stores data, but you can “make requests” to that
object, asking it to perform operations on itself. In theory, you can take any conceptual
component in the problem you’re trying to solve (dogs, buildings, services, etc.) and
represent it as an object in your program.

2. A program is a bunch of objects telling each other what to do by sending


messages.

To make a request of an object, you “send a message” to that object. More concretely, you
can think of a message as a request to call a function that belongs to a particular object.

3. Each object has its own memory made up of other objects.

Put another way, you create a new kind of object by making a package containing
existing objects. Thus, you can build complexity in a program while hiding it behind the
simplicity of objects.

4. Every object has a type.

Using the parlance, each object is an instance of a class, in which “class” is synonymous
with “type.” The most important distinguishing characteristic of a class is “What messages
can you send to it?”

5. All objects of a particular type can receive the same messages.

This is actually a loaded statement, as you will see later. Because an object of type
“circle” is also an object of type “shape,” a circle is guaranteed to accept shape
messages. This means you can write code that talks to shapes and automatically
handles anything that fits the description of a shape. This substitutability is one of the
most powerful concepts in OOP.

L & T Infotech Page 5 of 87


OOPS Concepts using C++
Keys to Object

Keys to Object

Why Objects?
The chasm between conventional software development and true, object-oriented development is
not easily crossed. A company really has to want to be on the other side in order to make the leap
successfully. So, it's only fair to begin with the most basic question: Why bother?

The answer, in a nutshell, is this:


Objects are the enabling technology for adaptive business systems.

 The Adaptive Organization


Natural selection, the engine of adaptation in all living systems, has just shifted into high gear. It
is now operating at the level of organizations rather than organisms, and the cycle of adaptations
is measured in months rather than millennia. The competitive environment of business is
continuously changing, and the pace of that change is increasing at an accelerating rate. Where it
was once possible for a company to stake out its marketing turf and defend its position for years,
static positioning is now viable only in a few isolated industries. For most companies today, the
only constant is change.
How is a company to cope with this kind of change? The message from the management gurus is
clear and consistent: The key to survival in today's chaotic business environment is rapid
adaptation. The adaptive organization can move quickly into new market niches, deliver custom
solutions instead of fixed products, and continuously outmaneuver its competition in the ongoing
battle for market share.
Unfortunately, it's a lot easier to preach the benefits of adaptivity than to realize them.
Organizations have a natural inertia that inhibits any change in direction, and that inertia
increases with the mass of the company. Much of the resistance stems from human nature—
people stake out their turf within organizations and tend to oppose any change that threatens
their position. Reward structures keyed to quarterly earnings only serve to reinforce the status
quo and discourage rapid change. But even if all the human and organizational barriers to change
could be overcome, there is another source of inertia with a mass approximating that of a black
hole—namely, corporate information systems.

 From Productivity to Adaptivity


The software construction primer in the appendix offers a quick overview of the way we build
information systems and how that approach has evolved over the past 50 years. Although
information systems now allow organizations to do things that would have been unthinkable prior
to the advent of computers, there is one thing they hinder far more than help: the process of
change. Large information systems are notoriously resistant to change, so much so that many
companies find themselves locked in place by the very systems that helped them to become
competitive just a few short years ago.
For many years, the standard answer to this problem was to increase the speed of software
development. Fourth-generation languages (4GLs), computer-aided software engineering (CASE)
tools, and yes, object technology, have all promised and failed to deliver the "order-of-magnitude
productivity improvement" that has long served as the holy grail of software development.
Although I remain convinced that objects can deliver on that promise, I no longer believe it is the
right goal. We have passed the point where building new applications faster can solve the
problem. No matter how much we accelerate the development process, the increasing pace of
business change will continue to outstrip our ability to create new software.
The only enduring solution to the challenge of constant change lies in the development of
adaptive business systems—systems that can change at least as fast as the organizations they

L & T Infotech Page 6 of 87


OOPS Concepts using C++
Keys to Object
support. This is a radical departure from the time-honored practice of developing new applications
from scratch to meet new business requirements. It requires us to construct software systems of
sufficient flexibility that they can quickly be modified in response to new opportunities and
challenges. In short, the answer lies not in productivity but in adaptivity.

 The Enabling Technology


The key benefit of object technology is that it is the enabling technology for adaptive business
systems. However, this adaptivity is not an automatic consequence of adopting objects. Many
companies are using objects simply as a different tool for doing what they have always done—
creating new applications to solve specific business problems. Objects themselves are naturally
adaptive units of software, but they lose all their flexibility if they are locked into conventional
applications.
The key to building adaptive systems is to understand and uphold the principles of object
technology at every level of a system, from the lowest-level object to the enterprise itself.
Fortunately, this isn't very hard to do. The most difficult part is simply getting out of the way—
setting aside our preconceptions of how software should be built and discovering where objects
will take us if we remain true to their principles as we build our way up to the enterprise.

 The Three Keys


The definition of object technology has been a source of debate throughout its history.
However, there is an industry-standard definition of object-oriented technology, and it can be
summarized in terms of three key concepts:
1. Objects that provide encapsulation of procedures and data

2. Messages that support polymorphism across objects

3. Classes that implement inheritance within class hierarchies


These three concepts and their associated terminology are explained in the remaining sections of
this chapter. But even without further explanation, the three concepts can be used to make a
distinction between languages that are and are not object-oriented.
The object languages that are most widely used in commercial applications are Smalltalk,
C++, and Java. Eiffel has gained widespread acceptance in Europe; the latest version of Ada
qualifies as object-oriented; and Object COBOL is finally making its way into the market. Of all the
object languages currently available, Java is having the greatest impact on the industry and
shows the most promise for building adaptive business systems.
By contrast, the original versions of C, Ada, and COBOL are anything but object-oriented. Closer
to the border are languages like Visual Basic (VB), which began as a conventional language but
now supports most of the mechanisms of object technology. As you can see from the examples,
many languages are adding object features, so the list of options is constantly growing. Visual
Basic is a good illustration of this—all that version 5 lacks is inheritance, and VB could very well
be fully object-oriented in its next release. The important point is not whether a language is "truly"
object-oriented but how easy it is to apply the principles of objects in the environment provided by
the language.

 Object & Class


Aristotle was probably the first to begin a careful study of the concept of type; he spoke of “the
class of fishes and the class of birds.” The idea that all objects, while being unique, are also part
of a class of objects that have characteristics and behaviors in common was used directly in the
first object-oriented language, Simula-67, with its fundamental keyword class that introduces a
new type into a program.

L & T Infotech Page 7 of 87


OOPS Concepts using C++
Keys to Object
Simula, as its name implies, was created for developing simulations such as the classic “bank
teller problem.” In this, you have a bunch of tellers, customers, accounts, transactions, and units
of money – a lot of “objects.” Objects that are identical except for their state during a program’s
execution are grouped together into “classes of objects” and that’s where the keyword class
came from. Creating abstract data types (classes) is a fundamental concept in object-oriented
programming. Abstract data types work almost exactly like built-in types: You can create
variables of a type (called objects or instances in object-oriented parlance) and manipulate those
variables (called sending messages or requests; you send a message and the object figures out
what to do with it). The members (elements) of each class share some commonality: every
account has a balance, every teller can accept a deposit, etc. At the same time, each member
has its own state, each account has a different balance, each teller has a name. Thus, the tellers,
customers, accounts, transactions, etc., can each be represented with a unique entity in the
computer program. This entity is the object, and each object belongs to a particular class that
defines its characteristics and behaviors.

So, although what we really do in object-oriented programming is create new data types, virtually
all object-oriented programming languages use the “class” keyword. When you see the word
“type” think “class” and vice versa.

Since a class describes a set of objects that have identical characteristics (data elements) and
behaviors (functionality), a class is really a data type because a floating point number, for
example, also has a set of characteristics and behaviors. The difference is that a programmer
defines a class to fit a problem rather than being forced to use an existing data type that was
designed to represent a unit of storage in a machine. You extend the programming language by
adding new data types specific to your needs. The programming system welcomes the new
classes and gives them all the care and type checking that it gives to built-in types.

The object-oriented approach is not limited to building simulations. Whether or not you agree that
any program is a simulation of the system you’re designing, the use of OOP techniques can
easily reduce a large set of problems to a simple solution.

Once a class is established, you can make as many objects of that class as you like, and then
manipulate those objects as if they are the elements that exist in the problem you are trying to
solve. Indeed, one of the challenges of object-oriented programming is to create a one-to-one
mapping between the elements in the problem space and objects in the solution space.

But how do you get an object to do useful work for you? There must be a way to make a request
of the object so that it will do something, such as complete a transaction, draw something on the
screen or turn on a switch. And each object can satisfy only certain requests. The requests you
can make of an object are defined by its interface, and the type is what determines the interface.

A simple example might be a representation of a light bulb:

L & T Infotech Page 8 of 87


OOPS Concepts using C++
Keys to Object

Light lt;
lt.on();

The interface establishes what requests you can make for a particular object. However, there
must be code somewhere to satisfy that request. This, along with the hidden data, comprises the
implementation. From a procedural programming standpoint, it’s not that complicated. A type has
a function associated with each possible request, and when you make a particular request to an
object, that function is called. This process is usually summarized by saying that you “send a
message” (make a request) to an object, and the object figures out what to do with that message
(it executes code).
Here, the name of the type/class is Light, the name of this particular Light object is lt, and the
requests that you can make of a Light object are to turn it on, turn it off, make it brighter or make
it dimmer. You create a Light object by declaring a name (lt) for that object. To send a message
to the object, you state the name of the object and connect it to the message request with a
period (dot). From the standpoint of the user of a pre-defined class, that’s pretty much all there is
to programming with objects.
The diagram shown above follows the format of the Unified Modeling Language (UML). Each
class is represented by a box, with the type name in the top portion of the box, any data members
that you care to describe in the middle portion of the box, and the member functions (the
functions that belong to this object, which receive any messages you send to that object) in the
bottom portion of the box. Often, only the name of the class and the public member functions are
shown in UML design diagrams, and so the middle portion is not shown. If you’re interested only
in the class name, then the bottom portion doesn’t need to be shown, either.

 Classes
Structured programming languages use functions to structure a program. C++, on the other
hand, provides both functions and classes. Data abstraction is implemented in C++ by the class
user-defined datatype.

Classes in C++ evolved from the C struct concept. A struct represents one or more data values,
which can be manipulated in a manner similar to individual variables.

Access to a struct is not restricted – so once a struct variable is within scope, it can be modified.
In C++, you use classes to define new datatypes as encapsulations of data and operations.

Each class contains data as well as the set of functions that manipulates that data. The data
components of a class are called data members. And the function components of a class are
called member functions.

L & T Infotech Page 9 of 87


OOPS Concepts using C++
Object and Encapsulation

Defining a class in C++

1. Defining classes
C++ provides data abstraction through the class construct. This is a typical class definition.
y
class clock
{
private :
short tHour;
short tMin;
short tSec;

public:
void set_time(int,int,int);
void disp_time();

}stopwatch;

A class
• encapsulates data
• names the class
• controls access to functions by means of the private, public, and protected keywords
• declares instances of the class (if any)

y
int x=20;
main()
{
int x;
x=10;
}
class clock
{
private :
short tHour;
short tMin;
short tSec;

public:
void set_time(int,int,int);
void disp_time();
}stopwatch;


Class instances are created when you declare a variable of the class type.

L & T Infotech Page 10 of 87


OOPS Concepts using C++
Object and Encapsulation
By default, the members of a class are private. This means they can only be accessed by other
class members.The following are some guidelines for declaring a class:

• all members should be defined as private, public, or protected


• members that have the same access control should be kept together

y
int x=20;
main()
{
int x;
x=10;
}

#include <iostream.h>
class date
{
private :
short dd;
short mm;
short yy;

public:
void set_date();
short validate();
short find_day();

};

The code in the example declares data members.


Data members of a class must not be directly initialized as in the next code.

y
int x=20;
main()
{
int x;
x=10;
}

short mm=12;
#include <iostream.h>
class date
{
private :
short dd;
short mm=12;
short yy;

L & T Infotech Page 11 of 87


OOPS Concepts using C++
Object and Encapsulation
public:
void set_date();
short validate();
short find_day();

};

Member function declarations are similar to function declarations.


For example, the member function validate() in short validate ( ); is declared as taking no
arguments and returning a value of the short datatype.

y
int x=20;
main()
{
int x;
x=10;
}

#include <iostream.h>
class date
{
private :
short dd;
short mm=12;
short yy;

public:
void set_date();
short validate();
short find_day();
};

 Declaring class instances


Instances of a class can be declared in a number of ways. An instance is a single occurrence of
a class.

For example, an instance of the class clock could be stopwatch.

y
int x=20;
main()
{
int x;
x=10;
}

class clock
{

L & T Infotech Page 12 of 87


OOPS Concepts using C++
Object and Encapsulation
private :
short tHour;
short tMin;
short tSec;

public:
void set_time(int,int,int);
void disp_time(); } stopwatch, digital, analog;

You can define a class instance by specifying an instance name in the part of the structure called
the instance list.

The above code defines three instances of the class clock.


You can define an instance of a class separately from the class declaration.

A class instance may also be defined by using the keyword class followed by the class name and
a unique identifier.

In this case, the code is class numbers.


An instance of the class numbers is declared in class numbers no;

y
int x=20;
main()
{
int x;
x=10;
}

class numbers
{
private :
short x, y, z;
public:
void InitNumbers (short nx, short ny);
void getZ(void);
void displayZ(void);
};

}
void main (void)
{
class numbers no;
no.InitNumbers (1, 2);
no.getZ();
no.displayZ();
};
The datatype specifier class is dropped from the definition in numbers no;.

The compiler recognizes the class name "numbers" from its previous declaration and creates an
instance of that class called "no".

Because of this, the keyword class is usually dropped from the definition.

L & T Infotech Page 13 of 87


OOPS Concepts using C++
Object and Encapsulation

 Accessing classes
In a class construct you can control access to class members by using the public,
private, and protected access control specifiers.

Data members of a class are usually private, though they can be public.

Private data members can only be accessed by other members of their class.
Public functions can be accessed outside their class.

This means that private members can be accessed through public access or member functions.
A class's data and function members belong to that class's scope in

short date :: validate ()


C++ requires that a member function definition specifies the class for which it is in scope.

This is done by using the :: scope resolution operator in the header of the definition.
Resolving the scope of the get_data() function means that the private data members dd, mm, yy
can be accessed.

y
int x=20;
main()
{
int x;
x=10;
}

private:
short dd;
short mm;
short yy;

public:
void get_data(short, short, short);
}

void date :: get_data(short d,short m,short y)


{
dd = d;
mm = m;
yy = y;
}

main ()
{
short c;
short day_of_the_week;
date sd; }

L & T Infotech Page 14 of 87


OOPS Concepts using C++
Object and Encapsulation
Class members can be accessed using the dot operator (.) as in
day.validate ();

The dot operator accesses a class member by means of the variable name for the object or a
reference to the object. The dot operator can be used to access public members of a class only
when the instance of a class being accessed is named.

date day ;
day.validate ();


The dot operator is used with the public function to validate the user's input.

A class's data and function members belong to that class's scope, C++ requires that a member
function definition specify the class for which it is in scope, and class members can be accessed
using the dot operator.

L & T Infotech Page 15 of 87


OOPS Concepts using C++
Object and Encapsulation

Objects and Encapsulation

Although object technology came into the commercial limelight relatively recently, it's actually
more than 25 years old. All the basic concepts of the object approach were introduced in the
Simula programming language developed in Norway during the late 1960s.

 Modeling Physical Objects


Simula, an acronym for "simulation language," was created to support computer simulations of
real-world processes. The authors of Simula, O. J. Dahl and Kristen Nygaard, wanted to build
accurate working models of complex physical systems that could contain many thousands of
components.

It was apparent even back in the 1960s that modular programming is essential for building
complex systems, and modularization played a central role in the design of Simula. What is
special about Simula is the way in which modules are defined. They are not based on
procedures, as they are in conventional programming. In Simula, modules are based on the
physical objects being modeled in the simulation.
This choice makes a lot of sense because the objects in a simulation offer a very natural way of
breaking down the problem to be solved. Each object has a range of behavior to be modeled, and
each has to maintain some information about its own status. The interaction of these objects
defines the simulation. Why look for some other way to package procedures and data when the
real world has already organized them for you?

 Inside Objects
The concept of software objects arose out of the need to model real-world objects in computer
simulations. An object is a software package that contains a collection of related procedures and
data. These procedures are often called methods to distinguish them from conventional
procedures that aren't attached to objects. In keeping with traditional programming terminology,
the data elements are usually referred to as variables because their values can vary over time.

y
Consider how you might represent an automated guided vehicle (AGV) in the simulation of a
factory. The vehicle can exhibit a variety of behaviors, such as moving from one location to
another or loading and unloading its contents. It must also maintain information about its
characteristics (pallet size, lifting capacity, maximum speed, and so on) as well as its current
state (contents, location, orientation, and velocity).
To represent the vehicle as an object, you would program its behaviors as methods and declare
variables to contain information about its characteristics and states. During the simulation, the
object would carry out its various methods, changing its variables as needed to reflect the effects
of its actions.

The concept of an object is simple yet powerful. Objects make ideal software modules because
they can be defined and maintained independently of one another, with each object forming a
neat, self-contained universe. Everything an object "knows" is captured in its variables, and
everything it can do is expressed in its methods.

L & T Infotech Page 16 of 87


OOPS Concepts using C++
Data Abstraction

Messages and Polymorphism

Sending a Message
Real-world objects can exhibit an infinite variety of effects on one another—creating, destroying,
lifting, attaching, buying, bending, sending, and so on. This tremendous variety raises an
interesting problem: How can all these different kinds of interactions be represented in software?
The authors of Simula came up with an elegant solution to this problem: the message. The way
objects interact with one another is to send messages asking objects to carry out their methods.
A message is simply the name of an object followed by the name of a method
the object knows how to execute. If a method requires any additional information in order to
know precisely what to do, the message includes that information as a collection of data elements
called parameters. The object that initiates a message is called the sender of that message,
and the object that receives the message is called the receiver.

y
To make an automated vehicle move to a new location, for example, some other object might
send it the following message:
vehicle104 moveTo: binB7
In this example, vehicle104 is the name of the receiver, moveTo is the method it is being asked
to execute, and binB7 is a parameter telling the receiver where to go.

In order for a message to make sense, the sender and receiver must agree on the format of the
message. This format is stipulated in a message signature that specifies the name of the
method to be executed and the parameters to be included. The moveTo message in the
present example has a simple signature: Its name is moveTo, and it sends one parameter,
which must be a location. The signature requires all senders of this message to identify it by that
name and to supply exactly one parameter of the correct type. In the context of object
interactions, the shorter term signature is often used.
An object program, then, consists of a number of objects interacting by sending messages to one
another. Since everything an object can do is expressed by its methods, this simple mechanism
supports all possible interactions between objects.

 Responding to a Message
The fact that methods are always associated with specific objects has an interesting side effect
that turns out to be highly advantageous. Different objects can respond to the same generic
message, but each object can interpret the message in a different way. For example, a truck
object could implement its own version of the moveTo message, as could a ship, a train, an
aircraft, a person, or anything else that moves. The way these real-world objects determine their
routes, plan their movements, and carry out these movements differs radically. But all of them
would understand a common request to go to a specified destination.
The ability of different objects to respond to the same message in different ways is called
polymorphism, a Greek term meaning "many forms." The term can be intimidating, and
polymorphism is often considered an advanced concept in object technology. But the basic idea
couldn't be simpler: Each object can have a unique response to the same message.

For most business people, polymorphism is so obvious that they have a hard time seeing what is
so special about it. The reason is that human communication is naturally polymorphic. You can
ask a dozen people the same question and they could all determine their answers in a different
way, but the meaning of the question and the form of the answer would be the same across all of

L & T Infotech Page 17 of 87


OOPS Concepts using C++
Data Abstraction
them. You don't much care about their private mental processes; you just want to hear their
answers. All polymorphism does is allow object interactions to enjoy some of the same flexibility
as human interactions.

The real surprise to most business people is that software doesn't normally work this way. In
conventional programming, procedures aren't attached to objects, and every name must be
unique. This means that you would have to call a different procedure for each kind of object in
order to get it to do something different. The simple moveTo message would turn into an open-
ended list of specialized requests: AGVMoveTo, truckMoveTo, shipMoveTo,
trainMoveTo, aircraftMoveTo, personMoveTo, and so on. It seems like a rather
cumbersome way to build software in retrospect, but there was no other way to do it prior to
objects.

L & T Infotech Page 18 of 87


OOPS Concepts using C++
Data Abstraction

Data Abstraction
Sometimes, a simulation involves only a single example of a particular kind of object. It is much
more common, however, to need more than one object of each kind. An automated factory, for
example, might have any number of guided vehicles. This possibility raises another concern: It
would be extremely inefficient to redefine the same methods in every single occurrence of that
object.

 Templates for Objects


Here again, the authors of Simula came up with an elegant solution: the class. A class is a
software template that defines the methods and variables to be included in a particular kind of
object. The methods and variables that make up the object are defined only once, in the definition
of the class. The objects that belong to a class—commonly called instances of that class—
contain only their own particular values for the variables.

To continue the previous example, a simulated factory might contain many automated vehicles,
each of which carried out the same actions and maintained the same kinds of information. All
such vehicles would be represented by a class called AutomatedVehicle, which would define its
methods and variables. The actual vehicles would be represented by instances of this class, each
with its own unique identity (vehicle101, vehicle102, vehicle103, and so on). Each of these
instances would contain data values that represented its own particular contents and location.
Another important function of classes is to specify the messages that objects of this kind will
make available to other objects. The set of messages an object commits to respond to is called
its message interface. This interface is specified as a collection of message signatures,
each of which defines the name and parameters for a particular message. The only design
requirement placed on a class is that it provide a method to implement each message specified in
its interface. The internals of the class are completely hidden behind this interface and may
include any number of variables as well as "invisible" methods that are used only by the object
itself.

An object, then, is an instance of a particular class. Its methods and variables are defined in the
class, and its values are stored in the instance. To keep my explanations simple, I usually talk
about objects wherever possible, referring to classes and instances only when it's important to
point out where the object's information is actually stored. For example, if I say that the object
vehicle104 has a method called moveTo, this is simply a more convenient way of saying that
vehicle104 is an instance of a class that defines a method called moveTo.

 Inheriting Class Information


Simula took the concept of classes one step further by allowing classes to be defined as special
cases of each other. If you needed to represent two different kinds of automated vehicle, you
could define one vehicle class in detail and then define the other as everything in the first class
plus any additional methods and variables you wanted to add. Simply by declaring the second
class to be a special case of the first, you would automatically give it access to everything the first
class could do.
The mechanism whereby one class of objects can be defined as a special case of a more general
class is known as inheritance. Special cases of a class are commonly known as
subclasses of that class; the more general class, in turn, is known as the superclass of its
special cases. In addition to the methods and variables they inherit, subclasses may define their
own methods and variables. They can also redefine any of the inherited methods, a technique
known as overriding.

L & T Infotech Page 19 of 87


OOPS Concepts using C++
Data Abstraction

y
The class AutomatedVehicle could be broken down into two subclasses, PalletAGV and
RollAGV, each of which will inherit the general characteristics of the parent class. Either
subclass could establish its own special characteristics by adding to the parent's definition or by
overriding its behavior.

Because classes define message interfaces, these interfaces are also inherited by their
subclasses. This means that all the subclasses of a given class are guaranteed to respond to any
messages that can be handled by the parent class. This is an extremely useful property because
it allows us to treat all the specialized forms of a class as equivalent at the general level.

y
if we define a Product class that includes messages for production, pricing, and shipping in its
interface, then we have an ironclad guarantee that all the subclasses of Product will implement all
these messages.
Any given subclass may use the implementations it inherits from Product, or it may define its own
implementations; it doesn't matter to us at this level. What matters is that we can design our
system to produce, price, and ship an unlimited variety of products without having to be
concerned about how each specialized type carries out these tasks.

 Hierarchies of Classes
Classes can be nested to any degree, and inheritance will automatically accumulate down
through all the levels. The resulting treelike structure is known as a class hierarchy. A class
called Part, for example, could be broken down into special kinds of parts such as Motor,
Chassis, Connector, and so on. Motor, in turn, could be divided into DriveMotor and
SteppingMotor, each of which could be broken down further as needed. An instance of, say,
VariableSpeedDriveMotor would inherit all the characteristics of the Part class, as well
as those of Motor and DriveMotor.

Class hierarchies increase the ability of objects to reflect the way we view the real world. Human
knowledge is often organized in a hierarchical manner, relying on generic concepts and their
refinement into increasingly specialized cases. Object technology takes the same conceptual
mechanisms we employ in everyday life and uses them to build sophisticated yet understandable
software systems. This is particularly evident in the generalization and specialization provided by
a class hierarchy.

Natural Building Blocks


Object programming is often said to be more natural than traditional programming, and this is true
on a couple of different levels. On one level, object programming is more natural because it
allows us to organize information in ways that are familiar to us, as illustrated in the class
hierarchies described in the preceding chapter. On a deeper level, it is more natural in that it
reflects nature's own techniques for managing complexity. This chapter opens and closes with
brief looks at the structure of living organisms to establish a framework for understanding the
adaptive nature of objects. The remainder of the chapter looks at the actual technology
underlying objects and demonstrates why objects provide a better foundation for flexible business
systems.
The basic building block out of which all living things are composed is the cell. Cells are organic
"packages" that, like objects, combine related information and behavior. Most of the information is

L & T Infotech Page 20 of 87


OOPS Concepts using C++
Data Abstraction
contained in protein molecules within the nucleus of the cell. The behavior, which may range from
energy conversion to movement, is carried out by structures outside the nucleus.
Cells are surrounded by a membrane that permits only certain kinds of chemical exchanges with
other cells. This membrane protects the internal workings of the cell from outside intrusion, and it
also hides the complexity of the cell and presents a relatively simple interface to the rest of the
organism. All interactions between cells take place through chemical messages recognized by
the cell membrane and passed through to the inside of the cell.

This message-based communication greatly simplifies the way cells function. The cells don't have
to read each others' protein molecules or control each others' structures to get what they need
from each other. All they do is send the appropriate chemical message, and the receiving cell
responds accordingly.

The cell is truly a universal building block. All cells share a common structure and operate
according to the same basic principles. Within this generic structure, however, infinite variability is
possible. For example, plant cells have a hard outer wall to make them rigid; blood cells are
mobile and specialized to transport gases; and muscle cells are able to distort their shape to
perform mechanical work. But this tremendous variability is not chaotic; it's all neatly organized—
or "classified"—in a hierarchy of specialized types and subtypes. The accompanying diagram
gives the merest hint of the depth and breadth of this diversity.

Objects, as defined in object technology, have many of the essential characteristics of living cells.
A closer look inside the structure of an object reveals some of these similarities.

 The Anatomy of an Object


Packaging related data and procedures together is called encapsulation. As you can see
from the structure of a cell, encapsulation is an idea that has been around for a very long time.
The fact that it has worked so well in natural systems suggests that we may be on the right track
with this mechanism!

Encapsulating Objects
The key to object encapsulation is the message interface. As the accompanying illustration
indicates, this interface surrounds the object and acts as the point of contact for all incoming
messages. The message interface serves the same function as the membrane of a cell—to
provide an essential barrier between the internal structure of the object and everything that lies
outside the object. Like a cell's membrane, the message interface ensures that all interactions
with the object take place through a predefined system of messages that the object is guaranteed
to understand and handle correctly.

The encapsulation mechanism of object technology is a natural extension of the information-


hiding strategy developed in structured programming, as described in the software construction
primer in the appendix. Object technology improves on this strategy with better mechanisms to
pull the right kinds of information together, including all related data and procedures, and hide
their details more effectively. There is simply no way for any other object to access the data or
methods hidden behind an object's interface.

y
Data inside an object is accessed only by methods that implement the object's interface. Just as
cells don't "read" each others' protein molecules, objects don't touch each others' data structures.
Rather, objects send each other messages that call methods into action. These methods, in turn,
access the required variables.

L & T Infotech Page 21 of 87


OOPS Concepts using C++
Data Abstraction
This same mechanism also controls access to methods that are used only by the object itself. For
example, determining the price of a product can require a complex set of interacting calculations,
each of which could involve a number of methods and variables. Allowing other objects to trigger
these internal methods directly could create havoc within the object. To prevent this kind of
disruption, the object hides all of its pricing logic behind an interface that only allows other objects
to inquire about its current price or set a new base price for future calculations.
Message interfaces offer two important kinds of protection. First, they protect an object's internal
components from being corrupted by other objects. If other objects had direct access to an
object's variables and internal methods, eventually one of these other objects would handle a
variable incorrectly or call the wrong method and damage the object. An object protects itself
from this kind of error by hiding its variables and internal methods behind its message interface.
The second and less obvious kind of protection works in the opposite direction. By hiding its
variables and internal methods, an object protects other objects from depending on its internal
structure. For example, they are spared having to keep track of each variable's name, the type of
information it contains, the amount of space it takes up in storage, and a host of other details that
would complicate all their procedures for accessing an object's variables. With encapsulation, an
object only needs to know how to ask another object for information. All the details about how that
information is stored are neatly tucked out of sight behind the message interface.

 Facilitating Changes
In addition to simplifying the interactions between objects, encapsulation also makes the
modification of objects much easier than it would otherwise be. Hiding all the implementation
details of an object inside its message interface allows the object to be modified extensively in
response to changing business needs. As long as the portions of the message interface currently
in use by other objects remain intact, internal modifications won't require changes to any other
part of the system.
Consider making the following change to the AutomatedVehicle class discussed in the preceding
chapter. When you first defined the class, you declared a fixed carrying capacity for the vehicle
and stored it in a variable. Subsequently, you discover that you need to perform one of several
different calculations to determine capacity depending on the kind of load involved. To make this
change, you remove the capacity variable and define a set of internal methods for calculating
capacity. Each of these methods might require one or more variables, so you add these variables
as needed. Finally, you perform the switchover—you change the load method to call your new
methods to verify that the vehicle can handle the load.

In a conventional system, this change would require significant restructuring. You would need to
rewrite all the subroutines in the system that dealt with vehicle carrying capacities to make them
call functions rather than access a data value. You would have to repeat the same selection logic
for using the correct calculation in all the affected subroutines. Every routine that needed to
determine capacity would have to be changed; all these changes would have to be made
correctly; and all these changes would have to be synchronized to occur at the same time.
Anything less would result in a broken system.
In short, modeling the automated vehicle as a self-contained object allows you to restrict all your
changes to a single object. There is no duplication of the selection logic, no doubt about whether
all the necessary subroutines have been modified, and no synchronization problem. Just modify
the AutomatedVehicle class, and you're done. All other objects continue to interact with it just as
they did before. You have made a fundamental change in how information is handled, converting
it from data to a collection of specialized procedures, and none of the other objects even "know"
that a change has taken place!

L & T Infotech Page 22 of 87


OOPS Concepts using C++
Data Abstraction

 Using Composite Interfaces


In most cases, the message interface surrounding an object is a single, unbroken surface.
However, it is possible to divide this interface into segments by first defining some simpler
interfaces and then combining them into a composite interface for a particular object. This
technique can be used to further protect the internals of objects by giving other objects access
only to selected components of the object's overall interface.
For example, the message interface for a Product object might be composed of four component
interfaces: one for defining the product, a second for producing it, a third for selling it, and a fourth
for shipping it. Each of these interfaces deals with very different aspects of the product and would
be accessed by different parts of the company

manufacturing interface. Only the manufacturing object would be affected by Notice that the
segmentation of the message interface increases the two kinds of protection described earlier.
First, other objects can't access methods they have no right to invoke. A Sale object, for example,
couldn't get access to the manufacturing interface to change the production schedule for a
product. Second, other objects are protected from changes to interfaces they don't have access
to. If a change in the way a product was manufactured required changes to the interface of the
Product object, these changes would be restricted to the the changes—the marketing, sales, and
shipping objects would be completely unaffected.

 Objects Inside Other Objects


The variables contained within objects can be used in two different ways. First, they can be used
to store data values, such as the number 12.5 or the text string "Approved." More interestingly,
they can contain references to other objects. The form of the reference is an implementation
detail and varies considerably among object systems. The important point is that the reference
held by a variable provides the containing object with a "handle" or effective address for the
contained object, allowing the containing object to manage its component by sending it
appropriate messages.

Objects that contain other objects are called composite objects. Composite objects are
important because they can represent far more sophisticated structures than simple objects can.
y
An aircraft consists of wings, engines, and other components that are far too complex to be
represented as simple numbers or text.

The objects contained in composite objects may themselves be composite objects, and this
nesting can be carried out to any number of levels. The major components of an aircraft, for
example, are very complex objects in their own right. In any reasonable model of an aircraft, each
of these components would be represented by a composite object that, in all likelihood, would be
composed of still more composite objects, and so on.

 Collections of Objects
There is a special kind of class, often called the collection class, that can be found in the class
library shipped with most commercial languages. As the name suggests, the basic function of a
collection is to gather together objects that must be managed as a group. In a model of an
aircraft, for example, we wouldn't create a separate named variable for every seat object. Rather,

L & T Infotech Page 23 of 87


OOPS Concepts using C++
Data Abstraction
we would gather all the seat objects into a collection and place a reference to that collection in a
single variable called Seats.

This example illustrates how collections can simplify composite objects while also making them
more flexible. In addition to reducing several hundred variables down to one, the Seats collection
allows us to vary the number of seats without reprogramming the model. In addition, the
collection makes it easier to carry out group operations on the seats, such as scanning them to
see which ones are currently reserved. The method that performed this task would repeatedly ask
the collection for its next element until the collection reported that it was empty. This is much
simpler than writing a method to examine several hundred named variables.

 The Benefits of Composition


Because objects can be composed of other objects, object languages can represent real-world
objects at the level we naturally think about them. Even a complex, deeply nested structure such
as a jet aircraft can be treated as a single, unified object. And since that complex object can have
its own behavior, other objects can use it with very little awareness of its internal complexity. This
is a good example of how object technology can bring order to large-scale systems. Composite
objects not only keep simple things simple, they can make complex things simple as well.
Composite objects offer another important advantage—they lay the foundation for a mechanism
called delegation, in which an object assigns a task to another object. Delegation is a very
common pattern in object designs because it supports the division of labor encouraged by
objects.

y
Determining the charge for a telephone call is a fairly complex process because the charge can
be based on physical distance, arbitrary zones, or other factors. Rather than building this
complexity directly into a Call object, we could give Call a component Rater to perform this
task. Then, the Call could simply send its end points and duration to the Rater and get back the
appropriate charge. Because it would not know anything about how the Rater did its work, any
kind of Rater could be placed in the Call without affecting the behavior of the Call object in
any way.

 The hidden implementation


It is helpful to break up the playing field into class creators (those who create new data types) and
client programmers (the class consumers who use the data types in their applications). The goal
of the client programmer is to collect a toolbox full of classes to use for rapid application
development. The goal of the class creator is to build a class that exposes only what’s necessary
to the client programmer and keeps everything else hidden. Why? Because if it’s hidden, the
client programmer can’t use it, which means that the class creator can change the hidden portion
at will without worrying about the impact to anyone else. The hidden portion usually represents
the tender insides of an object that could easily be corrupted by a careless or uninformed client
programmer, so hiding the implementation reduces program bugs. The concept of
implementation hiding cannot be overemphasized.

In any relationship it’s important to have boundaries that are respected by all parties involved.
When you create a library, you establish a relationship with the client programmer, who is also a
programmer, but one who is putting together an application by using your library, possibly to build
a bigger library.

L & T Infotech Page 24 of 87


OOPS Concepts using C++
Data Abstraction
If all the members of a class are available to everyone, then the client programmer can do
anything with that class and there’s no way to enforce rules. Even though you might really prefer
that the client programmer not directly manipulate some of the members of your class, without
access control there’s no way to prevent it. Everything’s naked to the world.

So the first reason for access control is to keep client programmers’ hands off portions they
shouldn’t touch – parts that are necessary for the internal machinations of the data type but not
part of the interface that users need in order to solve their particular problems. This is actually a
service to users because they can easily see what’s important to them and what they can ignore.
The second reason for access control is to allow the library designer to change the internal
workings of the class without worrying about how it will affect the client programmer. For
example, you might implement a particular class in a simple fashion to ease development, and
then later discover that you need to rewrite it in order to make it run faster. If the interface and
implementation are clearly separated and protected, you can accomplish this easily and require
only a relink by the user.

C++ uses three explicit keywords to set the boundaries in a class: public, private, and
protected. Their use and meaning are quite straightforward. These access specifiers determine
who can use the definitions that follow. public means the following definitions are available to
everyone. The private keyword, on the other hand, means that no one can access those
definitions except you, the creator of the type, inside member functions of that type. private is a
brick wall between you and the client programmer. If someone tries to access a private member,
they’ll get a compile-time error. protected acts just like private, with the exception that an
inheriting class has access to protected members, but not private members.

In C++, an object is an instance of a user-defined class. For example, a person would be a


class, but Tom (the person) would be an instance of a person class. Objects can hide their data
and implementation.

Only the information provided by the class (through class members) is accessible, and everything
else is hidden.

You can control access to a class's data members and functions, using the following access
specifiers:
• public
• private
• protected

Public members are accessible outside the class, private and protected members are accessible
within the class, and protected members are also available to subclasses.
By default, all members of a class are private.

Making data members private and controlling access through public member functions helps to
ensure data integrity in your programs. Private data members can be manipulated only by other
member functions of the class.
This means that a class's implementation may change internally, but its public interface need not,
minimizing the change to the class.

 Attributes and behaviors


A class can represent an object in the real world, such as a radio.
In the class, you can declare the data that describes that object. And you can declare the
operations that are possible on that data.

L & T Infotech Page 25 of 87


OOPS Concepts using C++
Data Abstraction
A radio has attributes and behavior.

A radio has attributes, such as the volume at which it plays and the frequency to which it is tuned.
These attributes are analogous to a class's data members.

And it has behavior or operations (member functions), such as changing volume and tuning to a
station.
The real-world object – the radio – helps illustrate the concepts of encapsulation and data hiding.

You can change the volume and tune to a station without having to know how the radio interprets
and acts on those commands. Just as the radio is held within one unit, the data and functions are
said to be encapsulated. The attributes of volume and frequency are declared as private.

In other words, the way in which the radio implements them is a matter of concern only to
members of the radio class, which are its internal circuits and controls.

In the example of data hiding, Change_volume() and Tune_station() functions are declared as
public, but "external" elements (such as the person listening to the radio) can use them.

y
public:

void Change_volume (short nNewVolume)

void Tune_station (void);

 C++ program generation


Released in 1985, C++ is an object-oriented programming language created by Bjarne
Stroustrup. C++ maintains almost all aspects of the C language, while simplifying memory
management and adding several features - including a new datatype known as a class (you will
learn more about these later) - to allow object-oriented programming. C++ maintains the features
of C which allowed for low-level memory access but also gives the programmer new tools to
simplify memory management.

C++ is a general-purpose, strongly-typed programming language based on the C language.i.e


Everything must be declared before it is used, both variables and functions. C ++ has a few basic
building blocks, which can be grouped into types, operations and functions. It is the result of
research into extending C to incorporate the principles of object-oriented programming.This
research was carried out by Dr Bjarne Stroustrup of AT&T Bell Laboratories in the early 1980s.

C++ development systems generally consist of several parts:


• a text editor
• a C++ compiler/linker

• the C standard library

• class libraries
• a debugger

L & T Infotech Page 26 of 87


OOPS Concepts using C++
Data Abstraction


These components are sometimes integrated into a single development environment

The steps involved in generating a C++ program include


• editing
• preprocessing
• compiling
• linking

 Editing
You write the source code for a C++ program in the text editor, after which it is translated into
machine code by the compiler.

 Preprocessing
The C++ preprocessor executes before the compiler's translation phase begins. The
preprocessor obeys commands called preprocessor directives, which indicate that certain
manipulations are to be performed on the program before compilation. These manipulations
usually involve including the contents of other source code files within the current file, and
performing various text replacements.

The preprocessor also performs conditional compilation, that is, it allows different sections of
code to be compiled depending on preprocessor definitions. A common preprocessor directive is
#include. Lines beginning with the pound sign (#) are processed by the preprocessor before the
program is compiled.

 Compiling
The compiler translates the C++ program into machine code, also referred to as object code.
Programs don't always work the first time. Each of the steps can fail because of various types of
errors. The compiler reports warnings and errors.
Only errors prevent a program from compiling. The compiler indicates where each error occurred,
which helps you in locating and rectifying the errors.

 Linking
The fourth step is called linking. C++ programs typically contain references to data and to
functions defined elsewhere.
These may be defined in the C++ standard libraries, the private libraries of programmers working
on a project, or in third-party libraries.
A linker links the object code with the code for the missing functions to produce an executable
file. When a compile/link succeeds, an executable module is produced.
Using a debugger you can follow the source code as its machine code counterpart is executing.
This enables you to step through the code to ensure that it is doing what you expect. Also, you
can trace a bug or an unexpected runtime action in the program.

L & T Infotech Page 27 of 87


OOPS Concepts using C++
Data Abstraction

 Comments and functions


Let's consider how to develop a simple C++ program.
You can use comments to add explanatory notes to a program.

A line beginning with // indicates that a comment follows.


Comments are ignored by the compiler.

y
// Take in a student's name, grade and percentage
#include <iostream.h>

main()
{
}
A comment that begins with // is called a single-line comment because the comment ends at the
end of the line. Comments can also be multi-line, but they use different symbols to represent this.
The following code contains a preprocessor directive. This line tells the preprocessor to include
the contents of the input/output stream header file iostream.h in the program.

This file must be included for any C++ program that outputs data to the screen or receives input
data from the keyboard using the proposed C++ standard stream input/output.

y
// Take in a student's name, grade and percentage
#include <iostream.h>

main()
{
}

C++ programs contain one or more functions, one of which must be called main(). The
parentheses after main() indicate that it is a function. C++ programs begin executing at main() by
default, even if it isn't the first function in the program.


Some C++ compilers allow a different entry point function to be specified in the compiler settings.

The left brace, {, must begin the body of every function and the right brace, }, must end each
function.

y
// Take in a student's name, grade and percentage
#include <iostream.h>
main()
{
}

L & T Infotech Page 28 of 87


OOPS Concepts using C++
Data Abstraction

 Variables
You store data in a C++ program by assigning values to variables.

A variable is a name that is associated with memory set aside for storing the variable's value.
char sStudent[50];
char cGrade;
short nPercentage;

Every variable has a name, a type, a value, a size and a lifetime.


All variables must be declared with a name and a data type before they can be used in a
program.
A variable name is any valid identifier. Variable names must be unique within their scope.

An identifier is a series of characters consisting of letters, digits, and underscores (_).Identifiers


are case sensitive and cannot contain spaces.An identifier may not begin with a digit.

y
1A and A 1 are not legitimate identifiers.
C++ doesn't always limit the length of identifiers, but some implementations of C++ do restrict
their length. It's good programming practice to pick meaningful names for identifiers.

For example, it is much clearer to call a variable that represents a student's name sStudent rather
than s1.

y
char sStudent[50];
char cGrade;
short nPercentage;
A data type defines the sort of values a variable can store.
char sStudent[50];
char cGrade;
short nPercentage;

Fundamental data types include


• int
• float
• char

int
Variables of type int hold integer values, that is, whole numbers such as 7, -35, 0, and
23961.

The int data type has a range which is system dependent.

float
You use the float data type to represent any number that might be expressed using a
decimal point, that is, a real number, for example 2.7, 4.9, and -31.2.

char

L & T Infotech Page 29 of 87


OOPS Concepts using C++
Data Abstraction
A character in C++ is represented by its integer character code. The char data type
stores an integer character code. The char value range is from -128 to +127.

y
char sStudent[50];
char cGrade;
short nPercentage;
int x;
float y;

You can assign a value to a variable using the assignment operator, =.


In the following code the assignment statement calculates the sum of the variables integer1 and
integer2 and assigns the result to the variable "total".

Most calculations are performed in assignment statements.


total = integer1 + integer2;

Variables declared inside functions are local to those functions.


Variables declared outside functions, including main(), are global.

y
int x=20;
main()
{
int x;
x=10;
}

Local variables may be referenced only by statements that are inside the block in which the
variables are declared.

This feature is known as a variable's scope.


Statements outside the variable's scope have no access to that variable, and so
can't use its value.

y
int x=20;
main()
{
int x;
x=10;
}

Local variables are usually stored on the stack.The stack is a region of memory that holds,
among other things, local variables.

L & T Infotech Page 30 of 87


OOPS Concepts using C++
Data Abstraction
int x=20;
main()
{
int x;
x=10;
}

When a function begins, it allocates space on the stack to hold its local variables.
This space exists only while the function is active. After the function returns, it deletes the
allocated stack space, thus discarding any values stored there.
y
int x=20;
main()
{
int x;
x=10;
}

Global variables exist for the duration of a program. You create global variables by declaring
them outside any function.Any function may access them, regardless of what block of code that
expression is in.
y
int x=20;
main()
{
int x;
x=10;
}

This fragment shows that x, within main(), is currently in scope. Also, the global x is not modified
by the assignment.

y
int x=20;
main()
{
int x;
x=10;
}

You can allocate space for variables at runtime.These are called dynamic variables. They are
created on demand and stored in a block of free memory known as the heap.

 cout and cin stream objects


The cout and cin stream objects facilitate interaction between the user and the computer.
• cout << "Enter student name:";

• cin << sStudent;


cout << "Enter student name:";

L & T Infotech Page 31 of 87


OOPS Concepts using C++
Data Abstraction
You use the output stream object, cout, to display on the screen the text string contained between
the quotation marks. The stream insertion operator (<<) indicates that the value to the right of
the operator is inserted in the output stream.

cin << sStudent;


You use the input stream object, cin, and the stream extraction operator, <<, to accept input from
the user. The cin object takes input from the standard input stream, which is usually the
keyboard, and assigns the input to the variable.

L & T Infotech Page 32 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

Constructors and Destructors


Constructor functions and destructor functions are special functions available in the C++
programming language.A constructor function, which is a member function of a class, can
initialize the members of that class.

A destructor function is called when program execution leaves the scope in which an instance of
a class exists.

The purpose of a destructor is to reclaim an object's memory space (before the system reclaims
it) so that it may hold new objects.Because constructors and destructors take care of initialization
and destruction responsibilities in a program, these two member functions complement each
other.Often, it is necessary to initialize various data members with specific data values.

Using a constructor function, you can initialize various variables when the object is created.Using
C++, you can pass arguments to an object's constructor function, which are known only when the
object is created.

Let's say that you are defining a constructor function of an object called Time, which has data
members x and y.

Time:: Time (short x=0, short y=0)


{
nX=x; nY=y; };

You can set default values by coding the definition header.


Now, if Time is constructed with no parameters being passed to it, nX and nY will be zero.

 Declaring a constructor and destructor


Let's say that you want to add constructor and destructor functions to the program implementing
a simple time object.
First, you need to add the constructor and destructor functions to the class declaration.

#include <iostream.h>

class CClock
{
private:
short nHours,nMinutes,nSeconds;

public:

CClock();

L & T Infotech Page 33 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);

};

The constructor function name is always that of the class,

y
class Cclock

It is added to the list of member functions.

Destructors also have the same name as the class to which they belong, but they have a (~) tilde
in front of them, for example

~CClock();

In this case, the destructor is also added to the list of member functions.

#include <iostream.h>

class CClock
{
private:
short nHours,nMinutes,nSeconds;

public:

CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);

};

It does not matter whether you declare the constructor or the destructor first.
Both the constructor and the destructor are declared as public member functions.

L & T Infotech Page 34 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
Because the constructor and destructor are public, they will be called implicitly in the function
main(),

y
void main(void)

Either the constructor or destructor could have been declared as private. If so, class objects
would be created or destroyed only from within another member function.The only instance in
which you could create or destroy a class object from within another function is if the member
functions were static.


Constructors and destructors are usually declared as public.

 Adding a constructor function


You need to define the constructor and destructor functions.
You begin the constructor definition with the definition header. In this case, you use

CClock::CClock()

The Cclock(); line of code specifies that the constructor function CClock is a member function of
the class CClock.
The braces, which are to contain the specifications of the definition, are below the header.

public:

CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);

};

CClock::CClock()
{
}

Next you initialize the data members nHours, nMinutes, and nSeconds within the braces.
Initializing the data members in the constructor means that you do not need to initialize the data
members in the definition of the InitTime() function.

L & T Infotech Page 35 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

{
nHours=0;
nMinutes=0;
nSeconds=0;
}

Initializing the data members in the constructor definition means that they will be automatically
initialized in the function main() of the program.

 Adding a destructor function


You begin the destructor definition by specifying that it is a member of the CClock class.

In this case, the definition is

CClock::~CClock()
public:

CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);

};

CClock::CClock()
{
nHours=0;
nMinutes=0;
nSeconds=0;
}

CClock::~CClock()
{
}

Then, within the braces, you define the destructor to output a message onscreen.

Now destroying the clock object

To do so, you use the cout statement by entering

cout<< "Now destroying clock object";

L & T Infotech Page 36 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

public:

CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);

};

CClock::CClock()
{
nHours=0;
nMinutes=0;
nSeconds=0;
}

CClock::~CClock()
{
cout<<"Now destroying the clock object";
}

Constructors and destructors, like ordinary member functions, may contain any type of code.

Nevertheless, it is good practice to use them only for their intended purposes and to place
extraneous code in other functions.
Data members of a class cannot be initialized in the class definition, but they can be initialized in
a constructor of the class.

L & T Infotech Page 37 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

Inheritance
The two primary characteristics of object-oriented programming are inheritance and
polymorphism. Inheritance allows us to group classes into families of related types, allowing for
the sharing of common operations and data.

Inheritance defines a parent/child relationship. The parent defines the public interface and private
implementation that are common to all its children. Each child adds to or overrides what it inherits
to implement its own unique behavior. An AudioBook child class, for example, in addition to the
title and author it inherits from its parent Book class, introduces support for a speaker and a count
of the number of cassettes. In addition, it overrides the inherited check_out() member function
of its parent.

In C++, the parent is called the base class and the child is called the derived class. The
relationship between the parent or base class and its children is called an inheritance hierarchy.
At a design review meeting, for example, we might say, "We intend to implement an AudioBook
derived class. It will override the check_out() method of its Book base class. However, it will
reuse the inherited Book class data members and member functions to manage its shelf location,
author's name, and title."

When classes are similar, it is preferable to define them in terms of their common characteristics,
rather than duplicate effort by defining individual classes in full.

The mechanism provided by C++ to allow classes to reuse declarations made in other classes is
called inheritance.
When coding a new class, instead of creating new data members and new member functions, a
programmer can specify that the new class should inherit the data members and member
functions of a previously defined base class.

This is called inheritance, and the new class created is called a derived class.
Inheritance allows programmers to reuse software that has proven itself to work efficiently, and it
is therefore a major addition to the C++ programming language.


Every derived class can potentially be a base class to another derived class.

Inheritance in computer programming works in much the same way as it does in real life.

y
You inherit certain characteristics from your parents.
Similarly, a derived class inherits certain characteristics from its base class.

The two types of inheritance are

• single inheritance
• multiple inheritance

L & T Infotech Page 38 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
When a derived class inherits properties of only one base class, this is called single inheritance.
When a derived class inherits properties of more than one base class, this is called multiple
inheritance. When a derived class is created, it generally contains data members and function
members additional to those in its base class.

A derived class tends to be bigger in size but more specific than its base class.Derived classes
usually represent a smaller group of objects than their base classes.
The real advantage of inheritance is its ability to define subtle changes to the features inherited
by a derived class for one or more base classes.

Every object of a derived class is also an object of that derived class's base class.
A base-class object is not also an object of that base-class's derived class.The objects of a
derived class are, on the other hand, objects of its base class.

 Base and derived classes


Let's say that you are examining shapes as a class, particularly a derived class called triangle.
Although a triangle is a shape, not all shapes are triangles.

Conversely, considering triangles as a derived class of the shape base class, a triangle is a
shape, and therefore the object of the derived class is also an object of the base class. A derived
class can access the public members of its base class.

And derived classes receive favored treatment over other functions in accessing protected base
class members.

A derived class cannot access the private members of its base class.
These can be accessed by the derived class through access functions provided in the base
class's public or protected interfaces.

When deriving a class, you must specify which of the base class members you want the derived
class to inherit.

In the code Class B: public A,

the derived class B is set to inherit the protected members of the

base class A.

The derived class will also inherit the public functions by default.
A derived class can often inherit unwanted or inappropriate functions from the public interface of
its base class.
This is not a major problem because the unwanted inheritance can be redefined in the derived
class to have an appropriate implementation.

 Deriving a class
Let's say that you want to write a C++ program that implements a time object with an alarm
mechanism to demonstrate how C++ derived classes inherit the characteristics of base classes.

The steps involved in the program are


• include the header file

• declare the base class and its member functions

L & T Infotech Page 39 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
• declare the derived class and its data members and member functions

• define the functions of the base class

• define the member functions of the derived class

• code the main () function

• call the function


First you must include the header file <iostream.h> in the program.

#include<iostream.h>

Next, you declare the class CClock with the private data members nHours, nMinutes, and
nSeconds.
class CClock
{
private:
short nHours, nMinutes, nSeconds;

Now you declare the member functions of the base class – CClock, ~CClock, InitTime(),
AdvanceHours(), AdvanceMinutes(), and AdvanceSeconds() – for public access.

public:

CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);
};

The base class (CClock) is placed to the right of the colon (:), whereas the derived class
(CAlarmClock) is placed on the left.
It means that a derived class is to inherit the public elements of the base class.

#include<iostream.h>

class CClock
{
private:
short nHours, nMinutes, nSeconds;

public:
CClock();
~CClock();

L & T Infotech Page 40 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);
};

class CAlarmClock:public CClock


{


A base class can be either a direct base class or an indirect base class. The direct class's
name is listed in the header of the class, whereas an indirect class's name is inherited from
two or more levels up the class hierarchy.
Now you declare the data members of the derived class.

#include<iostream.h>

class CClock
{
private:
short nHours, nMinutes, nSeconds;

public:
CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);
};

class CAlarmClock:public CClock


{
private:
short nAlarmHours, nAlarmMinutes;

The data members nAlarmHours and nAlarmMinutes are declared as private.

include<iostream.h>

class CClock
{
private:
short nHours, nMinutes, nSeconds;

public:

L & T Infotech Page 41 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
CClock();
~CClock();

void InitTime(void);
void AdvanceHours(void);
void AdvanceMinutes(void);
void AdvanceSeconds(void);
};

class CAlarmClock:public CClock


{
private:
short nAlarmHours, nAlarmMinutes;

Declare the member functions of the class CAlarmClock.


Declare the member functions for public member access.

The member function CAlarmClock is a constructor function.The member function ~CAlarmClock


is a destructor function.You assign the third member function SetAlarm() the parameters qHours
and qMins.

This means that the function can be called only if values are specified for qHours and qMins.

public:
CAlarmClock();
~CAlarmClock();
void SetAlarm(short qHours,
short qMins);};

Now you need to define the member functions that you declared.
You define the constructor function CClock() to automatically initialize the function

InitTime()
CClock::CClock()
{
InitTime();
}

Define the destructor function to display "Now destroying clock object" on screen.

CClock::~CClock()
{
cout<<"Now destroying clock object";
}

L & T Infotech Page 42 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
Now you define the function InitTime() to attribute a zero value to the class CClock data
members.

void CClock::InitTime(void)
{
nHours=0;
nMinutes=0;
nSeconds=0;
}

In the definition of the function AdvanceHours(), you reset the value of nHours to zero when its
value is no longer less than 23.

void CClock::AdvanceHours(void)
{
nHours++;
if(nHours>23){
nHours=0;
}
}

Next you define the AdvanceMinutes() member function to reset the value of nMinutes to zero
when its value is no longer less than 59.

void CClock::AdvanceMinutes(void)
{
nMinutes++;
if(nMinutes>59){
nMinutes=0;
}
}

Now you define the member function AdvanceSeconds() to reset the value of nSeconds to zero
when its value is no longer less than 59.

void CClock::AdvanceSeconds(void)
{
nSeconds++;
if(nSeconds>59){
nSeconds=0;
}}

Having defined the functions of the CClock class, you now need to define the member functions
declared in the class declaration of CAlarmClock.

First define the constructor function CAlarmClock().

CAlarmClock::CAlarmClock()
{
}

L & T Infotech Page 43 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
Now define the destructor function ~CAlarmClock().

CAlarmClock::~CAlarmClock()
{
}

Now define the function

SetAlarm(short qHours, short qMins)

In the header of this definition, define the function SetAlarm(short qHours, short
qMins) as a member function of the class CAlarmClock.

void CAlarmClock::SetAlarm(short qHours, shortqMins)

Then you equate the value of nAlarmHours to that of qHours and the value of
nAlarmMinutes to that of qMins.

{
nAlarmHours=qHours;
nAlarmMinutes=qMins;
}

Now that the base clas and the derived class have been declared and defined then, code
the main() function of the program.

First you name the function main() then you declare an object of class

CAlarmClock[CAlarmClock] and call it clock.

CAlarmClock() [CAlarmClock] is a derived class of CClock.

CAlarmClock::CAlarmClock()
{
}

CAlarmClock::~CAlarmClock()
{
}

void CAlarmClock::SetAlarm(short nHours, short nMins)


{
nAlarmHours=qHours;
nAlarmMinutes=qMins;
}

void main(void)
{
CAlarmClock clock;

The C++ feature of inheritance has allowed CAlarmClock to inherit all the publicly defined

L & T Infotech Page 44 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
members of the class CClock.Therefore, the function main() has full access to the publicly
declared members of the class

CClock.

CAlarmClock::CAlarmClock()
{
}

CAlarmClock::~CAlarmClock()
{
}

void CAlarmClock::SetAlarm(short nHours, short nMins)


{
nAlarmHours=qHours;
nAlarmMinutes=qMins;
}

void main(void)
{
CAlarmClock clock;

Next, type the code to call the SetAlarm() function.

In this case, the code is

Clock.SetAlarm (10, 50);

The qHours is assigned the value of 10, and qMinutes is assigned the value of 50 in the
function SetAlarm() to the set function.

The alarm is therefore set to sound when 10 hours and 50 minutes have elapsed.

clock.SetAlarm(10, 50);

The nested loop in the main method is made up of three for statements.
The loop is designed to operate a 24-hour clock object with hours, minutes, and seconds.

for(short h==0;h<24;h++){
clock.AdvanceHours();
for(short m==0;m<60;m++){
clock.AdvanceMinutes();
for(short s==0;s<60;s++){
clock.AdvanceSeconds();
}
}
}

L & T Infotech Page 45 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

 Multiple inheritance
Single inheritance means that a derived class inherits elements from only one base class.

Multiple inheritance, on the other hand, means that a derived class inherits elements from more
than one base class.Multiple inheritance was included in the C++ Release 2.0 language
definition.

The addition was necessary to reflect and accommodate real-world objects, which programmers
were trying to simulate.

y
Let's say that you're mixing different colors of paint from the three primary colors red, blue, and
yellow.

By mixing red and blue you get purple.


purple is a derived class from the two base classes red and blue.

By mixing red, blue, and yellow you get brown.


In this case, brown has inherited elements of the base classes red, blue, and yellow.

In the example of multiple inheritance, brown is the derived class, and red, blue, and yellow are
the multiple base classes.

A specific syntax is used to indicate multiple inheritance when the derived class is called.

After the colon (:) inheritance indicator in the derived class declaration, the base classes being
inherited are listed and separated by a comma.

In the code, derived class D inherits the member functions and data members of base classes A,
B, and C.
Class D: public A,
public B, public C{
};
As in single inheritance, classes derived from multiple base classes inherit only member functions
and data members to which they have access.

 Coding multiple inheritance


Let's say that you want to code a program in C++ that uses multiple inheritance.
First, you need to make the header file <iostream.h> available to the program.

L & T Infotech Page 46 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
The syntax for including the header file <iostream.h> in the program is

#include<iostream.h>
Next you declare the class A.

class A
{
public:
int x;
void make_x(int i);

};

Now declare the data members and member functions of class A for public member access.
Next you declare class B.

Also declare the data member int y and the member function void make_y(int i) for public member
access.
class B
{
public:
int y;
void make_y(int i);
};
Next, declare the class C, which is a derived class with class A and class B as its multiple base
classes.

In the syntax, class C inherits all the public members of classes A and B.
Also, declare the function make_xy() for public member access.

#include<iostream.h>

class A
{
public:
int x;
void make_x(int i);

};

class B
{
public:
int y;
void make_y(int i);
};

L & T Infotech Page 47 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
class C:public A, public B
{
public:
int make_xy(void);

Next type the class A function make_x()


Type void A::make_x(int i) and then press Enter.
Now define the class B function make_y().

Define the function make_y() to set the value of y to the value of i by coding y=i; between braces.

void A::make_x(int i)
{
x=i;
}

void B::make_y(int i)
{
y=i;
}

Next define the class C function make_xy().

In the definition header, you code void in the brackets.This specifies that the function takes no
parameters.

By coding return x*y; between the braces, you define the function make_xy() to return the value
of x multiplied by y when the function is executed.

void A::make_x(int i)
{
x=i;
}

void B::make_y(int i)
{
y=i;
}

void C::make_xy(void)
{
return x*y;
}
Now you code the program's main() function.
main (void)
{
C i;

L & T Infotech Page 48 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

i.make_x(10);
i.make_y(12);

cout<<i.make_xy();

On the first line – C i; – in the main() function, you call the class C and give it the variable name i.
On this line, you call the function i.make_x(10).

You can call the make_x() function even though it was declared in the class A declaration, and
not in the class C declaration.

This is because class C inherits the member functions of class A.


Next type the code to call the function make_y().
Type i.make_y(12); and then press Enter.
The code – i.make_y(12) – calls the function make_y(), which is called from main().

The parameter, and therefore the value of the function, is 12.


The make_y() function is not a member function of the derived class C, but it can be called
because it is a member of the base class B.

main (void)
{
C i;

i.make_x(10);
i.make_y(12);

cout<<i.make_xy();

The last line – cout<<i.make_xy();– in the main() function employs cout to display the result on
screen.

The make_xy() function was defined to return the value of x multiplied by y.


main (void)
{
C i;

i.make_x(10);
i.make_y(12);

cout<<i.make_xy();
}

L & T Infotech Page 49 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

Because the value of x is 10, and the value of y is 12, the return is 120.

 Multiple inheritance issues


Because of its very nature, programming multiple inheritance can be difficult, so a programmer
needs to pay attention to several issues.
When deriving a class from one or more public base classes, public members of the base class
become public members of the derived class.

Protected members of the base classes become protected members of the derived class.

Private members of a base class are never directly accessible from a derived class.
When deriving from a protected base class, public and protected members of the base class
become protected members of the derived class.

When deriving from a private base class, public and protected members of the base class
become private members of the derived class.
In the base-class list, member access must be specified for each base class.

In the code, class A is protected, class B is public, and class C defaults to private.
class D: protected A, public B, private C{
};
If member access is not specified, the base class always defaults to private.
class D: private C{
};
However, for clarity, it is recommended that the member access be stated explicitly.
class D: protected A, public B, private C{
};
A base-class name must not be included more than once in a base-class list.

In the case of an indirect base class, its name is not specified in the declaration.

The name of the class, which is derived from it, is used.


class D: protected A, public B, private C,
public B{
Let's say that class A inherits properties directly from class B.

In this case, class D inherits all the characteristics directly from class A and class C.

Because class D inherits class A, class B is an indirect base class of class D.


class D: protected A, public B, private C{
};

L & T Infotech Page 50 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

 Calling issues
A class derived from multiple base classes may need to call multiple base-class constructors.

A derived class inherits its base class's members.


Let's say that there is an instance of an object of a derived class.

The base-class members of the derived class object must be initialized by calling the base class's
constructor.
A base-class initializer may be coded in the derived class's constructor to explicitly call the base-
class constructor.

Otherwise, the derived class's constructor will implicitly call the base class's default constructor.

A derived-class constructor always calls the constructor for its base class first to initialize the
derived class's base-class members.
Constructors are called in the order in which their base classes are declared.

However, it is generally unwise to devise classes that depend on other class objects to be
constructed in a particular order.

As a rule, classes should operate as independently of each other as possible.


Class D: protected A, public B, C{
};
Suppose that you're coding a class that depends on other classes' objects to be initialized in a
certain order.

Instead of having one class inherit other classes' properties, you might declare the dependent
classes as data members of a new class.

The new class could then control when and how the dependent members are initialized.

L & T Infotech Page 51 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

Virtual Functions and Polymorphism

Polymorphism is an important feature of object-oriented languages. It makes it easier to reuse


code. This, in turn, leads to systems that are easier to maintain and extend.
// main
void main(void) {
CEmployee *pEmployee;

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
Polymorphism can be defined as the ability of objects of different classes, related by inheritance,
to respond differently to the same member function call.

It allows the use of identical interfaces with different implementations.


Consider the definition of a base class CEmployee which is used to define two derived classes:
• CHourlyWorker

• CSupervisor
#include <iostream.h>
// class declarations
// CEmployee
class CEmployee{
protected:
char cLastName[25];
char cFirstName[25];
float fYearlyEarnings;

public:
CEmployee();
virtual void Print();
float ReviseYearlyEarnings();
};

// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;
// CHourlyWorker

L & T Infotech Page 52 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;

public:
CHourlyWorker();
void Print();
};

// CSupervisor
class CSupervisor:public CEmployee{
private:
int nMonthlySalary;

public:
CSupervisor
void Print();
};

CEmployee might include a function called Print() that allows you to output the contents of an
object of that class.

Each derived class of CEmployee can redefine this function to output its local contents.
// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;

public:
CHourlyWorker();
void Print();
};

// CSupervisor
class CSupervisor:public CEmployee{
private:
int nMonthlySalary;

public:
CSupervisor
void Print();
};
Although the contents of each derived class will be different, polymorphism allows you to treat
them all as objects of the base class.

The contents of any derived class can then be printed by simply making a generic call to Print()
using a base-class pointer.

L & T Infotech Page 53 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
// main
void main(void) {
CEmployee *pEmployee;

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
}
The proper behavior of the derived-class object when treated as a base-class object is
polymorphism.
// main
void main(void) {
CEmployee *pEmployee;

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
}
The call to function Print() can be resolved only at run time, and not at compile time. This ability to
delay resolution is referred to as late or dynamic binding.

Late binding is the mechanism for implementing polymorphism.


Resolving the function at compile time is called early or static binding.

L & T Infotech Page 54 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

 Virtual functions
C++ supports polymorphism using virtual functions. You use the keyword virtual in a virtual
function's prototype declaration.

#include <iostream.h>

//-----------------------------
// class declarations
//-----------------------------

// CEmployee
class CEmployee{
protected:
char cLastName[25];
char cFirstName[25];
float fYearlyEarnings;

public:
CEmployee();
virtual void Print();
float ReviseYearlyEarnings();
};

// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;
};

Unlike redefined nonvirtual functions, redefined virtual functions must have the same number of
parameters and the same parameter types and return type.

When a function is declared as a virtual function, it remains virtual from that point down through
the hierarchy.

#include <iostream.h>

//-----------------------------
// class declarations
//-----------------------------

// CEmployee
class CEmployee{
protected:
char cLastName[25];
char cFirstName[25];

L & T Infotech Page 55 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
float fYearlyEarnings;

public:
CEmployee();
virtual void Print();
float ReviseYearlyEarnings();
};

// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;
};

For the "employee" example, the function Print() is declared as a virtual function in the base class
CEmployee.
Print() is then redefined (or overloaded) in each derived class to print the contents specific to that
class.

#include <iostream.h>
// class declarations
// CEmployee
class CEmployee{
protected:
char cLastName[25];
char cFirstName[25];
float fYearlyEarnings;

public:
CEmployee();
virtual void Print();
float ReviseYearlyEarnings();
};

// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;

public:
CHourlyWorker();
void Print();
};

// CSupervisor
class CSupervisor:public CEmployee{
private:

L & T Infotech Page 56 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
int nMonthlySalary;

public:
CSupervisor
void Print();
};

Base-class member functions that are too generic to be defined (implemented) within the base
class should be declared as pure virtual functions.

When a pure virtual function is included in a class, you cannot create an instance of that class.
This is referred to as an abstract class as it is too generic to define a real object.

// CHourlyWorker
class CHourlyWorker:public CEmployee{
private:
float fWeeklyWage;

public:
CHourlyWorker();
void Print();
};

// CSupervisor
class CSupervisor:public CEmployee{
private:
int nMonthlySalary;

public:
CSupervisor
void Print();
};


Although you cannot create an object from an abstract class, you can declare a pointer to that
abstract class.
A virtual function that is created in a base class and redefined in one or more derived classes can
act polymorphically.

When the function is called as a member of the base class using a base-class pointer, C++
selects the correct redefined function in the appropriate derived class associated with that object.
// main
void main(void) {
CEmployee *pEmployee;

L & T Infotech Page 57 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
}

A call to a virtual function using a specific object name and the dot member selection operator is
resolved at compile time.
The virtual function used is the one defined for the class associated with that object, in this case
the CSupervisor class.

// CHourlyWorker
CHourlyWorker::CHourlyworker() {
}

virtual void CHourlyWorker::Print( ) {


cout << cFirstName << ' ' << cLastName << endl
<< "Weekly wage = " << fWeeklyWage << endl
<< "Expected Yearly Earnings = " << fYearlyEarnings;
}

void main() {
CSupervisor Brown;
Brown.print();
}

When a nonvirtual member function of a base class is redefined in a derived class, a call to that
function using a base-class pointer always uses the base-class version of the function.
If a derived-class pointer is used to call the member function, the derived-class version of the
function is used. This represents nonpolymorphic behavior.

// CHourlyWorker
CHourlyWorker::CHourlyworker() {
}

virtual void CHourlyWorker::Print( ) {


cout << cFirstName << ' ' << cLastName << endl
<< "Weekly wage = " << fWeeklyWage << endl

L & T Infotech Page 58 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
<< "Expected Yearly Earnings = " << fYearlyEarnings;
}
void main() {
CSupervisor Brown;
Brown.print();
}

As an example of nonpolymorphic behavior, consider the redefinition of nonvirtual base-class


member function ReviseYearlyEarnings() within class CSupervisor.
A call to this function using the base-class pointer pEmployee will always access the base-class
version of the function rather than the corresponding redefined version.

// main
void main(void) {
CEmployee *pEmployee;

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
}

void CEmployee::REviseYearlyEarnings() {
fYearlyEarnings = fYearlyEarnings + fYearlyEarnings/50
}

// CSupervisor::CSupervisor() {
}

virtual void CSupervisor::Print() {


cout << cFirstName << ' ' << cLastName << endl
<< "Monthly Salary = " << nMonthlySalary << endl
<< "Expected Yearly Earnings = " << fYearlyEarnings;
}

void CSupervisor::REviseYEarlyEarnings() {
fYearlyEarnings = fYearlyEarnings + fYearlyEarnings/50
To access the appropriate redefined version of the function, you need to use a pointer to the
derived class (CSupervisor).
// main
void main(void) {
CEmployee *pEmployee;

L & T Infotech Page 59 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism

pEmployee = new CHourlyWorker();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;

pEmployee = new CSupervisor();


pEmployee->ReviseYearlyEarnings();
pEmployee->Print();
delete pEmployee;
}

 Compiling considerations
With polymorphism and virtual functions, a programmer can write code independently of the types
of objects to which messages are sent.

Dynamic binding allows virtual functions to compile without knowing the type or class of an object
at compile time.
At run time, the virtual function call is matched with the member function of the receiving object.
This allows new objects to be added without the need to recompile the whole system.
All you need to do is compile the objects being added and any code which manipulates that
object type specifically.

 Default function parameters


A useful technique associated with C++ functions is the ability to specify default values for
function parameters.

You can employ this technique when a function call needs to provide only some of the expected
arguments for that function.
Consider a function that returns the product of three integer values.
To call the function using only two arguments, say num1 and num2, the programmer first needs
to determine and then supply the correct value to the unused parameter.
This is cumbersome and can be prone to error.
Default function arguments are designed to guard against incorrect function values being
assigned to function parameters.

To declare a default value, you assign the parameter the appropriate value in the function
prototype.
In this example, the prototype declaration indicates that Product() requires only two arguments,
but can have three arguments.
The default values must come last in the function's parameter list, and can only appear in the
function's prototype. For example, you can't have a prototype like the one in this example.
But you can use the following prototype:

int Product(int X, int Y, int Z=1);

L & T Infotech Page 60 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
If a function call specifies no arguments for function parameters with default values, then the
parameters are given the default values listed in the prototype.

Polymorphism in an application

1. Shapes
Let's consider a shape hierarchy as the classic example of how you can apply polymorphism to
an application.

The shape program needs to manage generic shape objects. All shapes can be drawn, but
triangles, circles, and squares are all drawn differently.
To create a program that is easy to extend, you need to be able to handle generic shape pointers
while ignoring the details of the particular shape you are dealing with.

2. Coding considerations
Suppose a set of shape classes CTriangle, CCircle, and CSquare are all to be derived from base
class CShape.

Each derived class will have its own Draw() and SetColor() functions.
Using polymorphism, you want to be able to draw any shape and set its color by simply invoking
the Draw() and SetColor() functions using a base-class pointer.
To implement the program, you first need to define the base class, CShape, from which all other
shape classes will be derived.
By declaring color as a private data member, access to it is restricted to functions that are
members or friends of the base class.
#include <iostream.h>

typedef enum{
Unknown,
Blue,
Green,
Red,
Yellow
} Color;

//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{
private:
Color color;

L & T Infotech Page 61 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
public:
Cshape();
CShape must be set up as an abstract class because member function Draw() is too generic to
be defined for an object of this class.
#include <iostream.h>

typedef enum{
Unknown,
Blue,
Green,
Red,
Yellow
} Color;

//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{
private:
Color color;

public:
Cshape();
You make CShape an abstract class by declaring Draw() as a pure virtual function, that is, you
assign its prototype a value of zero.
//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{
private:
Color color;

public:
Cshape();
virtual ~CShape();

virtual void Draw(void)=0;


virtual void SetColor(Color c);
};

// CTriangle
class CTriangle : public CShape{
private: //-------------------------------

L & T Infotech Page 62 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
// class definitions
//-------------------------------

// CShape
CShape::CShape() {
}

CShape::~CShape() {
cout << "In ~ CShape()\n";
}

void CShape::SetColor(Color c) {
cout << "In CShape::Setcolor()\n";
color=c;
};

// CTriangle
CTriangle::CTriangle() {
m_nAngle1=m_nAngle2=m_nAngle3=0;


The implementation presented here does not deal with the mechanics of how to draw each
shape.
Only part definitions of constructors, destructors, and other class member functions are
shown.
When the program is executed, the output consists of a list of "location messages" (or
diagnostics), used to indicate the execution path through the program.

Base-class member function SetColor() can be defined without knowing which shape object it is
being applied to.
Therefore, it can be declared as a virtual function, rather than a pure virtual function.
You can see from its definition that it outputs a location message to the screen and assigns a
value to base-class data member color.

//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{
private:
Color color;

L & T Infotech Page 63 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
public:
Cshape();
virtual ~CShape();

virtual void Draw(void)=0;


virtual void SetColor(Color c);
};

// CTriangle
class CTriangle : public CShape{
private:

//-------------------------------
// class definitions
//-------------------------------

// CShape
CShape::CShape() {
}

CShape::~CShape() {
cout << "In ~ CShape()\n";
}

void CShape::SetColor(Color c) {
cout << "In CShape::Setcolor()\n";
color=c;
};

// CTriangle
CTriangle::CTriangle() {
m_nAngle1=m_nAngle2=m_nAngle3=0;

In addition to Draw() and SetColor(), CShape's public interface includes the constructor CShape()
and the destructor ~CShape()

The destructor ~CShape needs to be declared as a virtual function to overcome a problem which
occurs when virtual functions and destructors are used with class hierarchies.

//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{

L & T Infotech Page 64 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
private:
Color color;

public:
Cshape();
virtual ~CShape();

virtual void Draw(void)=0;


virtual void SetColor(Color c);
};

// CTriangle
class CTriangle : public CShape{
private:


If the destructor is not marked as virtual, then an explicit call to destroy an object using the
delete operator and a base-class pointer will always use the base-class destructor,
irrespective of the object being pointed to.

Once CShape has been defined, you can begin to define each of the derived classes.

Each derived class will inherit from the base class CShape.
//--------------------------
// class declarations
//--------------------------

// CShape
class CShape{
private:
Color color;

public:
Cshape();
virtual ~CShape();

virtual void Draw(void)=0;


virtual void SetColor(Color c);
};

// CTriangle
class CTriangle : public CShape{
private:

L & T Infotech Page 65 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
3. Defining derived classes
Let's look at how you might define CTriangle, the derived class for triangle objects.
You want the public members of CShape to be public in the derived class CTriangle. So you
derive CTriangle from CShape using the keyword public.

// CTriangle
class CTriangle : public CShape{
private:
short m_nAngle1, m_nAngle2, m_nAngle3;
public:
CTriangle();
~CTriangle();

void SetAngles(short nAngle1, short nAngle2, short nAngle3)


void Draw(void);
void SetColor(Color c);
};

// CCircle
class CCircle : public CShape(
private:
short m_nRadius;
public:
CCircle();
~CCircle();

The shape of any triangle is described by the magnitude of its three angles. Therefore, CTriangle
includes three data members to hold these values.

// CTriangle
class CTriangle : public CShape{
private:
short m_nAngle1, m_nAngle2, m_nAngle3;
public:
CTriangle();
~CTriangle();

void SetAngles(short nAngle1, short nAngle2, short nAngle3)


void Draw(void);
void SetColor(Color c);
};

// CCircle
class CCircle : public CShape(
private:
short m_nRadius;

L & T Infotech Page 66 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
public:
CCircle();
~CCircle();
In addition to a constructor and destructor, CTriangle includes three other member functions in its
public interface
• SetAngles()

• Draw()

• SetColor()

SetAngles()Draw()SetColor()

// CTriangle
class CTriangle : public CShape{
private:
short m_nAngle1, m_nAngle2, m_nAngle3;
public:
CTriangle();
~CTriangle();

void SetAngles(short nAngle1, short nAngle2, short nAngle3)


void Draw(void);
void SetColor(Color c);
};

// CCircle
class CCircle : public CShape(
private:
short m_nRadius;
public:
CCircle();
~CCircle();

SetAngles() allows you to describe a triangle object by setting the values of CTriangle's data
members m_nAngle1, m_nAngle2, and m_nAngle3.
Draw() and SetColor() are overloaded versions of the corresponding base class virtual functions,
which allows them to be polymorphically selected at run time.

// CTriangle
class CTriangle : public CShape{
private:
short m_nAngle1, m_nAngle2, m_nAngle3;

L & T Infotech Page 67 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
public:
CTriangle();
~CTriangle();

void SetAngles(short nAngle1, short nAngle2, short nAngle3)


void Draw(void);
void SetColor(Color c);
};

// CCircle
class CCircle : public CShape(
private:
short m_nRadius;
public:
CCircle();
~CCircle();

In this example, Draw() simply outputs the message "In CTriangle::Draw()" each time it is called.
SetColor() explicitly calls the base-class version of itself to assign a value to base-class private
data member color.

CTriangle::~CTriangle() {
cout << "In ~CTriangle()\n";
}
void CTriangle::SetAngles(short nAngle1, short nAngle2,
short nAngle3) {
m_nAngle1=nAngle1;
m_nAngle2=nAngle2;
m_nAngle3=nAngle3;
}

void CTriangle::Draw(void) {
cout << "In CTriangle::Draw()\n";
}
void CTriangle::SetColor(Color c) {
cout << "In CTriangle::SetColor()\n"
CShape::SetColor(c);
}
// CCircle

You don't have to derive your own versions of base-class virtual functions if implementations are
provided in the base class.

For example, if SetColor() was not redefined here, the CShape version would be inherited.

L & T Infotech Page 68 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
CTriangle::~CTriangle() {
cout << "In ~CTriangle()\n";
}
void CTriangle::SetAngles(short nAngle1, short nAngle2,
short nAngle3) {
m_nAngle1=nAngle1;
m_nAngle2=nAngle2;
m_nAngle3=nAngle3;
}
void CTriangle::Draw(void) {
cout << "In CTriangle::Draw()\n";
}
void CTriangle::SetColor(Color c) {
cout << "In CTriangle::SetColor()\n"
CShape::SetColor(c);
}
// CCircle


If Draw() was not defined in CTriangle, then CTriangle would be an abstract class as there is
no definition for Draw() in CShape.

Therefore, you do need to include a definition for Draw() in CTriangle.

Derived classes CCircle and CSquare are defined in a way similar to CTriangle. Each is set up to
publicly inherit from the base class CShape.

// CCircle
class CCircle : public CShape{
private:
short m_nRadius;
public:
CCircle();
~CCircle();

void SetRadius(short nRadius);


void Draw(void);
void SetColor(Color c);
};

// CSquare
class CSquare : public CShape(
private:
short m_nSideLength;
public:

L & T Infotech Page 69 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
CSquare();
~CSquare();

As a circle is described by its radius, an appropriate data member is declared in the private
portion of class CCircle.
CCircle includes a public member function SetRadius() that you can use to describe the circle
object created.

// CCircle
CCircle::CCircle() {
m_nRadius=0;
}

CCircle::~CCircle() {
cout << "In ~CCircle()\n";
}

void CCircle::SetRadius(short nRadius) {


m_nRadius=nRadius;
}

void CCircle::Draw(void) {
cout << "In CCircle::Draw()\n";
}

void CCircle::SetColor(Color c) {
cout << "In CCircle::SetColor()\n";
CShape::SetColor(c);
CSquare has a single data member, m_nSideLength, that describes the square object.

CSquare::SetSideLength() allows you to manipulate this data member


// CSquare
class CSquare : public CShape(
private:
short m_nSideLength;
public:
CSquare();
~CSquare();

void SetSideLength(short nSideLength);


void Draw(void);
void SetColor(Color c);
};

//-------------------------------
// class definitions

L & T Infotech Page 70 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
//-------------------------------

// CShape
CShape::CShape() {
}
Base-class member functions Draw() and SetColor() are both redefined for CCircle and CSquare.

The implementation of these functions is similar to those described for CTriangle.


// CSquare
class CSquare : public CShape(
private:
short m_nSideLength;
public:
CSquare();
~CSquare();

void SetSideLength(short nSideLength);


void Draw(void);
void SetColor(Color c);
};

//-------------------------------
// class definitions
//-------------------------------

// CShape
CShape::CShape() {
}

4. Polymorphism in main()
Let's now examine main() to see how polymorphism simplifies the code.
Function main() begins with the declaration of the base-class pointer pShape.

Using a base class pointer allows the use of generic calls to Draw() and SetColor() without any
indication of the shape currently being referenced
The first step in drawing a triangle is to create an object of class CTriangle.
One way to do this is to call CTriangle's constructor using the new operator.
The new operator returns the address of the object, which can be used to initialize the pointer
pShape.
// main function
void main(void) {
CShape *pShape;

// create a triangle
pShape=new CTriangle();

L & T Infotech Page 71 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism


The new and delete operators handle pointers rather than the objects themselves. You use
new to return a pointer to the initialized object.

The delete operator takes a pointer to an object that was previously created using new.

To describe the triangle, you need to access CTriangle's unique member function SetAngles().
You can do this by casting the base-class pointer, pShape, as a CTriangle pointer.

This allows you to call CTriangle::SetAngles() using the pointer arrow operator "->".
// main function
void main(void) {
CShape *pShape;

// create a triangle
pShape=new CTriangle();

((CTriangle*)pShape)->SetAngles(90,90,90);
Once you have described the object, you can make use of polymorphism to set its color and then
draw it.
Polymorphism allows you to code a generic call to SetColor() using base-class pointer pShape.

C++ will polymorphically select CTriangle::SetColor() as the correct version of SetColor() in this
instance. This is because pShape will be pointing to an object of class CTriangle when the call is
made.
// main function
void main(void) {
CShape *pShape;

// create a triangle
pShape=new CTriangle();

((CTriangle*)pShape)->SetAngles(90,90,90);
pShape->SetColor(Blue);
You can confirm the polymorphic behavior by observing the program's output.
The first non-constructor function executed is CTriangle::SetColor(). This function calls the base-
class version of SetColor() (that is, CShape::SetColor()) to set the color of the object.


No location messages have been included in the definition of class constructors. Therefore,
there is no indication of which constructors have been executed in the program's output.

Next, pShape is used to make a generic call to base-class member function Draw().

As for SetColor(), C++ polymorphically selects CTriangle::Draw() as the correct version of Draw()
in this instance.

L & T Infotech Page 72 of 87


OOPS Concepts using C++
Virtual Function & Polymorphism
// main function
void main(void) {
CShape *pShape;

// create a triangle
pShape=new CTriangle();

((CTriangle*)pShape)->SetAngles(90,90,90);
pShape->SetColor(Blue);
pShape->Draw();
delete pShape;
The delete operator is used to destroy the object currently pointed to by pShape. It automatically
invokes the correct class destructor for the object.

First, the derived-class destructor is called, then the destructor for the base class.


Generally, destructors are called in reverse order of their constructors.

Because of polymorphism, the code used to draw the circle and square objects is almost identical
to the code used to draw the triangle object.

The only difference is in the casting for calls to functions specific to each class.
// create a circle
pShape=new CCircle();
((CCircle*)pShape)->SetRadius(10);
pShape->SetColor(Red);
pShape->Draw();
delete pShape;

// create a square
pShape=new CSquare();
((CSquare*)pShape)->SetSideLength(10);
pShape->SetColor(Green);
A glance at the output shows that the execution path for each of the three objects is quite
different.

L & T Infotech Page 73 of 87


OOPS Concepts using C++ Program Using Polymorphism

Program Using Polymorphism

A program to calculate the area of two-dimensional objects using polymorphism.

This involves the following tasks:


• defining a base class

• defining member functions

• defining derived classes

• defining member functions

• handling a rectangle object

• handling a circle object


Suppose you have been asked to write a program to calculate the area of two-dimensional
objects using polymorphism. You are required to test the design by coding a main() function that
creates a rectangle and a circle.
You should calculate the area of each defined object and output the details of the calculation to
the screen.

Task 1: Defining a base class


Your first task is to define a base class, called C2dObject, from which all two-dimensional objects
will be derived.
Step 1 of 4

See if you can complete the line that begins the definition of the base class C2dObject.

Result

To complete the class definition you type


class C2dObject{

Next, you need to declare a data member within C2dObject that will hold the value calculated for
area.
Let's assume that you want derived-class member functions to have access to this base-class
data member.
#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{

L & T Infotech Page 74 of 87


OOPS Concepts using C++ Program Using Polymorphism

Step 2 of 4

In which portion of the class do you think you would declare this data member?
Options:

1. private

2. protected

3. public

Result

The protected portion of the class declares this data member.

You declare floating-point variable, m_fArea, as a protected data member of C2dObject.


#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{
protected
float m_fArea;
Assume that C2dObject's public interface has already been partly defined with the declaration of
a constructor and destructor.

You now want to declare a member function, called CalcArea(), that will be used to calculate the
area of any two-dimensional object.
#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{
protected
float m_fArea;

public:
C2dObject();
virtual ~C2dObject();

C2dObject is too generic to be a real object.

Step 3 of 4

L & T Infotech Page 75 of 87


OOPS Concepts using C++ Program Using Polymorphism

See if you can complete the declaration of the CalcArea() prototype.

MISSING CODE void CalcArea(void) = 0;


Result

You declare CalcArea() as a pure virtual function by entering this statement:


virtual void CalcArea(void) = 0;

You are also asked to include a function PrintDetails() that will display the value calculated for the
area of an object.
A generic call to PrintDetails() should also print the defining data used in the calculation of the
area of the object.
#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{
protected
float m_fArea;

public:
C2dObject();
virtual ~C2dObject();

virtual void CalcArea(void) = 0;


Step 4 of 4

How do you think you could declare PrintDetails() within the base class C2dObject, if a
definition for PrintDetails() is to exist for the base class as well as for derived classes?
Options:

1. virtual void PrintDetails(void);

2. virtual PrintDetails();

3. virtual PrintDetails()=0;

4. void PrintDetails(void)=0;

Result

You could declare PrintDetails() using the code


virtual void PrintDetails(void);
or
virtual PrintDetails();

L & T Infotech Page 76 of 87


OOPS Concepts using C++ Program Using Polymorphism

As a definition for PrintDetails() is to be included within C2dObject, and polymorphic behavior is


required, you declare PrintDetails() as a virtual function by entering this statement.

#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{
protected
float m_fArea;

public:
C2dObject();
virtual ~C2dObject();

virtual void CalcArea(void) = 0;


virtual void PrintDetails(void);

Finally, you enter the closing tag – }; – to complete the definition of the base class C2dObject.

#include <iostream.h>
//------------------------------------
// class declarations
//------------------------------------

// C2dObject
class C2dObject{
protected
float m_fArea;

public:
C2dObject();
virtual ~C2dObject();

virtual void CalcArea(void) = 0;


virtual void PrintDetails(void);
};

L & T Infotech Page 77 of 87


OOPS Concepts using C++ Program Using Polymorphism

Task 2: Defining member functions


Now, you need to define the member functions of class C2dObject.
Assume that the class constructor and destructor have already been defined.
//--------------------------
// class definitions
//--------------------------

// C2dObject
C2dObject::C2dObject() {
m_fArea = 0;
}

C2dObject::~C2dObject() {
}
Step 1 of 1

See if you can complete the code required to begin the definition of PrintDetails() for base
class C2dObject.

/--------------------------
// class definitions
//--------------------------

// C2dObject
C2dObject::C2dObject() {
m_fArea = 0;
}

C2dObject::~C2dObject() {
}

void MISSING CODE (void) {


Result

To begin the definition of PrintDetails() you type


C2dObject::PrintDetails

This cout statement outputs the area of the current object.


//--------------------------
// class definitions
//--------------------------

// C2dObject

L & T Infotech Page 78 of 87


OOPS Concepts using C++ Program Using Polymorphism

C2dObject::C2dObject() {
m_fArea = 0;
}

C2dObject::~C2dObject() {
}

void C2dObject::PrintDetails(void) {
cout << "Area = " << m_fArea << "\n";
}

Task 3: Defining derived classes


You are now going to define derived classes CRectangle and CCircle.
// CRectangle
Step 1 of 3

See if you can complete the opening line in the definition of derived class CRectangle.
You want public members of the base class to be inherited as public members in the derived
class.

// CRectangle
class MISSING CODE C2dObject {
Result

The code to complete the definition of derived class CRectangle is CRectangle:public.

Step 2 of 3

Which of the following data members would you expect to find declared in the private portion
of class CRectangle?
Options:

1. m_nLength

2. m_nWidth

3. m_nArea

4. m_nRadius

Result

A rectangle is described by its length and width. Therefore, you need to declare m_nLength
and m_nWidth as private data members of CRectangle.

Derived class CRectangle inherits base-class data member m_fArea to hold the value for the
area of a rectangle object.

L & T Infotech Page 79 of 87


OOPS Concepts using C++ Program Using Polymorphism

// CRectangle
class CRectangle:public C2dObject{
private:
int m_nLength, m_nWidth;
Assume that the constructor and destructor for CRectangle have already been declared and
defined.
Also declared is the prototype for the function SetDimensions(). It will be used to set the values
for the length and width of a rectangle object.
// CRectangle
class CRectangle:public C2dObject{
private:
int m_nLength, m_nWidth;
public:
CRectangle();
~CRectangle();

void SetDimensions(int nLength, int nWidth);


The program needs to display polymorphic behavior when calls are made to
• calculate the area of an object

• output the details of an object to the screen

Step 3 of 3

For a polymorphic implementation, which of the following declarations do you think you should
use to complete CRectangle's public interface?
Options:

1. void CalcArea(void);

2. virtual void CalcArea(void)=0;

3. void PrintDetails(void);

4. void PrintDetails();

Result

You use the declarations


void CalcArea(void); and
void PrintDetails(void);

You include declarations for base-class virtual member functions CalcArea() and PrintDetails() in
the public portion of derived class CRectangle.
// CRectangle
class CRectangle:public C2dObject{
private:
int m_nLength, m_nWidth;
public:

L & T Infotech Page 80 of 87


OOPS Concepts using C++ Program Using Polymorphism

CRectangle();
~CRectangle();

void SetDimensions(int nLength, int nWidth);


void CalcArea(void);
void PrintDetails(void);
Finally, you add the closing tag – }; – to complete the definition of derived class Crectangle.
// CRectangle
class CRectangle:public C2dObject{
private:
int m_nLength, m_nWidth;
public:
CRectangle();
~CRectangle();

void SetDimensions(int nLength, int nWidth);


void CalcArea(void);
void PrintDetails(void);
};

Task 4: Defining a rectangle object


Assume that the definitions for CRectangle's constructor and destructor functions have both been
completed.
// CRectangle
CRectangle::CRectangle() {
m_nLength = m_nWidth = 0;
}

CRectangle::~CRectangle() {
}

Step 1 of 2

What statement do you think you would include in the definition of


CRectangle::SetDimensions() to set the value for the length of an object?

// CRectangle
CRectangle::CRectangle() {
m_nLength = m_nWidth = 0;
}

CRectangle::~CRectangle() {
}
void CRectangle::SetDimensions(int nLength, int nWidth) {
MISSING CODE ;

L & T Infotech Page 81 of 87


OOPS Concepts using C++ Program Using Polymorphism

Result

The statement that sets the value for the length is


m_nLength=nLength;

Step 2 of 2

See if you can complete the definition CRectangle::CalcArea()

// CRectangle
CRectangle::CRectangle() {
m_nLength = m_nWidth = 0;
}

CRectangle::~CRectangle() {
}
void CRectangle::SetDimensions(int nLength, int nWidth) {
m_nLength=nLength;
m_nWidth=nWidth;
}
void CRectangle::CalcArea(void) {
MISSING CODE
}
Result

The code to complete the definition is


m_fArea=m_nLength*m_nWidth;

You define CRectangle::PrintDetails() to output the dimensions of a rectangle object using a


statement similar to this.
You can simply make a call to the base-class version of PrintDetails() to output the value
calculated for the area of the rectangle object.
You have now completed the implementation of derived class CRectangle and its member
functions.
// CRectangle
CRectangle::CRectangle() {
m_nLength = m_nWidth = 0;
}

CRectangle::~CRectangle() {
}
void CRectangle::SetDimensions(int nLength, int nWidth) {
m_nLength=nLength;
m_nWidth=nWidth;
}
void CRectangle::CalcArea(void) {
m_fArea=m_nLength*m_nWidth;

L & T Infotech Page 82 of 87


OOPS Concepts using C++ Program Using Polymorphism

}
void CRectangle::PrintDetails(void) {
cout << "Rectangle of length "<< m_nLength << "\n";
cout << "and width " << m_nWidth << "\n";
C2dObject::PrintDetails();
}
You implement derived class CCircle in a similar way to CRectangle.
}

// CCircle
CCircle::CCircle() {
m_nRadius = 0;
}

CCircle::~CCircle() {
}

void CCircle::SetRadius(int nRadius) {


m_nRadius = nRadius
}

void CCircle::CalcArea(void) {
m_fArea = 3.14 * m_nRadius * m_nRadius;
}

void CCircle::PrintDetails(void) {
cout << "Circle of radius " << m_nRadius << "\n";
C2dObject::PrintDetails();
}

Task 5: Handling a rectangle object


You are now ready to code a simple program for this application.
// main function
void main(void) {
Step 1 of 5

See if you can enter a statement declaring p2dObject as a base-class pointer.

// main function
void main(void) {

MISSING CODE
Result

The code to declare p2dObject as a base-class pointer is C2dObject*p2dObject. The base-


class pointer is required for polymorphic operation.

L & T Infotech Page 83 of 87


OOPS Concepts using C++ Program Using Polymorphism

Step 2 of 5

See if you can complete the statement that creates a rectangle object and assigns its address
to the base-class pointer.

// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=MISSING CODE
Result

The code used to complete the statement is newCRectangle().

To set the length and width of the newly created rectangle object, you need to call
CRectangle::SetDimensions().

Step 3 of 5

See if you can complete the function call to CRectangle::SetDimensions() using the base-
class pointer.

// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
( MISSING CODE)>SetDimensions(4, 2)
Result

The code to complete the function call is


(CRectangle*)p2dObject

Step 4 of 5

See if you can enter a statement to calculate the area of the newly created rectangle object.

// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();

L & T Infotech Page 84 of 87


OOPS Concepts using C++ Program Using Polymorphism

((CRectangle*)p2dObject)->SetDimensions(4, 2);
MISSING CODE
Result

The statement to calculate the area of the newly created rectangle is the generic function call
p2dObject->CalcArea.

You can use another generic call to output the details of the rectangle object.
// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
Step 5 of 5

See if you can enter a statement to destroy the object created.

// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
MISSING CODE
Result

To destroy the object you use the code delete p2dObject.

Task 6: Handling a circle object


You now want to create a circle.
// main function
void main(void) {

C2dObject*p2dObject;

L & T Infotech Page 85 of 87


OOPS Concepts using C++ Program Using Polymorphism

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
delete p2dObject;

// create a circle
Step 1 of 1

See if you can complete the assignment statement that creates a new circle object and
assigns its address to base-class pointer p2dObject.

// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
delete p2dObject;

// create a circle
p2dObject=MISSING CODE
Result

The code to complete the assignment statement is newCCircle();.

You can set the radius of the circle to 3 with this statement.
// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
delete p2dObject;

// create a circle

L & T Infotech Page 86 of 87


OOPS Concepts using C++ Program Using Polymorphism

p2dObject=newCCircle();
((CCircle*)p2dObject)->SetRadius(3);
The remainder of the program is a repetition of the code used to handle a rectangle object. This
completes the program.
// main function
void main(void) {

C2dObject*p2dObject;

// create a rectangle
p2dObject=newCRectangle();
((CRectangle*)p2dObject)->SetDimensions(4, 2);
p2dObject->CalcArea();
p2dObject->PrintDetails();
delete p2dObject;

// create a circle
p2dObject=newCCircle();
((CCircle*)p2dObject)->SetRadius(3);
p2dObject->CalcArea();
p2dObject->PrintDetails();
delete p2dObject;
}
When the program is compiled and run, it produces this output.

L & T Infotech Page 87 of 87

Você também pode gostar