Copy of oop

83
1

description

1 ‫بدايةصفحاتالكتابمنصفحة‬ 3 2 Third year Object Oriented Programming Dr. Mohamed El-Desoky Nassef Higher institute of computer science and information systems at Oct. 6 City 3

Transcript of Copy of oop

Page 1: Copy of oop

1

Page 2: Copy of oop

صفحة من الكتاب صفحات 3بداية

2

Page 3: Copy of oop

Higher institute of computer science and

information systems at Oct. 6 City

Third year

Object Oriented Programming

(oop)Second term

2011-2012

Dr. Mohamed El-Desoky Nassef

3

Page 4: Copy of oop

Reference: object-oriented programming in c++ by Robert Lafore

You were studied chapters 2(basic programming),3(loops and

decision),5(functions),10(pointers).

We will study chapters 4(structures), 6(object&class), 8(operator overload), 9(inheritance).

To be completely familiar you can able lonely complete the reference

Chapter 1

Introduction

Object-Oriented ProgrammingWhy has object-oriented programming become the preferred approach for most software

projects? OOP offers a new and powerful way to cope with complexity. Instead of

viewing a program as a series of steps to be carried out, it views it as a group of objects

that have certain properties and can take certain actions .

The Object-Oriented Approach:*The fundamental idea behind object-oriented languages is to combine into a single unit both data

and the functions that operate on that data. Such a unit is called an object.

*A C++ program typically consists of a number of objects, which communicate with each other

by calling one another’s member functions. The organization of a C++ program is shown in

Figure 1. 1 .

4

Page 5: Copy of oop

Figure 1.1. The organization of a C++ program

An analog you might want to think of objects as departments—such as sales, accounting, personnel,

and so on—in a company. Departments provide an important approach to corporate organization.

*Objects

What kinds of things become objects in object-oriented programs? The answer to this is such as our

institute objects are:

Staff

Student

Employee

Worker

ClassesA class is thus a description of a number of similar objects. An object is often called an “instance” of

a class.

InheritanceThe idea of classes leads to the idea of inheritance. In our daily lifes, we use the concept of

classes divided into subclasses. We know that the animal class is divided into mammals, insects,

birds, and so on. This idea is shown in Figure 1.2. Notice in the figure that features A and B,

which are part of the base class, are common to all the derived classes, but that each derived

class also has features of its own.

In a similar way, an OOP class can become a parent of several subclasses. In C++ the original

class is called the base class; other classes can be defined that share its characteristics, but add

their

own as

well.

These

are

called

derived

classes.

5

Page 6: Copy of oop

Figure 1.2 inheritance

Reusability

Once a class has been written, created, and debugged, it can be distributed to other

programmers for use in their own programs. This is called reusability

However, in OOP, the concept of inheritance provides an important extension to the idea

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

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

existing one. The new class will inherit the capabilities of the old one, but is free to add

new features of its own.

For example, you might have written (or purchased from someone else) a class that

creates a menu system, such as that used in Windows or other Graphic User Interfaces

(GUIs). This class works fine, and you don’t want to change it, but you want to add the

capability to make some menu entries flash on and off. To do this, you simply create a

new class that inherits all the capabilities of the existing one but adds flashing menu

entries.

6

Page 7: Copy of oop

Chapter 2

Structuresthe Structure Definition

A structure is a collection of simple variables. As following:

struct part{int modelnumber;int partnumber;float cost;

;}

The keyword struct introduces the structure definition. Next comes the structure name or tag,

which is part. The declarations of the structure members—modelnumber, partnumber, and

cost—are enclosed in braces. A semicolon follows the closing brace, terminating the entire

structure .

A Simple Structure program// uses parts inventory to demonstrate structures#include <iostream>using namespace std;struct part //declare a structure{int modelnumber; //ID number of widgetint partnumber; //ID number of widget partfloat cost; //cost of part};

int main(){part part1; //define a structure variable

part1.modelnumber = 6244; //give values to structure memberspart1.partnumber = 373;

7

Page 8: Copy of oop

part1.cost = 217.55F;//display structure memberscout<<"model"<<part1.modelnumber;cout<<"part"<<part1.partnumber;cout<<"cost"<<part1.cost << endl;return 0;}Notes:The program’s output looks like this:

Model 6244, part 373, costs $217.55

Accessing Structure Members

Once a structure variable has been defined, its members can be accessed using something

called the dot operator. Here’s how the first member is given a value:

part1.modelnumber = 6244;

The variable name must be used to distinguish one variable from another, such as

part1, part2, and so on, as shown in Figure 2.1

8

Page 9: Copy of oop

Figure 2.1

Initializing Structure Members

The next example shows how structure members can be initialized when the structure variable

is defined.

// shows initialization of structure variables#include <iostream>using namespace std;////////////////////////////////////////////////////////////////struct part //specify a structure{int modelnumber; //ID number of widgetint partnumber; //ID number of widget partfloat cost; //cost of part};////////////////////////////////////////////////////////////////int main(){ //initialize variablepart part1 = { 6244, 373, 217.55F };part part2; //define variable//display first variablecout<<"model1"<<" "<<part1.modelnumber<<" ";cout<<"part1"<<" "<<part1.partnumber<<" ";cout<<"cost1"<<" "<<part1.cost << endl;part2 = part1; //assign first variable to second//display second variablecout<<"model2"<<" "<<part2.modelnumber<<" ";cout<<"part2"<<" "<<part2.partnumber<<" ";cout<<"cost2"<<" "<<part2.cost << endl;return 0;{This program defines two variables of type part: part1 and part2. It initializes part1, prints

out the values of its members, assigns part1 to part2, and prints out its members.

Here’s the output:Model1 6244, part1 373, costs $217.55Model2 6244, part2 373, costs $217.55The same output is repeated since one variable is made equal to the other.

A Measurement Example// englstrc.cpp// demonstrates structures using English measurements#include <iostream>using namespace std;////////////////////////////////////////////////////////////////struct Distance //English distance

9

Page 10: Copy of oop

{int feet;float inches;};int main(){Distance d1, d3; //define two lengthsDistance d2 = { 11, 6.25 }; //define & initialize one length

//get length d1 from usercout << "\nEnter feet: "; cin >> d1.feet;cout << "Enter inches:"; cin >> d1.inches;

//add lengths d1 and d2 to get d3d3.inches = d1.inches + d2.inches; //add the inchesd3.feet = 0; //(for possible carry)if(d3.inches >= 12.0) //if total exceeds 12.0,{ //then decrease inches by 12.0d3.inches -= 12.0; //andd3.feet++; //increase feet by 1}d3.feet += d1.feet + d2.feet; //add the feet

//display all lengthscout << d1.feet << "\'-" << d1.inches << "\"+";cout << d2.feet << "\'-" << d2.inches << "\"=";cout << d3.feet << "\'-" << d3.inches << "\"\n";return 0;{

Here the structure Distance has two members: feet and inches. The inches variable may

have a fractional part, so we’ll use type float for it. Feet are always integers, so we’ll use

type int for them. We define two such distances, d1 and d3, without initializing them,

while we initialize another, d2, to 11'– 6.25''. The program asks the user to enter a

distance in feet and inches, and assigns this distance to d1. (The inches value should be

smaller than 12.0.) It then adds the distance d1 to d2, obtaining the total distance d3.

Finally the program displays the two initial distances and the newly calculated total

distance.

Structures within Structures// englarea.cpp// demonstrates nested structures#include <iostream>using namespace std;////////////////////////////////////////////////////////////////struct Distance //English distance{int feet;float inches;

10

Page 11: Copy of oop

};////////////////////////////////////////////////////////////////struct Room //rectangular area{Distance length; //length of rectangleDistance width; //width of rectangle};////////////////////////////////////////////////////////////////int main(){Room dining; //define a room

dining.length.feet = 13; //assign values to roomdining.length.inches = 6.5;dining.width.feet = 10;dining.width.inches = 0.0;//convert length & widthfloat l = dining.length.feet + dining.length.inches/12;float w = dining.width.feet + dining.width.inches/12;//find area and display itcout << "Dining room area is " << l * w<< " square feet\n" ;return 0;

{

program defines a single variable—dining—of type Room, in the lineRoom dining; // variable dining of type RoomIt then assigns values to the various members of this structure

Accessing Nested

Structure

Members

Because one

structure is nested

inside another,

we must apply the

dot operator

twice to access

the structure

members.

dining.length.feet =

13;

11

Page 12: Copy of oop

figure 2.2

Initializing Nested Structures

How do you initialize a structure variable that itself contains structures? The following state-

ment initializes the variable dining to the same values it is given in the ENGLAREA program:

Room dining = } }13, 6.5{, }10, 0.0{ {;

// englarea.cpp// demonstrates nested structures#include <iostream>using namespace std;////////////////////////////////////////////////////////////////struct Distance //English distance{int feet;float inches;};////////////////////////////////////////////////////////////////struct Room //rectangular area{Distance length; //length of rectangleDistance width; //width of rectangle};////////////////////////////////////////////////////////////////int main(){

Room dining={{13, 6.5},{10, 0.0}}; //define a room12

Page 13: Copy of oop

//convert length & widthfloat l = dining.length.feet + dining.length.inches/12;float w = dining.width.feet + dining.width.inches/12;//find area and display itcout << "Dining room area is " << l * w<< " square feet\n" ;return 0;{

Enumerations

A different approach to defining data type is the enumeration .

Days of the Week

Enumerated types work when you know in advance a finite list of values that a data type can take

on. Here’s an example program, DAYENUM, that uses an enumeration for the days of the week:

//dayenum.cpp //demonstrates enum types

#include <iostream<using namespace std;

//specify enum typeenum days_of_week } Sun, Mon, Tue, Wed, Thu, Fri, Sat {;int main()

{days_of_week day1, day2; //define variables

//of type days_of_weekday1 = Mon; //give values today2 = Thu; //variables

int diff = day2 - day1; //can do integer arithmeticcout << “Days between = “ << diff << endl;

if(day1 < day2) //can do comparisonscout << “day1 comes before day2\n;”

return 0;}An enum declaration defines the set of all names that will be permissible values of the

type. These permissible values are called enumerators. The enum type days_of_week has

seven enumerators: Sun, Mon, Tue, and so on, up to Sat. Figure 2.3 shows the syntax of

an enum declaration.

13

Page 14: Copy of oop

Figure 2.3

Figure 2.4 shows the difference between an int and an enum.

Figure 2.4

You can use the standard arithmetic operators on enum types. In the program we subtract two

values. You can also use the comparison operators, as we show. Here’s the program’s output:

Days between = 3

day1 comes before day2

Ordinarily the first

name in the list is

given the value 0, the

next name is given the

value 1, and so on. In

the DAYENUM

example, the values

Sun through Sat are

14

Page 15: Copy of oop

stored as the integer values 0–6.

Other Examples

Here are some other examples of enumerated data declarations, to give you a feeling for

possi-

ble uses of this feature:

enum months } Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec {;

enum switch } off, on {;

enum meridian } am, pm {;

enum chess } pawn, knight, bishop, rook, queen, king {;

enum coins } penny, nickel, dime, quarter, half-dollar, dollar {;We’ll see other examples in future programs.

Chapter 3

Objects and Classes

15

Page 16: Copy of oop

Defining the Class

Here’s the definition (sometimes called a specifier) for the class smallobj, copied from the

SMALLOBJ listing:

class smallobj //define a class

{

private:

int somedata; //class data

public:

void setdata(int d) //member function to set data

{somedata = d} ;

void showdata() //member function to display data

{cout << “\nData is “ << somedata} ;

;}

The definition starts with the keyword class, followed by the class name—smallobj in this

example. Like a structure, the body of the class is delimited by braces and terminated by a

semicolon. (Don’t forget the semicolon. Remember, data constructs such as structures and

classes end with a semicolon, while control constructs such as functions and loops do not(.

private and public

Private data or functions

can only be accessed from within the class. Public data or functions, on the other hand, are

accessible from outside the class. This is shown in Figure 3.1.

Figure 3.116

Page 17: Copy of oop

A Simple Class program

Our first program contains a class and two objects of that class. Although it’s simple, the program

demonstrates the syntax and general features of classes in C++. Here’s the listing for the

SMALLOBJ program:

// smallobj.cpp// demonstrates a small, simple object#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class smallobj //define a class{private:int somedata; //class datapublic:void setdata(int d) //member function to set data{ somedata = d; }void showdata() //member function to display data{ cout << "Data is " << somedata << endl; }};////////////////////////////////////////////////////////////////int main(){smallobj s1, s2; //define two objects of class smallobj

s1.setdata(1066); //call member function to set datas2.setdata(1776);

s1.showdata(); //call member function to display datas2.showdata();return 0;{

Placing data and functions together into a single entity is a central idea in object-oriented

programming. In SMALLOBJ, the ass—whose name is smallobj—is defined in

the first part of the program. Later, in main(), we define two objects—s1 and s2—that are

instances of that class.

We’ll begin by looking in detail at the first part of the program—the definition of the class

smallobj. Later we’ll focus on what main() does with objects of this class.

17

Page 18: Copy of oop

Using the Class

Now that the class is defined, let’s see how main() makes use of it. We’ll see how objects

are defined, and, once defined, how their member functions are accessed.

Defining Objects

The first statement in main()

smallobj s1, s2;

defines two objects, s1 and s2, of class smallobj. Defining an object is similar to

defining a variable of any data type: Space is set aside for it in memory. Defining objects

in this way means creating them. An object is an instance(that is, a specific example) of a

class. Objects are sometimes called instance variables.

Calling Member Functions

The next two statements in main() call the member function setdata:()

s1.setdata(1066);

s2.setdata(1776);

These statements don’t look like normal function calls. Why are the object names s1 and

s2 connected to the function names with a period? This strange syntax is used to call a

member function that is associated with a specific object. Because setdata() is a member

function of the smallobj class, it must always be called in connection with an object of

this class .

C++ Objects as Physical ObjectsWe’ll create a class based on the structure for the widget parts inventory, last

seen in such examples as PARTS in Chapter 3, “Structures.” Here’s the listing for

OBJPART:

// objpart.cpp// widget part as an object#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class part //define class{private:int modelnumber; //ID number of widgetint partnumber; //ID number of widget partfloat cost; //cost of partpublic:void setpart(int mn, int pn, float c) //set data{

18

Page 19: Copy of oop

modelnumber = mn;partnumber = pn;cost = c;}void showpart() //display data{cout << "Model " << modelnumber;cout <<", part" << partnumber;cout << ", costs $" << cost << endl;}};int main(){part part1; //define object// of class partpart1.setpart(6244, 373, 217.55F); //call member functionpart1.showpart(); //call member functionreturn 0;{

C++ Objects as Data Types

Here’s another kind of entity C++ objects can represent: variables of a user-defined data type.

We’ll use objects to represent distances measured in the English system, as discussed in

Chapter 2. Here’s the listing for ENGLOBJ:

// objects using English measurements#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Distance //English Distance class{private:int feet;float inches;public:void setdist(int ft, float in) //set Distance to args{ feet = ft; inches = in; }

void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;}

void showdist() //display distance{ cout << feet <<" " << inches << endl; }

};////////////////////////////////////////////////////////////////int main(){

19

Page 20: Copy of oop

Distance dist1, dist2; //define two lengths

dist1.setdist(11, 6.25); //set dist1dist2.getdist(); //get dist2 from user

//display lengthscout << "\ndist1 = "; dist1.showdist();cout << "\ndist2 = "; dist2.showdist();cout << endl;return 0;{

Constructors

The ENGLOBJ example shows two ways that member functions can be used to give values

to the data items in an object. Automatic initialization is carried out using a special member

function called a constructor. A constructor is a member function that is executed

automatically whenever an object is created.-

//counter.cpp //object represents a counter variable

#include <iostream<using namespace std;

////////////////////////////////////////////////////////////////class Counter{private:

unsigned int count; //countpublic:

Counter() : count(0) //constructor*/ {empty body} /*

void inc_count() //increment count {count} ;++

int get_count() //return count {return count} ;

;}////////////////////////////////////////////////////////////////

int main(){Counter c1, c2; //define and initialize

cout << “\nc1=” << c1.get_count(); //displaycout << “\nc2=” << c2.get_count;()

c1.inc_count(); //increment c1c2.inc_count(); //increment c2c2.inc_count(); //increment c2

cout << “\nc1=” << c1.get_count(); //display againcout << “\nc2=” << c2.get_count;()

cout << endl;return 0;

}

20

Page 21: Copy of oop

Same Name as the Class

There are some unusual aspects of constructor functions. First, it is no accident that they

have exactly the same name (Counter in this example) as the class of which they are

members. This is one way the compiler knows they are constructors.

Counter Output

The main() part of this program exercises the Counter class by creating two counters, c1 and c2.

It causes the counters to display their initial values, which—as arranged by the constructor—are

0 .It then increments c1 once and c2 twice, and again causes the counters to display themselves

)non-criminal behavior in this context .(Here’s the output:

c1=0

c2=0

c1=1

c2=2

can rewrite the constructor to print a message when it executes.

Counter() : count(0)

{cout << “I’m the constructor\n} ;”

Constructor overloading: more than constructors with the same name

Defining member functions outside the class: function name in class , definition outside the class

Objects as Function Arguments: we will see in next program how?

// englcon.cpp// constructors, adds objects using member function#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Distance //English Distance class{private:int feet;float inches;public: //constructor (no args), defaultDistance() : feet(0), inches(0.0){ }//constructor(two args),so overloading constructors with same namesDistance(int ft, float in) : feet(ft), inches(in){ }

void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;

21

Page 22: Copy of oop

}

void showdist() //display distance{ cout << feet << " "<< inches << endl; }

void add_dist( Distance, Distance ); //declaration};//--------------------------------------------------------------//add lengths d2 and d3,define member function outside the classvoid Distance::add_dist(Distance d2, Distance d3){inches = d2.inches + d3.inches; //add the inchesfeet = 0; //(for possible carry)if(inches >= 12.0) //if total exceeds 12.0,{ //then decrease inchesinches -= 12.0; //by 12.0 andfeet++; //increase feet} //by 1feet += d2.feet + d3.feet; //add the feet}////////////////////////////////////////////////////////////////int main(){Distance dist1, dist3; //define two lengthsDistance dist2(11, 6.25); //define and initialize dist2

dist1.getdist(); //get dist1 from userdist3.add_dist(dist1, dist2);//dist3=dist1+dist2,objects as function argument

//display all lengthscout << "\ndist1 = "; dist1.showdist();cout << "\ndist2 = "; dist2.showdist();cout << "\ndist3 = "; dist3.showdist();cout << endl;return 0;{This program starts with a distance dist2 set to an initial value and adds to it a distance dist1,whose value is supplied by the user, to obtain the sum of the distances. It then displays allthree distances:

Enter feet: 17Enter inches: 5.75

dist1 = 17’-5.75”dist2 = 11’-6.25”dist3 = 29’-0”Let’s see how the new features in this program are implemented.

22

Page 23: Copy of oop

Member Functions Defined Outside the Class

So far we’ve seen member functions that were defined inside the class definition. This need not

always be the case. ENGLCON shows a member function, add_dist(), that is not defined within

the Distance class definition. It is only declared inside the class, with the statement

void add_dist( Distance, Distance );

This tells the compiler that this function is a member of the class but that it will be defined

outside the class declaration, someplace else in the listing.

Figure 3.3

The Default Copy Constructor

We’ve seen two ways to initialize objects. A no-argument constructor can initialize data

members to constant values, and a multi-argument constructor can initialize data members to

values passed as arguments. Let’s mention another way to initialize an object: you can

initialize it with another object of the same type. It’s called the default copy constructor.

// ecopycon.cpp// initialize objects using default copy constructor#include <iostream>using namespace std;class Distance //English Distance class{private:int feet;float inches;public://constructor (no args)Distance() : feet(0), inches(0.0){ }//Note: no one-arg constructor

23

Page 24: Copy of oop

//constructor (two args)Distance(int ft, float in) : feet(ft), inches(in){ }

void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;}void showdist() //display distance{ cout << feet << " "<< inches << endl; }};int main(){Distance dist1(11, 6.25); //two-arg constructorDistance dist2(dist1); //one-arg constructorDistance dist3 = dist1; //also one-arg constructor//display all lengthscout << "\ndist1 = "; dist1.showdist();cout << "\ndist2 ="; dist2.showdist();cout << "\ndist3 = "; dist3.showdist();cout << endl;return 0;

{We initialize dist1 to the value of 11’-6.25” using the two-argument constructor. Then

we define two more objects of type Distance, dist2 and dist3, initializing both to the value

of dist1.

Although this looks like an assignment statement, it is not. Both formats invoke the defaultcopy constructor, and can be used interchangeably. Here’s the output from the program:dist1 = 11’-6.25”dist2 = 11’-6.25”dist3 = 11’-6.25”

Returning Objects from Functions

In the ENGLCON example, we saw objects being passed as arguments to functions. Now we’ll

see an example of a function that returns an object. We’ll modify the ENGLCON program to

produce ENGLRET:

// englret.cpp// function returns value of type Distance#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Distance //English Distance class{private:int feet;float inches;public: //constructor (no args)Distance() : feet(0), inches(0.0)

24

Page 25: Copy of oop

{ } //constructor (two args)Distance(int ft, float in) : feet(ft), inches(in){ }

void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;}void showdist() //display distance{ cout << feet << " " << inches << endl; }Distance add_dist(Distance); //add};//add this distance to d2, return the sumDistance Distance::add_dist(Distance d2){Distance temp; //temporary variabletemp.inches = inches + d2.inches; //add the inchesif(temp.inches >= 12.0) //if total exceeds 12.0,{ //then decrease inchestemp.inches -= 12.0; //by 12.0 andtemp.feet = 1; //increase feet} //by 1temp.feet += feet + d2.feet; //add the feetreturn temp;}////////////////////////////////////////////////////////////////int main(){Distance dist1, dist3; //define two lengthsDistance dist2(11, 6.25); //define, initialize dist2

dist1.getdist(); //get dist1 from userdist3 = dist1.add_dist(dist2); //dist3 = dist1 + dist2

//display all lengthscout << "\ndist1 = "; dist1.showdist();cout << "\ndist2 = "; dist2.showdist();cout << "\ndist3 = "; dist3.showdist();cout << endl;return 0;{

The ENGLRET program is very similar to ENGLCON, but the differences reveal important

aspects of how functions work with objects

25

Page 26: Copy of oop

Static Class DataIf a data item in a class is declared as static, only one such item is created for the entire class, no matter how many objects

there are. A static data item is useful when all objects of the same class must share a common item of information.

Here’s an example, STATDATA, that demonstrates a simple static data member:// statdata.cp// static class data#include <iostream>using namespace std;class foo{private:static int count; //only one data item for all objects//note: “declaration” only!public:foo() //increments count when object created{ count++; }int getcount() //returns count{ return count; }};//--------------------------------------------------------------int foo::count = 0; //*definition* of count////////////////////////////////////////////////////////////////int main(){foo f1, f2, f3; //create three objects

cout << "count is " << f1.getcount() << endl; //each objectcout << "count is " << f2.getcount() << endl; //sees thecout <<"count is " << f3.getcount() << endl; //same valuereturn 0;{

The class foo in this example has one data item, count, which is type static int. The

constructor for this class causes count to be incremented. In main() we define three objects of

class foo. Since the constructor is called three times, count is incremented three times. Another

member function, getcount(), returns the value in count. We call this function from all three

objects, and—as we expected—each prints the same value. Here’s the output :

count is 3

count is 3

count is 3

26

Page 27: Copy of oop

Chapter 4Operator Overloading

Operator overloading is one of the most exciting features of object-oriented programming. It

can transform complex, obscure program listings into intuitively obvious ones. For example,

statements like

d3.addobjects(d1, d2);

or the similar but equally obscure

d3 = d1.addobjects(d2);

can be changed to the much more readable

d3 = d1 + d2;

The rather forbidding term operator overloading refers to giving the normal C++ operators,

such as +, *, <=, and +=, additional meanings when they are applied to user-defined data types.

Normally

a = b + c;

works only with basic types such as int and float, and attempting to apply it when a, b, and c

are objects of a user-defined class will cause complaints from the compiler. However, using

overloading, you can make this statement legal even when a, b, and c are user-defined types.

Overloading Unary Operators

Unary operators act on only one operand. Examples of unary operators are the increment and

decrement operators ++ and example in Chapter 3, “Objects and Classes,” we created a class

Counter to keep track of a count. Objects of that class were incremented by calling a member

function:

c1.inc_count;()

Overloading Unary Operators could have used the

increment operator ++ instead:

++c1;

Let’s rewrite COUNTER to make this possible. Here’s the listing for COUNTPP1:

// countpp1.cpp// increment counter variable with ++ operator#include <iostream>using namespace std;

27

Page 28: Copy of oop

////////////////////////////////////////////////////////////////class Counter{private:unsigned int count; //countpublic:Counter() : count(0) //constructor{ }unsigned int get_count() //return count{ return count; }void operator ++ () //overloading ++{++count;}};int main(){Counter c1, c2; //define and initialize

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

++c1; //increment c1++c2; //increment c2++c2; //increment c2cout << "\nc1=" << c1.get_count(); //display againcout << "\nc2=" << c2.get_count() << endl;return 0;{In this program we create two objects of class Counter: c1 and c2 .

Here’s the program’s output:c1=0 counts are initially 0c2=0

c1=1 incremented oncec2=2 incremented twice

The statements responsible for these operations are++c1;++c2;++c2;

The ++ operator is applied once to c1 and twice to c2. We use prefix notation in this example;The operator Keyword

The keyword operator is used to overload the ++ operator in this declaratory:

void operator() ++

28

Page 29: Copy of oop

Operator Return Values

, we mustprovide a way for operator++() in assignment expressionst to return a value. just that.++c1; //c1=1c2 = ++c1; //c1=2, c2=2

// countpp2.cpp// increment counter variable with ++ operator, return value#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Counter{private:unsigned int count; //countpublic:Counter() : count(0) //constructor{ }unsigned int get_count() //return count{ return count; }Counter operator ++ () //increment count{++count; //increment countCounter temp; //make a temporary Countertemp.count = count; //give it same value as this objreturn temp; //return the copy}};////////////////////////////////////////////////////////////////int main(){Counter c1, c2; //c1=0, c2=0

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

++c1; //c1=1c2 = ++c1; //c1=2, c2=2

cout << "\nc1=" << c1.get_count(); //display againcout <<"\nc2=" << c2.get_count() << endl;return 0;{

Nameless Temporary Objects

In COUNTPP2 to provide a return value for the ++ operator. This required three 29

Page 30: Copy of oop

statements.

Counter temp; // make a temporary Counter object

temp.count = count; // give it same value as this object

return temp; // return it

Let’s examine another approach, as shown in the program COUNTPP3:

/// countpp3.cpp// increment counter variable with ++ operator// uses unnamed temporary object#include <iostream>using namespace std;class Counter{private:unsigned int count; //countpublic:Counter() : count(0) //constructor no args{ }Counter(int c) : count(c) //constructor, one arg{ }unsigned int get_count() //return count{ return count; }Counter operator ++ () //increment count{++count; // increment count, then returnreturn Counter(count); // an unnamed temporary object} // initialized to this count};int main(){Counter c1, c2; //c1=0, c2=0

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

++c1; //c1=1c2 = ++c1; //c1=2, c2=2

cout << "\nc1=" << c1.get_count(); //display againcout << "\nc2="<< c2.get_count() << endl;return 0;{

In this program a single statement

return Counter(count);

30

Page 31: Copy of oop

Overload arithmetic operators,

Comparison operators ,

And arithmetic assignment operators.

Arithmetic Operators

In the ENGLCON program in Chapter3 we showed how two English Distance objects could be

added using a member function add_dist:()dist3.add_dist(dist1, dist2);

By overloading the + operator we can reduce this dense-looking expression todist3 = dist1 + dist2;Here’s the listing for ENGLPLUS, which does just that:// englplus.cpp// overloaded ‘+’ operator adds two Distances#include <iostream>using namespace std;class Distance //English Distance class{private:int feet;float inches;public: //constructor (no args)Distance() : feet(0), inches(0.0){ } //constructor (two args)Distance(int ft, float in) : feet(ft), inches(in){ }void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;}void showdist() const //display distance{ cout << feet << " " << inches << endl; }

Distance operator + ( Distance ) const; //add 2 distances};//--------------------------------------------------------------//add this distance to d2Distance Distance::operator + (Distance d2) const //return sum{int f = feet + d2.feet; //add the feetfloat i = inches + d2.inches; //add the inchesif(i >= 12.0) //if total exceeds 12.0,{ //then decrease inchesi -= 12.0; //by 12.0 andf++; //increase feet by 1} //return a temporary Distance

31

Page 32: Copy of oop

return Distance(f,i); //initialized to sum}int main(){Distance dist1, dist3, dist4; //define distancesdist1.getdist(); //get dist1 from user

Distance dist2(11, 6.25); //define, initialize dist2

dist3 = dist1 + dist2; //single ‘+’ operator

dist4 = dist1 + dist2 + dist3; //multiple ‘+’ operators//display all lengthscout << "dist1 = "; dist1.showdist(); cout << endl;cout << "dist2 = "; dist2.showdist(); cout << endl;cout << "dist3 = "; dist3.showdist(); cout << endl;cout << "dist4 = "; dist4.showdist(); cout << endl;return 0;}

Similar functions could be created to overload other operators in the Distance class, so you

could subtract, multiply, and divide objects of this class in natural-looking ways.

Comparison Operators

Let’s see how to overload a different kind of C++ operator: comparison operators.

Comparing Distances

In our first example we’ll overload the less than operator (<) in the Distance class so that we

can compare two distances. Here’s the listing for ENGLESS:

// engless.cpp// overloaded ‘<’ operator compares two Distances#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Distance //English Distance class{private:int feet;float inches;public: //constructor (no args)-Distance() : feet(0), inches(0.0){ } //constructor (two argsDistance(int ft, float in) : feet(ft), inches(in){ }void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;

32

Page 33: Copy of oop

}void showdist() const //display distance{ cout << feet << " " << inches << endl; }bool operator < (Distance) const; //compare distances};//compare this distance with d2bool Distance::operator < (Distance d2) const //return the sum{float bf1 = feet + inches/12;float bf2 = d2.feet + d2.inches/12;return (bf1 < bf2) ? true : false;}////////////////////////////////////////////////////////////////int main(){Distance dist1; //define Distance dist1dist1.getdist(); //get dist1 from user

Distance dist2(6, 2.5); //define and initialize dist2//display distancescout << "\ndist1 = "; dist1.showdist();cout << "\ndist2 = "; dist2.showdist();

if( dist1 < dist2 ) //overloaded ‘<’ operatorcout << "\ndist1 is less than dist2";elsecout << "\ndist1 is greater than (or equal to) dist2";cout << endl;return 0;}

Arithmetic Assignment Operators

Let’s finish up our exploration of overloaded binary operators with an arithmetic

assignment

operator: the += operator. Recall that this operator combines assignment and addition into

one

step. We’ll use this operator to add one English distance to a second, leaving the result in

the

first. This is similar to the ENGLPLUS example shown earlier, but there is a subtle

difference.

Here’s the listing for ENGLPLEQ:

// englpleq.cpp// overloaded ‘+=’ assignment operator#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Distance //English Distance class{

33

Page 34: Copy of oop

private:int feet;float inches;public: //constructor (no args)Distance() : feet(0), inches(0.0){ } //constructor (two args)Distance(int ft, float in) : feet(ft), inches(in){ }void getdist() //get length from user{cout << "\nEnter feet: "; cin >> feet;cout << "Enter inches: "; cin >> inches;}void showdist() const //display distance{ cout << feet << " " << inches << endl; }void operator += ( Distance );};//--------------------------------------------------------------//add distance to this onevoid Distance::operator += (Distance d2){feet += d2.feet; //add the feetinches += d2.inches; //add the inchesif(inches >= 12.0) //if total exceeds 12.0,{ //then decrease inchesinches -= 12.0; //by 12.0 andfeet++; //increase feet} //by 1}////////////////////////////////////////////////////////////////int main(){Distance dist1; //define dist1dist1.getdist(); //get dist1 from usercout << "\ndist1 = "; dist1.showdist();

Distance dist2(11, 6.25); //define, initialize dist2cout << "\ndist2 = "; dist2.showdist();

dist1 += dist2; //dist1 = dist1 + dist2cout << "\nAfter addition,";cout << "\ndist1 = "; dist1.showdist();cout << endl;return 0;{

Not All Operators Can Be Overloaded

The following operators cannot be overloaded: the member access or dot operator (.), the

scope resolution operator (::), and the conditional operator (?:). Also, the pointer-to-member

operator (->), which we have not yet encountered, cannot be overloaded .

34

Page 35: Copy of oop

Chapter5

Inheritance

IN THIS CHAPTER

•Derived Class and Base Class

•Derived Class Constructors

•Overriding Member Functions

•Inheritance in the English Distance Class

•Class Hierarchies

•Public and Private Inheritance

•Levels of Inheritance

•Multiple Inheritances

•Private Derivation in EMPMULT

Aggregation: Classes Within Classes

•Inheritance and Program Development

35

Page 36: Copy of oop

Inheritance is probably the most powerful feature of object-oriented programming, after classes

themselves. Inheritance is the process of creating new classes, called derived classes, from

existing or base classes. The derived class inherits all the capabilities of the base class but

can add embellishments and refinements of its own. The base class is unchanged by this

process. The inheritance relationship is shown in Figure 5.1.

Figure 5.1.

The arrow in Figure 5.1 goes in the opposite direction of what you might expect. If it pointed

down we would label it inheritance. However, the more common approach is to point the

arrow up, from the derived class to the base class, and to think of it as a “derived from” arrow.

36

Page 37: Copy of oop

Derived Class and Base Class

Remember the COUNTPP3 example from Chapter 8, “Operator Overloading”? This

program used a class Counter as a general-purpose counter variable. A count could be

initialized to 0 or to a specified number with constructors, incremented with the ++

operator, and read with the

get_count() operator.

Let’s suppose that we have worked long and hard to make the Counter class operate just

the way we want, and we’re pleased with the results, except for one thing. We really need

a way to decrement the count. Perhaps we’re counting people entering a bank, and we

want to increment the count when they come in and decrement it when they go out, so

that the count represents the number of people in the bank at any moment.

we can use inheritance to create a new class based on Counter, without modifying

Counter itself. Here’s the listing for COUNTEN, which includes a new class, CountDn,

that adds a decrement operator to the Counter class:

// counten.cpp// inheritance with Counter class#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Counter //base class{protected: //NOTE: not privateunsigned int count; //countpublic:Counter() : count(0) //no-arg constructor{ }Counter(int c) : count(c) //1-arg constructor{ }unsigned int get_count() const //return count{ return count; }Counter operator ++ () //incr count (prefix){ return Counter(++count); }};////////////////////////////////////////////////////////////////class CountDn : public Counter //derived class see : not::{ // countDn has all all proparties of class conter public:Counter operator -- () //decr count (prefix){ return Counter(--count); }};////////////////////////////////////////////////////////////////

37

Page 38: Copy of oop

int main(){CountDn c1; //c1 of class CountDn

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

++c1; ++c1; ++c1; //increment c1, 3 timescout << "\nc1= " << c1.get_count(); //display it

--c1; --c1; //decrement c1, twicecout << "\nc1=" << c1.get_count(); //display itcout << endl;return 0;{

Specifying the Derived ClassThe new CountDn class inherits all the features of the Counter class. CountDn doesn’t need a

constructor or the get_count() or operator++() functions, because these already exist in Counter.

The first line of CountDn specifies that it is derived from Counter:

Accessing Base Class Members

An important topic in inheritance is knowing when a member function in the base class can be

used by objects of the derived class. This is called accessibility .

The protected Access Specifier

As in the table 5.1

TABLE 5.1 Inheritance and Accessibility

Access Accessible from Accessible from Accessible fromSpecifier Own Class Derived Class Objects Outside Class

public yes yes yes

protected yes yes noprivate yes no no

Base Class UnchangedRemember that, even if other classes have been derived from it, the base class remainsunchanged.

38

Page 39: Copy of oop

Other TermsIn some languages the base class is called the superclass and the derived class is called thesubclass. Some writers also refer to the base class as the parent and the derived class as the child.

Derived Class Constructors What happens if we want to initialize a CountDn object to a value? Can the one-argument constructor in Counter be used? The answer is no. To make such a definition work we mustwrite a new set of constructors for the derived class. This is shown in the COUNTEN2 program.// counten2.cpp// constructors in derived class#include <iostream>using namespace std;////////////////////////////////////////////////////////////////class Counter{protected: //NOTE: not privateunsigned int count; //countpublic:Counter() : count() //constructor, no args{ }Counter(int c) : count(c) //constructor, one arg{ }unsigned int get_count() const //return count{ return count; }Counter operator ++ () //incr count (prefix){ return Counter(++count); }};////////////////////////////////////////////////////////////////class CountDn : public Counter{public:CountDn() : Counter() //constructor, no args{ }CountDn(int c) : Counter(c) //constructor, 1 arg{ }CountDn operator -- () //decr count (prefix){ return CountDn(--count); }};////////////////////////////////////////////////////////////////int main(){CountDn c1; //class CountDn

39

Page 40: Copy of oop

CountDn c2(100);cout << "\nc1=" << c1.get_count(); //displaycout << "\nc2=" << c2.get_count(); //display++c1; ++c1; ++c1; //increment c1cout << "\nc1=" << c1.get_count(); //display it--c2; --c2; //decrement c2cout << "\nc2=" << c2.get_count(); //display itCountDn c3 = --c2; //create c3 from c2cout <<"\nc3=" << c3.get_count(); //display c3cout << endl;return 0;}

Overriding Member FunctionsYou can use member functions in a derived class that override—that is, have the same nameas—those in the base class. You might want to do this so that calls in your program work thesame way for objects of both base and derived classes.Here’s an example based on the STAKARAY “Arrays ” That program modeled a stack, a simple data storage device. It allowed you to push integers onto the stack and pop them off. However, STAKARAY had a potential flaw. If you tried to push too many items onto the stack, the program might bomb, since data would be placed in memory beyond the end of the st[] array. Or if you tried to pop too many items, the results would be meaningless, since you would be reading data from memory locations outside the array.To cure these defects we’ve created a new class, Stack2, derived from Stack. Objects ofStack2 behave in exactly the same way as those of Stack, except that you will be warned ifyou attempt to push too many items on the stack or if you try to pop an item from an emptystack. Here’s the listing for STAKEN:// staken.cpp// overloading functions in base and derived classes#include <iostream>using namespace std;#include <process.h> //for exit()////////////////////////////////////////////////////////////////class Stack{

40

Page 41: Copy of oop

protected: //NOTE: can’t be privateenum { MAX = 3 }; //size of stack arrayint st[MAX]; //stack: array of integersint top; //index to top of stackpublic:Stack() //constructor{ top = -1; }void push(int var) //put number on stack{ st[++top] = var; }int pop() //take number off stack{ return st[top--]; }};////////////////////////////////////////////////////////////////class Stack2 : public Stack{public:void push(int var) //put number on stack{if(top >= MAX-1) //error if stack full{ cout << "\nError: stack is full"; exit(1); }Stack::push(var); //call push() in Stack class}int pop() //take number off stack{if(top < 0) //error if stack empty{ cout << "\nError: stack is empty\n"; exit(1); }return Stack::pop(); //call pop() in Stack class}};////////////////////////////////////////////////////////////////int main(){Stack2 s1;s1.push(11); //push some values onto stacks1.push(22);s1.push(33);cout << endl << s1.pop(); //pop some values from stackcout << endl << s1.pop();cout << endl << s1.pop();cout << endl << s1.pop(); //oops, popped one too many...cout << endl;return 0;}

In this program the Stack class is just the same as it was in the STAKARAY program, except thatthe data members have been made protected.

Which Function Is Used?

41

Page 42: Copy of oop

The Stack2 class contains two functions, push() and pop(). These functions have the samenames, and the same argument and return types, as the functions in Stack. When we call thesefunctions from main(), in statements likes1.push(11);

how does the compiler know which of the two push() functions to use? Here’s the rule: Whenthe same function exists in both the base class and the derived class, the function in the derivedclass will be executed. (This is true of objects of the derived class. Objects of the base classdon’t know anything about the derived class and will always use the base class functions.) Wesay that the derived class function overrides the base class function. So in the preceding statement,since s1 is an object of class Stack2, the push() function in Stack2 will be executed,not the one in Stack.The push() function in Stack2 checks to see whether the stack is full. If it is, it displays anerror message and causes the program to exit. If it isn’t, it calls the push() function in Stack.Similarly, the pop() function in Stack2 checks to see whether the stack is empty. If it is, itprints an error message and exits; otherwise, it calls the pop() function in Stack.In main() we push three items onto the stack, but we pop four. The last pop elicits an errormessage332211Error: stack is emptyand terminates the program.

42

Page 43: Copy of oop

Scope Resolution with Overridden FunctionsHow do push() and pop() in Stack2 access push() and pop() in Stack? They use the scoperesolution operator, ::, in the statementsStack::push(var);andreturn Stack::pop();These statements specify that the push() and pop() functions in Stack are to be called. Withoutthe scope resolution operator, the compiler would think the push() and pop() functions inStack2 were calling themselves, which—in this case—would lead to program failure. Using thescope resolution operator allows you to specify exactly what class the function is a member of.Class HierarchiesIn the examples so far in this chapter, inheritance has been used to add functionality to anexisting class. Now let’s look at an example where inheritance is used for a different purpose:as part of the original design of a program.Our example models a database of employees of a widget company. We’ve simplified the situationso that only three kinds of employees are represented. Managers manage, scientists performresearch to develop better widgets, and laborers operate the dangerous widget-stamping presses.The database stores a name and an employee identification number for all employees, no matterwhat their category. However, for managers, it also stores their titles and golf club dues. Forscientists, it stores the number of scholarly articles they have published. Laborers need noadditional data beyond their names and numbers.

43

Page 44: Copy of oop

Our example program starts with a base class employee. This class handles the employee’s lastname and employee number. From this class three other classes are derived: manager, scientist,and laborer. The manager and scientist classes contain additional information about these

categories of employee, and member functions to handle this information, as shown: // employ.cpp// models employee database using inheritance#include <iostream>using namespace std;const int LEN = 80; //maximum length of names////////////////////////////////////////////////////////////////class employee //employee class{private:char name[LEN]; //employee nameunsigned long number; //employee numberpublic:void getdata(){cout << “\n Enter last name: “; cin >> name;cout << “ Enter number: “; cin >> number{void putdata() const{cout << “\n Name: “ << name;cout << “\n Number: “ << number;}};////////////////////////////////////////////////////////////////class manager : public employee //management class{private:char title[LEN]; //”vice-president” etc.double dues; //golf club duespublic:void getdata(){employee::getdata();cout << “ Enter title: “; cin >> title;cout << “ Enter golf club dues: “; cin >> dues;}void putdata() const{employee::putdata();cout << “\n Title: “ << title;

44

Page 45: Copy of oop

cout << “\n Golf club dues: “ << dues;}};////////////////////////////////////////////////////////////////class scientist : public employee //scientist class{private:int pubs; //number of publicationspublic:void getdata(){employee::getdata();cout << “ Enter number of pubs: “; cin >> pubs;}void putdata() const{employee::putdata();cout << “\n Number of publications: “ << pubs;}};////////////////////////////////////////////////////////////////class laborer : public employee //laborer class}};////////////////////////////////////////////////////////////////int main(){

“Abstract” Base ClassNotice that we don’t define any objects of the base class employee. We use this as a generalclass whose sole purpose is to act as a base from which other classes are derived.The laborer class operates identically to the employee class, since it contains no additionaldata or functions. It may seem that the laborer class is unnecessary, but by making it a separateclass we emphasize that all classes are descended from the same source, employee. Also, if inthe future we decided to modify the laborer class, we would not need to change the declarationfor employee.

Public and Private Inheritance45

Page 46: Copy of oop

The program specifies a base class, A, with private, protected, and public data items. Twoclasses, B and C, are derived from A. B is publicly derived and C is privately derived.As we’ve seen before, functions in the derived classes can access protected and public data inthe base class. Objects of the derived classes cannot access private or protected members of thebase class.What’s new is the difference between publicly derived and privately derived classes. Objects ofthe publicly derived class B can access public members of the base class A, while objects of theprivately derived class C cannot; they can only access the public members of their own derivedclass. This is shown in Figure 5.3.

Figure 5.3.

46

Page 47: Copy of oop

Levels of InheritanceClasses can be derived from classes that are themselves derived. Here’s a miniprogram thatshows the idea:class A{ };class B : public A{ };class C : public B{ };Here B is derived from A, and C is derived from B. The process can be extended to an arbitrarynumber of levels—D could be derived from C, and so on.As a more concrete example, suppose that we decided to add a special kind of laborer called aforeman to the EMPLOY program. We’ll create a new program, EMPLOY2, that incorporatesobjects of class foreman.Since a foreman is a kind of laborer, the foreman class is derived from the laborer class as in figure 5.3.

Figure 5.3

Foremen oversee the widget-stamping operation, supervising groups of laborers. They are

47

Page 48: Copy of oop

responsible for the widget production quota for their group. A foreman’s ability is measured bythe percentage of production quotas successfully met. The quotas data item in the foremanclass represents this percentage. Here’s the listing for EMPLOY2:// employ2.cpp// multiple levels of inheritance#include <iostream>using namespace std;const int LEN = 80; //maximum length of names////////////////////////////////////////////////////////////////class employee{private:char name[LEN]; //employee nameunsigned long number; //employee numberpublic:void getdata(){cout << "\n Enter last name: "; cin >> name;cout << " Enter number: "; cin >> number;}void putdata() const{cout << "\n Name: " << name;cout << "\n Number: " << number;}};////////////////////////////////////////////////////////////////class manager : public employee //manager class{private:char title[LEN]; //”vice-president” etc.double dues; //golf club duespublic:void getdata(){employee::getdata();cout << " Enter title: "; cin >> title;cout << " Enter golf club dues: "; cin >> dues;}void putdata() const{employee::putdata();cout << "\n Title: "<< title;cout << "\n Golf club dues: "<< dues;}};////////////////////////////////////////////////////////////////class scientist : public employee //scientist class

48

Page 49: Copy of oop

{private:int pubs; //number of publicationspublic:void getdata(){employee::getdata();cout <<" Enter number of pubs: "; cin >> pubs;}void putdata() const{employee::putdata();cout << "\n Number of publications:" << pubs;}

};////////////////////////////////////////////////////////////////class laborer : public employee //laborer class{};////////////////////////////////////////////////////////////////class foreman : public laborer //foreman class{private:float quotas; //percent of quotas met successfullypublic:void getdata(){laborer::getdata();cout << " Enter quotas: "; cin >> quotas;}void putdata() const{laborer::putdata();cout << "\n Quotas: " << quotas;}};////////////////////////////////////////////////////////////////int main(){laborer l1;foreman f1;cout << endl;cout << "\nEnter data for laborer 1";l1.getdata();cout << "\nEnter data for foreman 1";f1.getdata();cout << endl;cout << "\nData on laborer 1";l1.putdata();cout << "\nData on foreman 1";f1.putdata();

49

Page 50: Copy of oop

cout << endl;return 0;{

Multiple InheritanceA class can be derived from more than one base class. This is called multiple inheritance.Figure5.4 shows how this looks when a class C is derived from base classes A and B.

Figure5.4

The syntax for multiple inheritance is similar to that for single inheritance. In the situationshown in Figure 5.4, the relationship is expressed like this:class A // base class A{};class B // base class B{};class C : public A, public B // C is derived from A and B{};The base classes from which C is derived are listed following the colon in C’s specification;they are separated by commas.

Member Functions in Multiple InheritanceAs an example of multiple inheritance, suppose that we need to record the educationalexperience of some of the employees in the EMPLOY program. Let’s also suppose that, perhaps

50

Page 51: Copy of oop

in a different project, we’ve already developed a class called student that models students withdifferent educational backgrounds. We decide that instead of modifying the employee class toincorporate educational data, we will add this data by multiple inheritance from the studentclass.The student class stores the name of the school or university last attended and the highestdegree received. Both these data items are stored as strings. Two member functions, getedu()and putedu(), ask the user for this information and display it.Educational information is not relevant to every class of employee. Let’s suppose, somewhatundemocratically, that we don’t need to record the educational experience of laborers; it’s onlyrelevant for managers and scientists. We therefore modify manager and scientist so that theyinherit from both the employee and student classes, as shown in Figure 5.5.

Figure 5.5

51

Page 52: Copy of oop

The syntax for multiple inheritances is similar to that for single inheritance. In the situationshown in Figure 5.5 the relationship is expressed like this:class A // base class A{};class B // base class B{};class C : public A, public B // C is derived from A and B{};The base classes from which C is derived are listed following the colon in C’s specification;they are separated by commas.Here’s a miniprogram that shows these relationships (but leaves out everything else):class student{ };class employee{ };class manager : private employee, private student{ };class scientist : private employee, private student{ };class laborer : public employee{ };And here, featuring considerably more detail, is the listing for EMPMULT://empmult.cpp//multiple inheritance with employees and degrees#include <iostream>using namespace std;const int LEN = 80; //maximum length of names////////////////////////////////////////////////////////////////class student //educational background{private:

52

Page 53: Copy of oop

char school[LEN]; //name of school or universitychar degree[LEN]; //highest degree earnedpublic:void getedu(){cout << " Enter name of school or university: ";cin >> school;cout << " Enter highest degree earned \n";cout << " (Highschool, Bachelor’s, Master’s, PhD): ";cin >> degree;}void putedu() const{cout << "\n School or university: " << school;cout << "\n Highest degree earned: " << degree;}};////////////////////////////////////////////////////////////////class employee{private:char name[LEN]; //employee nameunsigned long number; //employee numberpublic:void getdata(){cout << "\n Enter last name: "; cin >> name;cout << " Enter number: "; cin >> number;}void putdata() const{cout <<"\n Name:" << name;cout << "\n Number: " << number;}};////////////////////////////////////////////////////////////////class manager : private employee, private student //management{private:char title[LEN]; //”vice-president” etc.double dues; //golf club duespublic:void getdata(){employee::getdata();cout << " Enter title: "; cin >> title;cout << " Enter golf club dues: "; cin >> dues;student::getedu();}void putdata() const{employee::putdata();cout << "\n Title: " << title;

53

Page 54: Copy of oop

cout << "\n Golf club dues: " << dues;student::putedu();}};////////////////////////////////////////////////////////////////class scientist : private employee, private student //scientist{private:int pubs; //number of publicationspublic:void getdata(){employee::getdata();cout <<" Enter number of pubs: "; cin >> pubs;student::getedu();}void putdata() const{employee::putdata();cout << "\n Number of publications: " << pubs;student::putedu();}};////////////////////////////////////////////////////////////////class laborer : public employee //laborer{};////////////////////////////////////////////////////////////////int main(){manager m1;scientist s1, s2;laborer l1;cout << endl;cout << "\nEnter data for manager 1"; //get data form1.getdata(); //several employeescout << "\nEnter data for scientist 1";s1.getdata();cout << "\nEnter data for scientist 2";s2.getdata();cout << "\nEnter data for laborer 1";l1.getdata();cout << "\nData on manager 1"; //display data form1.putdata(); //several employeescout << "\nData on scientist 1";s1.putdata();cout << "\nData on scientist 2";s2.putdata();cout << "\nData on laborer 1";l1.putdata();cout << endl;return 0;}

54

Page 55: Copy of oop

Aggregation: Classes Within ClassesWe’ll discuss aggregation here because, while it is not directly related to inheritance, bothaggregation and inheritance are class relationships that are more specialized than associations.It is instructive to compare and contrast them.If a class B is derived by inheritance from a class A, we can say that “B is a kind of A.” This is

because B has all the characteristics of A, and in addition some of its own

Aggregation in the EMPCONT ProgramLet’s rearrange the EMPMULT program to use aggregation instead of inheritance. In EMPMULT themanager and scientist classes are derived from the employee and student classes using theinheritance relationship. In our new program, EMPCONT, the manager and scientist classescontain instances of the employee and student classes as attributes. This aggregation relationshipis shown in Figure 5.6

55

Page 56: Copy of oop

Figure 5.6

The following miniprogram shows these relationships in a different way:class student{};class employee{};class manager{student stu; // stu is an object of class studentemployee emp; // emp is an object of class employee};class scientist{student stu; // stu is an object of class studentemployee emp; // emp is an object of class employee};class laborer{employee emp; // emp is an object of class employee};

Here’s the full-scale listing for EMPCONT:

// empcont.cpp// containership with employees and degrees#include <iostream>#include <string>using namespace std;////////////////////////////////////////////////////////////////class student //educational background{private:string school; //name of school or universitystring degree; //highest degree earnedpublic:void getedu(){cout << " Enter name of school or university: ";cin >> school;cout << " Enter highest degree earned \n";cout << " (Highschool, Bachelor’s, Master’s, PhD):";cin >> degree;}void putedu() const{cout << "\n School or university: " << school;cout << "\n Highest degree earned: " << degree;}};////////////////////////////////////////////////////////////////class employee

56

Page 57: Copy of oop

{private:string name; //employee nameunsigned long number; //employee numberpublic:void getdata(){cout << "\n Enter last name: "; cin >> name;cout << " Enter number: "; cin >> number;}void putdata() const{cout << "\n Name: " << name;cout << "\n Number: " << number;}};////////////////////////////////////////////////////////////////class manager //management

{private:string title; //”vice-president” etc.double dues; //golf club duesemployee emp; //object of class employeestudent stu; //object of class studentpublic:void getdata(){emp.getdata();cout << " Enter title: "; cin >> title;cout << " Enter golf club dues: "; cin >> dues;stu.getedu();}void putdata() const{emp.putdata();cout << "\n Title: " << title;cout << "\n Golf club dues: " << dues;stu.putedu();}};////////////////////////////////////////////////////////////////class scientist //scientist{private:int pubs; //number of publicationsemployee emp; //object of class employeestudent stu; //object of class studentpublic:void getdata(){

57

Page 58: Copy of oop

emp.getdata();cout << " Enter number of pubs: "; cin >> pubs;stu.getedu();}void putdata() const{emp.putdata();cout << "\n Number of publications: " << pubs;stu.putedu();}};////////////////////////////////////////////////////////////////class laborer //laborer{private:employee emp; //object of class employeepublic:void getdata(){ emp.getdata(); }void putdata() const{ emp.putdata(); }};////////////////////////////////////////////////////////////////int main(){manager m1;scientist s1, s2;laborer l1;cout << endl;cout << "\nEnter data for manager 1"; //get data form1.getdata(); //several employeescout << "\nEnter data for scientist 1";s1.getdata();cout << "\nEnter data for scientist 2";s2.getdata();cout <<"\nEnter data for laborer 1";l1.getdata();cout << "\nData on manager 1"; //display data form1.putdata(); //several employeescout << "\nData on scientist 1";s1.putdata();cout << "\nData on scientist 2";s2.putdata();cout << "\nData on laborer 1";l1.putdata();cout << endl;return 0;}

The student and employee classes are the same in EMPCONT as they were in EMPMULT, but they are related in a different way to the manager and scientist classes.

58

Page 59: Copy of oop

Composition: A Stronger AggregationComposition is a stronger form of aggregation. It has all the characteristics of aggregation, plustwo more:• The part may belong to only one whole.• The lifetime of the part is the same as the lifetime of the whole.A car is composed of doors (among other things). The doors can’t belong to some other car,and they are born and die along with the car. A room is composed of a floor, ceiling, andwalls. While aggregation is a “has a” relationship, composition is a “consists of” relationship.In UML diagrams, composition is shown in the same way as aggregation, except that thediamond-shaped arrowhead is solid instead of open. This is shown in Figure 5.7.

Figure 5.7.

59

Page 60: Copy of oop

Even a single object can be related to a class by composition. In a car there is only one engine.Inheritance and Program DevelopmentThe program-development process, as practiced for decades by programmers everywhere, isbeing fundamentally altered by object-oriented programming. This is due not only to the useof classes in OOP but to inheritance as well. Let’s see how this comes about.Programmer A creates a class. Perhaps it’s something like the Distance class, with a completeset of member functions for arithmetic operations on a user-defined data type.Programmer B likes the Distance class but thinks it could be improved by using signeddistances. The solution is to create a new class, like DistSign in the ENGLEN example, thatis derived from Distance but incorporates the extensions necessary to implement signed distances.Programmers C and D then write applications that use the DistSign class.Programmer B may not have access to the source code for the Distance member functions,and programmers C and D may not have access to the source code for DistSign. Yet, becauseof the software reusability feature of C++, B can modify and extend the work of A, and C andD can make use of the work of B (and A).Notice that the distinction between software tool developers and application writers is becomingblurred. Programmer A creates a general-purpose programming tool, the Distance class.Programmer B creates a specialized version of this class, the DistSign class. Programmers C

60

Page 61: Copy of oop

and D create applications. A is a tool developer, and C and D are applications developers. B issomewhere in between. In any case OOP is making the programming scene more flexible andat the same time more complex.In Chapter 13 we’ll see how a class can be divided into a client-accessible part and a part that isdistributed only in object form, so it can be used by other programmers without the distributionof source code.SummaryA class, called the derived class, can inherit the features of another class, called the base class.The derived class can add other features of its own, so it becomes a specialized version of thebase class. Inheritance provides a powerful way to extend the capabilities of existing classes,and to design programs using hierarchical relationships.Accessibility of base class members from derived classes and from objects of derived classes isan important issue. Data or functions in the base class that are prefaced by the keyword protectedcan be accessed from derived classes but not by any other objects, including objects ofderived classes. Classes may be publicly or privately derived from base classes. Objects of apublicly derived class can access public members of the base class, while objects of a privatelyderived class cannot.A class can be derived from more than one base class. This is called multiple inheritance. Aclass can also be contained within another class.In the UML, inheritance is called generalization. This relationship is represented in class diagrams

61

Page 62: Copy of oop

by an open triangle pointing to the base (parent) class.Aggregation is a “has a” or “part-whole” relationship: one class contains objects of anotherclass. Aggregation is represented in UML class diagrams by an open diamond pointing to the“whole” part of the part-whole pair. Composition is a strong form of aggregation. Its arrowheadis solid rather than open.Inheritance permits the reusability of software: Derived classes can extend the capabilities ofbase classes with no need to modify—or even access the source code of—the base class. Thisleads to new flexibility in the software development process, and to a wider range of roles forsoftware developers .

62

Page 63: Copy of oop

63