chapter 14 - inheritancewps.aw.com/wps/media/objects/80/82902/savitchimch14.doc · web viewchapter...

48
Chapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming technique. This technique is of great importance for several reasons. OOP enables the solution domain to be closer to the problem domain, in part, by providing solution domain modeling for actors and behavior in problems. It facilitates code reuse, and it helps the programmer to better manage complexity through better abstraction and encapsulation. In our earlier study of data abstraction, we identified objects and classes. In C++, an object is a variable that has functions (behavior) and data associated with it. We noted that classes encapsulate the essence of objects that are declared to be of class type. We characterized inheritance as creating a new class by "adding features to the features obtained from another class." We used the derivation of the ifstream class from istream, and the derivation of ofstream from ostream as examples of inheritance. We found that an object has identity (name, type), behavior (actions of the member functions), and state (the values of

Upload: vanhanh

Post on 28-May-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Chapter 14

Inheritance

0. Introduction

Object-Oriented Programming (OOP) is a powerful programming technique. This

technique is of great importance for several reasons. OOP enables the solution domain to

be closer to the problem domain, in part, by providing solution domain modeling for

actors and behavior in problems. It facilitates code reuse, and it helps the programmer to

better manage complexity through better abstraction and encapsulation.

In our earlier study of data abstraction, we identified objects and classes. In C++, an

object is a variable that has functions (behavior) and data associated with it. We noted

that classes encapsulate the essence of objects that are declared to be of class type. We

characterized inheritance as creating a new class by "adding features to the features

obtained from another class." We used the derivation of the ifstream class from

istream, and the derivation of ofstream from ostream as examples of inheritance.

We found that an object has identity (name, type), behavior (actions of the member

functions), and state (the values of the variables defined in the class and set on behalf of

our object.).

This chapter studies the inheritance relationship that classes bear to other, that is, the “is

a” relation. This chapter enables the student programmer to use inheritance in problem

solving.

1. Outline of topics in the chapter

14.1 Inheritance Basics

Derived Classes

Constructors in Derived Classes

Page 2: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 2Chapter 14 Inheritance

The protected Qualifier

Redefinition of Member Functions

Redefining versus Overloading

Access to a Redefined Base Function

Functions That Are Not Inherited

14.2 Programming With Inheritance

Assignment Operators and Copy Constructors in Derived Classes

Destructors in Derive Classes

Protected and Private Inheritance

Multiple Inheritance

2. General remarks on the chapter

14.1 Inheritance Basics

In the real world, objects exist in relation to one another. In solving a problem, we need

to be as close to the problem as we can, within an abstraction that allows us to retain only

the details to necessary to meaningful solution of our problem. Abstraction means that we

ignore details. Ignoring details simplifies the model so that we can solve the problem.

Retaining details makes our solution realistic. A meaningful solution means we have

balanced the details ignored to decrease the complexity with the essential details retained.

In a problem, we may find that objects are similar to other objects. The abstraction of the

commonality among objects in C++ is done with classes, and abstraction of the

commonality among objects that have distinguishing differences is expressed in C++ by

the notion of inheritance. The commonalities are encapsulated in the base class, the

distinctions are encapsulated in the derived class or classes, and the commonality is

passed from the base class to the derived class by the inheritance mechanism.

For example, consider a class of (general) vehicles. We may think of several kinds of

vehicle whose properties we list here.

vehicle that carries passengers (a car),

small vehicle that carries cargo in the open (a pickup truck),

Page 3: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 3Chapter 14 Inheritance

vehicle that carries cargo in an enclosure (Van),

vehicle that carries cargo enclosed and is articulated (A tractor-trailer).

The Car, Truck, Van, and TractorTrailer classes could inherit their common

features from the class vehicle. (Perhaps the common features of vehicles are

having a housing for the operator, a frame, wheels, a steering mechanism, a motor and

transmission.) We see that inheritance can creates a new class, called the derived class,

that is an extension, or modification of one or more existing classes, called the base

classes1.

We speak of single inheritance in the situation where there is only one base class.

Multiple inheritance refers to the situation where there is more than one base class. We

will not discuss multiple inheritance further as the text barely mentions this topic.

In these cases, a car is a vehicle, so are pickups, vans, and tractor-trailers. We describe

this relationship as an "is-a" relation. A car "is a" vehicle, a pickup truck "is a" vehicle,

and so on. The class abstraction of vehicle is the base class and the vehicles that bear the

"is a" relation to the base class are derived classes. Each base class has features, that the

derived class inherits those features and adds its own, extra, added features to the base

class to form its distinctiveness. If we write this example in C++, we haveclass Vehicle {/* . . . */};

class Car : public Vehicle { /* . . . */};

class Truck : public Vehicle { /* . . . */};

class TractorTrailer public Truck {/* . . . */};

class StationWagon : public Car {/* . . . */ };

class Boat : public Vehicle {/* . . .*/};

In this, example, we could illustrate multiple inheritance by defining

class Emergency {/* . . . */}; and have had a class PoliceCar

inherit from both class Car and class Emergency. We could have a

class Ambulance that inherits from both class Truck and

class EmergencyVehicle. The PoliceCar and Ambulance would inherit features

from class Car and the derived class adds its distinguishing features. The text only 1 In the C++ FAQ, pages 101 and 102, Cline and Lomow warn against use of “is a specialization of” and “is a subset of” as heuristics for detecting inheritance. Neither of “is a specialization of” or “is a subset of” implies that Derived must support all the operations defined by Base. The authors suggest substitutability as the proper heuristic.

Page 4: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 4Chapter 14 Inheritance

treats single inheritance, so we will not discuss this more general situation further. For

further information on multiple inheritance, see Lippman and Lajoie, C++ Primer, 3rd

edition or Stroustrup, The C++ Programming Language 3rd edition.

Terminology:

The roots of Object Oriented everything (Design, Analysis, Programming) are diverse.

The result is that terminology is equally diverse. From Simula 67 and Smalltalk come

object, class, superclass and subclass, methods and instance variables. From C++ we get

base class and derived class, member functions and member variables. From CLOS

(Common Lisp Object System) we get generic functions In C++ we have the template

facility.

The text follows Stroustrup’s usage in that it uses the terms base class and derived class,

member function and member variable, rather than superclass, subclass, method and

instance variable. Stroustrup remarks that he finds it counter intuitive to have a 'subclass'

that has more features than the 'superclass'.

Other terms that are used with derived class family relationships are described in the box,

“Parent and Child Classes” on page 590 of the text.

Access Specifiers in Inheritance

Suppose class derived has base class Base, as in the following code.

class Base {/* . . .*/};

class Derived : <access-specifier> Base

{ /* . . . */};

//where <access-specifier> is one of public, protected, private

Then the access that is accorded to member functions of class Derived depends on

the access-specifier selected. Unfortunately2, the access specifier for class inheritance

defaults to private3. My students sometimes forget the access specifier, with results that

2 “Unfortunately” is only an expression of my opinion. It is not to be confused with fact.

Page 5: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 5Chapter 14 Inheritance

are disappointing and confusing. Caution the students against omitting the access

specifier in inheritance.

It should be noted that while private and protected inheritance is possible, neither

is much used.

All Base Class Members Are Inherited

The private base class members are inaccessible to any function defined in any

derived class. For this reason, it is an error to attempt to access base class private

members. For purposes of writing code, private base class members might as well not

be inherited.

The foregoing apparently to the contrary, there is a very small number of exceptions to

the rule that every member of the base class is inherited, including the private

members. The exceptions to this are constructors, destructors, and certain operators

overloaded as members. We discuss this in a later section.

If you don’t believe that the private members are inherited, remember that all function

members of the base class are also inherited. These necessarily access the private

members of the base class, so these members must be present. You can confirm this.

Write a base class B with some private members (and other members), then derive a

class D with no members from the base class. You will find that the size of the derived

class object has the same size as the base class object.

If the derived class has members added of a size that would violate alignment that your

CPU requires, the implementation may allocate memory to “pad” accesses to achieve the

required alignment. For example, suppose you are using VC++ under Windows. If the

base class has only one int member, the base class object will have size 4. If the derived

class adds a char member and an int member in that order, the size of the derived class

3 The access specifier for struct defaults to public. The text treats a struct much as if structs had only the attributes they have in C. It does not use struct member functions, for example. We will not pursue the use of inheritance with structs.

Page 6: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 6Chapter 14 Inheritance

object will be 16. The derived class will inherit the two int variables from the base class

(8 bytes), add 1 for the char, and 3 for added padding, and 4 more for the int. As we

said, the padding is to align the memory access for the int member.

The Member Initializer List

Remind the students of the alternate initialization usage they saw first in Chapter 1, page

12 and 13.int count(0), limit(10);

double distance(5.723), zymurgyConstant(1.234);

This, for declaration of variables, is an exact equivalent to the following.

int count = 0, limit = 10;

double distance = 5.723, zymurgyConstant = 1.234;

When initializing data members in a class, it is possible to initialize inside the

constructor:

class A

{

public:

A();

// Other members

private:

int i;

int j;

};

A::A()

{

i = 0;

j = 1;

}

The preferred method is to use member initializer lists (also known as base class

initializer lists). Member initializer lists are only be used with the constructor definition,

not with the declaration within the class4.

4 If the definition of the constructor is placed in the class, inlined, then the initializer list is placed in the class, but this is not the usual practice in this book.

Page 7: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 7Chapter 14 Inheritance

class A

{

public:

A();

// Other members

private:

int i;

int j;

};

A::A() : i(0), j(0)

{// body deliberately empty

}

Stroustrup says that member initializers are required in situations where the semantics of

initialization differs from the semantics of assignment. That is, member initializers must

be used for members that are objects of classes not having default constructors, for

const members, and for reference members.

In the C++ FAQs, page 302 ff. Cline and Lomow say,

"Initialization lists are usually a performance issue, although there are cases when

the initialization lists impact correctness. . . . As a general rule, all member

objects and base classes should explicitly appear in the initialization list of a

constructor. In addition to being more efficient than to use the default

initialization followed by assignment, using the initialization list makes the code

clearer. There is no gain for built-in types, but there is no loss either, so

initialization lists should be used for symmetry.

Nonstatic const data members are declared in the class body with a const prefix

and … must be initialized in the constructor’s initialization list. …[A reference

data member] must be initialized in the initialization list of each constructor. "

Page 8: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 8Chapter 14 Inheritance

Constructors In Derived Classes

Suppose for purposes of this section that class D is derived with specifier public

from class B. (All our inheritance will be public, I will refrain from mentioning that

the derivation is public in what follows.)

An object of the derived class D has both pieces from class D and inherited pieces

from base class B. As such, a derived class object’s inherited pieces constitute a slice

that is a purely base class object. If you take these inherited pieces, and add the pieces

added in the inheritance, you get the whole derived class object. In this sense a derived

class object has more than one type, namely, its own type and its base class type.

The derived class constructor can only initialize the variables defined in the derived class

definition. Only base class constructor can initialize base class variables. Constructors are

not inherited, and there is no way to call a base class constructor from within the body of

a derived class constructor. How, then, can the base class pieces be initialized? If we do

not somehow call an appropriate constructor, then the base class default constructor will

be called.

The default constructor may not produce the results we want. If we want some other

constructor to initialize the base class parts of our derived class, we call the desired base

class constructor in the member initializer list, before the variables are initialized.

class B

{

public:

B();

// other members

private:

int b

};

B::B() : b()

{// implementation

}

class D : public B

{

public:

Page 9: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 9Chapter 14 Inheritance

D();

// other members

private:

int d;

};

D::D() : B(), d(0)

{// other implementation

}

The initialization is done by the implementation, not in the constructor declaration in the

class definition.

The protected Qualifier

We have seen that a member of a class can be public, or private. We have seen that

If the access qualifier is public, then any function can call a function in this

section, and any function can read or write a data member in this section.

If the access qualifier is private, then only functions declared in the class (or

friends of this class) can call a function in this section. Global functions and members

of nonfriend classes cannot call private functions read or write private data

members.

To these, C++ adds the keyword protected.

A member in a protected section can be accessed by member and friend functions

of this class and by members and friends of any derived class. The text puts it in

this succinct way: “Except for derived classes (and derived classes of derived

classes), a member variable that is marked protected is treated the same as if it were

private.

Members defined in the protected section of a class are accessible in member and

friend functions of the class, and in member and friend functions of classes derived

from the class. These members are inaccessible in any other function.

There are those who object to the use of friend functions on the theoretical ground that

it “breaks the encapsulation”. Stroustrup is blunt in his remarks regarding this attitude

toward friend functions, but he is not kind to the protected qualifier.

Page 10: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 10Chapter 14 Inheritance

Stroustrup remarks on the friend function concept on page 53 and following in The

Design and Evolution of C++, 1994, Addison Wesley.

“A friendship declaration was seen as a mechanism similar to that of one

protection domain granting read-write capability to another. It is an explicit and

specific part of a class declaration. Consequently, I have never been able to see

the recurring assertion that a friend declaration “violates encapsulation” as

anything but a combination ignorance and confusion with non-C++ terminology.”

Stroustrup is not so kind to the protected qualifier. In The Design and Evolution

of C++, page 301 and following, he says,

“Mark Linton was the main architect of Interviews [an X Windows toolkit]. … He

argued persuasively … that protected data was essential for the design of an

efficient and extensible … [X Windows] toolkit. …

“Five years later, Mark banned the use of protected data members in Interviews

because they had become a source of bugs. ‘… novice users poking where they

shouldn’t in ways they ought to have known better…’ They also seriously

complicate maintenance. …”

“In my experience there have always been alternatives to placing significant

amounts of information in a common base class for derived classes to use

directly. In fact, one of my concerns about protected is that it makes it too

easy to sue a common base the way one might sloppily have used global data.

“Fortunately, you don’t have to use protected data in C++; private is the

default for classes and is usually the better choice. Note that none of these

objections are significant for protected member functions. Use of protected

functions is a fine way of specifying operation for use in derived classes. …

“In retrospect, I think that protected is a case where ‘good arguments’ and

fashion overcame my better judgment … for accepting new features.”

My conclusion is that protected data members can be avoided so should not be used

but there is no problem with protected member functions or friend functions. I

Page 11: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 11Chapter 14 Inheritance

conclude further that accessor and mutator functions intended to serve derived classes can

(and perhaps should) be protected member functions. If declared inline, then with

simple accessor/mutator functions have the efficiency of public access and the protection

of the C++ model.

Redefinition of Member Functions

If in a derived class a function appears with the exact same signature5 as a function in the

base class, then we say that the base class function has been redefined. A base class

object will call the base class definition and a derived class object will call the derived

class definition. 6

Redefinition Versus Overloading

Redefined functions have definitions with the same signatures. This is function

redefinition even if the one of the definitions is in a base class and the other definition is

in a class derived from the base class. It is quite common to refer to function redefinition

as hiding the base member. Stroustrup says “A name in a derived class hides any object

or function of the same name in a base class.

Overloaded functions have the same name but different same signatures. This is

function name overloading even if one of the definitions is in a base class and the other is

in a derived class.

Here is some sample code:

class B

{

public:

void f(arglist1){ /*implementation 1*/}5 The signature includes all information that participates in overload resolution: the types of the parameters, and, if the function is a class member, the signature includes constant or volatile qualification and the class of which the function is a member. See the ANSI C++ Standard, Chapter 1, page 2, section 1.3.10.6 Which definition is called when the member function is called through a pointer or a reference depends on the type of the pointer or reference, not on the object to which the pointer points or to which the reference refers. Modifying this behavior is a subject we study in the next chapter.

Page 12: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 12Chapter 14 Inheritance

void g(arglist2){ /*implementation 2*/}

};

class D : public B

{

void f(arglist1){ /*implementation 3 */} //Redefined

void g(arglist3){ /*implementation 4*/} //overloaded

};

The function f(arglist1) has one definition in the base class B and is redefined in

derived class D. The functions with name g are overloaded because they have different

signatures in base class B and in derived class D.

Access to a Redefined Function

Consider the code in the last section. Suppose we have defined a derived class D object

and call the function f through the object d.

D d;

d.f(arglist1);

The function that is called is the one associated with class D. Now suppose we want to

call the function associated with the base class function. We can do that with the scope

resolution operator, qualifying the function using the base class name:

d.B::f(arglist1);

14.2 Programming with Inheritance

The text presents some subtle detail regarding inheritance, another example, and some

discussion of programming techniques.

Page 13: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 13Chapter 14 Inheritance

Assignment Operators and Copy Constructors in Derived Classes.

Remember that an object of a derived class has two types. It has the slice that is the base

class object and the added data members. If we define an assignment operator, we must

somehow assign the base class slice and then assign the parts added by inheritance. The

base class parts are assigned using the base class operator=. The text’s example

assumes that class Derived inherits from class Base.

Derived& Derived::operator=(const Derived& rhs)

{

this->Base::operator=(rhs);

//other code . . .

}

This code invokes the base class overloaded assignment operator on the base class slice

of the calling object. The “other code” part then finishes the job.

Similarly, the copy constructor in the derived class must copy the base class slice, then

copy the part added in the definition of Derived. The code looks like this.

Derived::Derived(const Derived& rhs):Base(rhs) //other needed

{ //initialization

// other code needed to finish the copy

}

As in the derived class assignment operator, the call to the base class copy constructor

copies the base class slice of the derived class object. Then the rest of the initializations

serve to copy the Derived class parts added in the derivation.

Destructors in Derived Classes

A caveat is needed. The situation described in the text works fine as long as no destructor

is ever called through a pointer or a reference. That situation requires a virtual base class

destructor, and is discussed in the next chapter.

Suppose B is a base class, D is derived from B and D2 is derived from D. Then when an

object of type D goes out of scope, the destructors for these three classes are called

Page 14: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 14Chapter 14 Inheritance

starting with ~D2, then ~D, then ~B. Said differently, the destructors are called in the

reverse order of the calls to constructors.

Protected and Private Inheritance; Multiple Inheritance

No remarks provided here.

3. Solutions to, and remarks on, selected Programming Projects

1. Administrator

Derive an Administrator class from SalariedEmployee in Display 14.4. It is

allowed (actually, it is recommended) to change the protection qualifier private to

protected in the base class.

Supply the following additional data and function members.

A variable of type string named title to contain the administrator's title.

Examples: Director, Vice President

A variable of type string named responsibility to hold the name of the area

of responsibility of the administrator. Example: Finance, Accounting, and Personnel.

A variable of type string named supervisor to hold the name of the

administrator's immediate supervisor.

A protected member variable of type double to hold the administrator's annual

salary.

A member function, setSupervisor, to change the name of the supervisor.

A member function to allow keyboard entry of the administrator's data.

A member function, print, that does screen display of administrator's data.

An overloaded member function PrintCheck() to print the administrator's data on

the check.

Page 15: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 15Chapter 14 Inheritance

Remarks: The function SalariedEmployee::PrintCheck() was tweaked. The

version of getline that comes with <string> in VC++6.0 has a bug. It seems to

lose something, so I used the cin member function getline instead of the version that

works with string objects directly.

//This is the HEADER FILE employee.h.

//This is the INTERFACE for the class Employee.

//This is primarily intended to be used as a base class to derive

//classes for different kinds of employees.

#ifndef EMPLOYEE_H

#define EMPLOYEE_H

#include <string>

using std::string;

namespace SavitchEmployees

{

class Employee

{

public:

Employee( );

Employee(string theName, string theSsn);

string getName( );

string getSsn( );

double getNetPay( );

void setName(string newName);

void setSsn(string newSsn);

void setNetPay(double newNetPay);

void printCheck( );

protected:

string name;

string ssn;

double netPay;

};

Page 16: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 16Chapter 14 Inheritance

}//SavitchEmployees

#endif //EMPLOYEE_H

//*****************************************************

//This is the IMPLEMENTATION FILE: employee.cpp

//This is the IMPLEMENTATION for the class Employee.

//The interface for the class Employee is in the header file employee.h.

#include <string>

#include <cstdlib>

#include <iostream>

#include "employee.h"

using std::string;

using std::cout;

namespace SavitchEmployees

{

Employee::Employee( ) : name("No name yet"),

ssn("No number yet"),

netPay(0)

{

//deliberately empty

}

0

Employee::Employee(string theName, string theNumber)

: name(theName),

ssn(theNumber),

netPay(0)

{

//deliberately empty

}

string Employee::getName( )

{

return name;

}

string Employee::getSsn( )

Page 17: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 17Chapter 14 Inheritance

{

return ssn;

}

double Employee::getNetPay( )

{

return netPay;

}

void Employee::setName(string newName)

{

name = newName;

}

void Employee::setSsn(string newSsn)

{

ssn = newSsn;

}

void Employee::setNetPay (double newNetPay)

{

netPay = newNetPay;

}

void Employee::printCheck( )

{

cout << "\nERROR: printCheck FUNCTION CALLED FOR AN \n"

<< "UNDIFFERENTIATED EMPLOYEE. Aborting the program.\n"

<< "Check with the author of the program about this bug.\n";

exit(1);

}

}//SavitchEmployees

//*********************************************

//This is the HEADER FILE salariedemployee.h.

//This is the INTERFACE for the class SalariedEmployee.

#ifndef SALARIEDEMPLOYEE_H

Page 18: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 18Chapter 14 Inheritance

#define SALARIEDEMPLOYEE_H

#include <string>

#include "employee.h"

using std::string;

namespace SavitchEmployees

{

class SalariedEmployee : public Employee

{

public:

SalariedEmployee( );

SalariedEmployee (string theName, string theSsn,

double theWeeklySalary);

double getSalary();

void setSalary(double newSalary);

void printCheck( );

private:

double salary; //weekly

};

}//SavitchEmployees

#endif //SALARIEDEMPLOYEE_H

//******************************************************

//This is the IMPLEMENTATION FILE: salariedemployee.cpp

//This is the IMPLEMENTATION for the class SalariedEmployee.

//The interface for the class SalariedEmployee is in

//the header file salariedemployee.h.

#include <iostream>

#include <string>

#include "salariedemployee.h"

using std::string;

Page 19: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 19Chapter 14 Inheritance

using std::cout;

using std::endl;

namespace SavitchEmployees

{

SalariedEmployee::SalariedEmployee( ):Employee( ), salary(0)

{

//deliberately empty

}

SalariedEmployee::SalariedEmployee(string newName,

string newNumber,

double newWeeklyPay)

: Employee(newName, newNumber),

salary(newWeeklyPay)

{

//deliberately empty

}

double SalariedEmployee::getSalary( )

{

return salary;

}

void SalariedEmployee::setSalary(double newSalary)

{

salary = newSalary;

}

void SalariedEmployee::printCheck( )

{

setNetPay(salary);

cout << "\n_______________________________________________\n";

cout << "Pay to the order of " << getName( ) << endl;

cout << "The sum of " << getNetPay( ) << " Dollars\n";

cout << "_________________________________________________\n";

cout << "Check Stub NOT NEGOTIABLE \n";

cout << "Employee Number: " << getSsn( ) << endl;

Page 20: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 20Chapter 14 Inheritance

cout << "Salaried Employee. Regular Pay: "

<< salary << endl;

cout << "_________________________________________________\n";

}

}//SavitchEmployees

//*********************************************************

//file: ch14p1.h

//This is the INTERFACE for class Administrator that inherits

//from class Employee and class SalariedEmployee

//Chapter 14 Programming Problem #1

//Title: Derive class Administrator

//

//Write a program using the class SalariedEmployee from

//Display 14.4. Define class Administrator that is derived

//publicly from class SalariedEmployee.

//Explain why there is a need to change private to protected.

//Answer: To allow the member functions inherited class member

//to see these data members.

//Additional Members required are:

//protected:

//string title; // administrator's title (CEO, Director etc.)

//string responsibility; // production, accounting, personnel

//string supervisor; //name of immediate supervisor

//double annualSalary;

//public:

//function to change name of immediate supervisor

//void changeSupervisor(string newSuper);

//function for reading all of a new administrator's data from

//the keyboard. Note that the data inherited from Employee will

//already be fetched automatically by default constructors.

Page 21: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 21Chapter 14 Inheritance

//void getAdminData();

// function to output administrator's data to the screen

// void print();

//prints a check with appropriate notations on the check

//void printCheck()

#ifndef PROTECT_ADMINISTRATOR_H

#define PROTECT_ADMINISTRATOR_H

#include "salariedemployee.h" // from Display 14.4

namespace SavitchEmployees

{

class Administrator : public SalariedEmployee

{

public:

//Constructors:

Administrator();

Administrator(string aName,

string anSSn,

string aTitle,

string aResponsibilty,

string aSupervisor,

double aSalary

);

// Administrator(string aTitle, string aResponsibilty,

// string aSupervisor, double aSalary);

// change name of immediate supervisor

Page 22: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 22Chapter 14 Inheritance

void changeSupervisor(string newSuper);

// Reads a new administrator's data from the keyboard.

void getAdminData();

//outputs administrator's data to the screen

void print();

// prints a check with appropriate notations on the check

void printCheck();

void giveRaise(double amount);

protected:

string title; // administrator's title

// (CEO, Director, Vice President)

string responsibility; // such as production,

// accounting, personnel

string supervisor; // name of immediate supervisor

double annualSalary; // if not added in the self test exercise

};

} // end this segment of namespace SavitchEmployees

// #endif

//*****************************************************

//File: ch14p1.cpp

//Chapter 14 Programming Project 1

//Implementation for the Administrator derived class

#include "employee.h" //display 14.1

#include "ch14p1.h"

#include <iostream>

namespace SavitchEmployees

{

void Administrator::

giveRaise(double amount)

Page 23: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 23Chapter 14 Inheritance

{

annualSalary += amount;

}

Administrator::

Administrator() : SalariedEmployee()

{

getAdminData();

}

Administrator::

Administrator(string aName,

string anSSn,

string aTitle,

string aResponsibilty,

string aSupervisor,

double aSalary

)

: SalariedEmployee(aName, anSSn, 0.0),

title(aTitle),

responsibility(aResponsibilty),

supervisor( aSupervisor), annualSalary(aSalary)

{

//deliberately empty

}

// change name of immediate supervisor

void Administrator::changeSupervisor(string newSuper)

{

supervisor = newSuper;

}

// Reading all of a new administrator's data from the keyboard.

void Administrator::getAdminData()

{

using namespace std;

char n[80];

Page 24: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 24Chapter 14 Inheritance

cout << "\nAdministrative Employee data is being entered:\n\n";

cout << "Enter the Administrator's name: \n";

// getline(cin, name, '\n'); //there is a bug in VC++ version of

getline.

//getline(cin, name);

cin.getline(n, 80); //But this version works.

name = n;

cout << "Enter social security number: \n";

// getline(cin. ssn);

cin.getline(n, 80);

ssn = n;

cout << "Enter a title, followed by return:\n";

//getline(cin, title);

cin.getline(n, 80);

title = n;

cout << "\nEnter an area of responsibility followed by return:\n";

//getline(cin, responsibility);

cin.getline(n, 80);

responsibility = n;

cout << "\nEnter the name of employee's supervisor, followed "

<< "by return:\n";

//getline(cin, supervisor);

cin.getline(n, 80);

supervisor = n;

cout << "\nEnter salary followed by return:\n";

cin >> annualSalary;

}

Page 25: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 25Chapter 14 Inheritance

//outputs administrator's data to the screen

void Administrator::print()

{

using namespace std;

cout << "\n\nprinting Administrator data \n";

cout << "Name: " << name << endl;

cout << "Annual Salary: $" << annualSalary << endl;

cout << "Social Security Number: " << ssn << endl;

cout << "Title: ";

cout << title << endl;

cout << "Responsibility:";

cout << responsibility << endl;

cout << "supervisor: ";

cout << supervisor << endl;

cout.setf(ios::showpoint);

cout.setf(ios::fixed);

cout.precision(2);

cout << "Annual Salary: "

<< annualSalary << endl << endl;

}

// prints a check with appropriate notations on the check

void Administrator::printCheck()

{

using namespace std;

double monthlyPay = annualSalary/12;

cout << "\n________________________________________________\n\n";

cout << "Pay to the order of " << name << endl << endl;

cout.setf(ios::showpoint);

cout.setf(ios::fixed);

cout.precision(2);

cout << "The sum of $" << monthlyPay << " Dollars\n";

cout << "\n_________________________________________________\n\n";

cout << "Check Stub NOT NEGOTIABLE \n";

Page 26: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 26Chapter 14 Inheritance

cout << "Employee Number: " << ssn << endl << endl;

cout << "Administrative Employee. \n";

cout << "_________________________________________________\n";

}

}// end this segment namespace SavitchEmployees

No sample run is provided.

2. Additional Classes for Employee Hierarchy

Add temporary, administrative, permanent classification to hierarchy from Display 14.1,

14.3, and 14.4. Implement and test, test all member functions. A user interface with menu

would be a nice touch for testing.

Suggestions:

Once the details of #1 have been worked out, this problem seems (to me, at leas) to be

fairly straightforward. Nevertheless, I'm making some suggestions here, because my

students have difficulty in deciding which class to derive from a collection of already

defined class, and they have difficulty deciding what features to add in a derived class.

Derive class TemporaryEmployee from HourlyEmployee. Add string data

members hireDate and employmentTerm. Add access members and appropriate

constructors.

Derive the class PermanentEmployee from class SalariedEmployee. Add a

string data member hireDate data member and member function string

getHireDate();. Add constructors that reflect these changes.

Derive class AdministrativeEmployee from PermenantEmployee, adding a

string title data member and add a member function string getTitle();.

Add constructors that reflect these changes.

Page 27: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 27Chapter 14 Inheritance

Consider adding a string hireDate data member and string

setHireDate(); member function to the class hierarchy where not present.

Consider adding a class ContractEmployee. These employees are not really

temporary, as they are employed for the life of a contract (or less). They are likely to be

hourly employees and receive no fringe benefits, but the hourly pay rate is likely to be

quite high.

Consider adding a class Professional. A lawyer, physician, nurse practitioner or

physician assistant, or nurse might be a job that such an employee might do.

3. Doctor

Derive class Doctor from SalariedEmployee Display 14.4. A Doctor record has

the specialty (Pediatrician, Obstetrician, Surgeon, General Practitioner. – use string ),

office visit fee (double). Use reasonable constructors and accessor. Overload the

assignment operator, and provide a copy constructor. Write a driver to test everything.

This is also very much like #1 and #2. The difference is that there is only one class with a

specialty variable instead of providing separate classes. Here the member function

collection is the same for all specialties, whereas in #1 and #2, there are differences in the

interface for different employee types., which justified the more extensive use of

inheritance.

4. Person, Vehicle, Truck

Implementation of the class definition for Person is given. The student is to implement

the members, write the classes Vehicle and Truck, deriving class Truck from class

Vehicle,

Class Vehicle has a string variable containing the manufacturer's name, an int

variable containing the number of cylinders, and a Person variable containing the name

of the owner.

Page 28: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 28Chapter 14 Inheritance

Class Truck is derived from Vehicle and has a double variable that contains load

capacity in tons, and an int variable containing the maximum towing capacity in

pounds.

Class Person is provided in the problem statement, and is repeated in the code.

Provide a reasonable complement of constructors, accessor, and overloaded assignment

operators. Write a driver that tests all methods.

NOTE: The default copy constructor and operator assignment do exactly what is needed.

I tested my code without writing these. The code works correctly with the default copy

constructor and operator assignment. Nevertheless, the exercise says to code these, so I

coded them. I (re)learned a bit doing this. I urge that the student be required to code these

per the problem statement.

//File: ch14p3.cpp

//Monolithic program

#include <iostream>

#include <string>

using namespace std;

class Person

{

public:

Person();

Person(const Person&);

Person& operator=(const Person& rhs);

Person(string);

Person::Person(const char* aName);

string getName() const;

friend istream& operator>> (istream& is, Person& p );

friend ostream& operator<< (ostream& os, const Person& p);

Page 29: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 29Chapter 14 Inheritance

private:

string name;

};

class Vehicle

{

public:

Vehicle();

Vehicle(string mfgr, int noCyl, const Person& owner);

Vehicle(const Vehicle& rhs);

Vehicle& operator=(const Vehicle& rhs);

string getMfgrName();

int getNumberCyl();

Person getOwner();

private:

string mfgrName;

int numberCyl;

Person vehicleOwner;

};

class Truck : public Vehicle

{

public:

Truck();

Truck (double maxLoad, int maxTow,

string mfgr, int noCyl,

const Person& owner);

Truck(const Truck& rhs);

Truck& operator=(const Truck& rhs);

Page 30: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 30Chapter 14 Inheritance

double getLoadCapacity();

int getTowingCapacity();

private:

double loadCapacity; // tons

int towingCapacity; // pounds

};

//*******************************************

//Vehicle implementation

Vehicle::Vehicle() : mfgrName("No Mfgr Yet"),

numberCyl(0),

vehicleOwner("No owner yet")

{//deliberately empty

}

Vehicle::Vehicle(string mfgr, int noCyl, const Person& owner)

: mfgrName(mfgr),

numberCyl(noCyl),

vehicleOwner(owner)

{//deliberately empty

}

Vehicle::Vehicle(const Vehicle& rhs)

: mfgrName(rhs.mfgrName),

numberCyl(rhs.numberCyl),

vehicleOwner(rhs.vehicleOwner)

{

}

Vehicle& Vehicle::operator=(const Vehicle& rhs)

{

this->mfgrName = rhs.mfgrName;

this->numberCyl = rhs.numberCyl;

this->vehicleOwner = rhs.vehicleOwner;

return *this;

Page 31: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 31Chapter 14 Inheritance

}

string Vehicle::getMfgrName()

{

return mfgrName;

}

int Vehicle::getNumberCyl()

{

return numberCyl;

}

Person Vehicle::getOwner()

{

return vehicleOwner;

}

//**************************

// Truck Implementation

Truck::Truck() : loadCapacity(0), towingCapacity(0)

{

}

Truck::Truck(double maxLoad,

int maxTow,

string mfgr,

int noCyl,

const Person& owner)

: Vehicle(mfgr, noCyl, owner),

loadCapacity(maxLoad),

towingCapacity(maxTow)

{

}

Truck::Truck(const Truck& rhs)

Page 32: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 32Chapter 14 Inheritance

: Vehicle(rhs),

loadCapacity(rhs.loadCapacity),

towingCapacity(rhs.towingCapacity)

{

}

Truck& Truck::operator=(const Truck& rhs)

{

Vehicle::operator=(rhs);

loadCapacity = rhs.loadCapacity;

towingCapacity = rhs.towingCapacity;

return *this;

}

double Truck::getLoadCapacity()

{

return loadCapacity;

}

int Truck::getTowingCapacity()

{

return towingCapacity;

}

//Person Implemenation

Person::Person() : name("")

{

}

Person::Person(string aName) : name(aName)

{

}

Person::Person(const char* aName) : name(aName)

{

}

Page 33: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 33Chapter 14 Inheritance

Person::Person(const Person& theName):name(theName.name)

{

}

Person& Person::operator=(const Person& rhs)

{

this->name = rhs.name; //string assignment is well behaved

return *this;

}

string Person::getName() const

{

return name;

}

istream& operator>>(istream& is, Person& p )

{

is >> p.name;

return is;

}

ostream& operator<< (ostream& os, const Person& p)

{

os << p.name;

return os;

}

//********************

//Testing Application

int main()

{

Vehicle v1("Ford", 4, "James Carter") ;

Vehicle v2;

Vehicle v3(v1);

v2 = v1;

cout << "\nCar v1 (constructed) Data:\n";

Page 34: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 34Chapter 14 Inheritance

cout << v1.getMfgrName() << endl;

cout << v1.getNumberCyl() << endl;

cout << v1.getOwner() << endl;

cout << "\nCar v2 (assigned) Data:\n";

cout << v2.getMfgrName() << endl;

cout << v2.getNumberCyl() << endl;

cout << v2.getOwner() << endl;

cout << "\nCar v3 (copy constructed) Data:\n";

cout << v3.getMfgrName() << endl;

cout << v3.getNumberCyl() << endl;

cout << v3.getOwner() << endl;

Truck t1(80.0, 20000, "Mac", 8, "John Q. Driver");

// 80 tons gross vehicle weight, 20,000 lbs tow capacity

Truck t3(t1), t2;

t2 = t1;

cout << "\nTruck T1 (constructed) data:\n";

cout << t1.getMfgrName() << endl;

cout << t1.getNumberCyl() << endl;

cout << t1.getOwner() << endl;

cout << t1.getLoadCapacity() << endl;

cout << t1.getTowingCapacity() << endl;

cout << "\nTruck T2 (assigned) data:\n";

cout << t2.getMfgrName() << endl;

cout << t2.getNumberCyl() << endl;

cout << t2.getOwner() << endl;

cout << t2.getLoadCapacity() << endl;

cout << t2.getTowingCapacity() << endl;

Page 35: Chapter 14 - Inheritancewps.aw.com/wps/media/objects/80/82902/SavitchIMCh14.doc · Web viewChapter 14 Inheritance 0. Introduction Object-Oriented Programming (OOP) is a powerful programming

Instructor’s Resource Manual for Savitch Absolute C++ 05/08/23 Page 35Chapter 14 Inheritance

cout << "\nTruck T3 (copy constructed) data:\n";

cout << t3.getMfgrName() << endl;

cout << t3.getNumberCyl() << endl;

cout << t3.getOwner() << endl;

cout << t3.getLoadCapacity() << endl;

cout << t3.getTowingCapacity() << endl;

return 0;

}

// end testing application

5. Patient and Billing

This extends #4. Write classes Patient and Billing. Patient is derived from class

Person. Class Patient object has the patient's name (through inheritance from class

Person, and adds primary physician of type Doctor (Project #3). Class Billing

contains a Patient object as member to contain the patient's name, a Doctor object,

and an amount due of type double.

Provide a reasonable complement of constructors and accessor, overloaded assignment,

and a copy constructor.7

This is only qualitatively different from other problems in this section.

7 The default copy constructor and operator assignment do exactly what we need. In the real world, these should not be written. I recommend pointing out to the student that apart from the valuable learning experience, these should not be written in where the defaults work correctly.