0% found this document useful (0 votes)
36 views92 pages

Inheritance - Chapter 11

This chapter discusses inheritance in C++. Inheritance allows a derived class to inherit attributes and behaviors from a base class to promote code reuse. There are three types of inheritance: public, private, and protected. Public inheritance allows a derived class to access all non-private members of the base class. Private inheritance is an alternative to composition. Protected inheritance is rarely used.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views92 pages

Inheritance - Chapter 11

This chapter discusses inheritance in C++. Inheritance allows a derived class to inherit attributes and behaviors from a base class to promote code reuse. There are three types of inheritance: public, private, and protected. Public inheritance allows a derived class to access all non-private members of the base class. Private inheritance is an alternative to composition. Protected inheritance is rarely used.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 92

Advanced C++

Chapter 11: Inheritance


(Chapter 12 in the Old Book)

Kristina Shroyer

1
Chapter Objectives
In this chapter you’ll learn:
n To create classes by inheriting from existing classes.
n How inheritance promotes software reuse.
n The notions of base classes and derived classes and the
relationships between them.
n The protected member access specifier.
n The use of constructors and destructors in inheritance
hierarchies.
n The differences between public, protected and
private inheritance.
n The use of inheritance to customize existing software.

2
Inheritance – The Is-A Relation
l Another important relationship between classes in a program is the
Is-A relation which is the relationship of inheritance

l Many objects in the real world are specialized versions of more


general objects
n An “insect” is a specialized version of the type “creature”
n A “grasshopper” and a “bumble bee” are specialized versions of the
more general type “insect”
♦ Because grasshoppers and bumble bees are insects they both have the
general characteristics of an insect
♦ In addition, they have special characteristics of their own
l Grasshoppers have jumping ability and bees have the ability to sting

l These type of real world relationships between objects also apply to


classes in object oriented programming
n A “Student” class could be a more specialized version of a “Person”
class

3
Inheritance – The Is-A Relation
l When one object is a specialized version of another
object there is an Is-A relationship between them
n A poodle is a dog
n A car is a vehicle
n A rectangle is a shape

l When an Is-A relationship exists between class data


types it means
n the specialized data type has all of the characteristics of the
general data type plus additional characteristics that make it
special

l In object oriented programming, inheritance is used


to create an Is-A relationship between classes

4
Inheritance – The Is-A Relation
l Why is Inheritance useful?
n Software reusability
♦ Saves time during program development
♦ Encourages the reuse of proven, debugged, high quality software
l Increases the likelihood that a system will be implemented effectively
n Create new class from existing class
♦ Absorb existing class’s data and behaviors
♦ Enhance and/or extend with new capabilities

l So with inheritance instead of writing completely new data members (member


variables) and member functions for a class you can designate that the new class
should inherit members of an existing class
n The Derived class inherits from base class
♦ So the existing general class is the base class and the more specialized class is the derived class
l (in Java the base class is called the superclass and the derived class is called the subclass)
n Derived class
♦ More specialized group of objects
♦ Behaviors inherited from base class
l Can customize the inherited behaviors (specialization)
♦ Additional behaviors
l The derived class usually contains additional behaviors besides the inherited ones adding to the
"specialization"

5
Inheritance – The Is-A Relation
l This is a UML lite visualization of inheritance

l Inheritance involves a base class and a derived class


n The base class is the general class
n The derived class is the specialized class
n You can think of the base class as the parent and the derived
class as the child

INSECT Base Class (parent)


-General Class
members

BEE Derived Class (Child)


-Specialized Class
members 6
Inheritance – The Is-A Relation
l Inheritance and the base and derived class properties:
n The derived class inherits the data members (member
variables/attributes) and member functions of the base class
n New data members (member variables) and member
functions may be added to the derived class to extend it to
make it more specialized than the base class
♦ Functions inherited from the base class may also be customized
(enhanced) adding to the specialization

INSECT Base Class (parent or superclass)


-General Class
members

BEE Derived Class (Child or subclass)


-Specialized Class
members 7
Inheritance – The Is-A Relation
l You can think of the classes involved in inheritance as being in a tree
or hierarchy which illustrates their relationships to each other
n Direct base class
♦ Inherited explicitly (one level up hierarchy)
l Vehicle -> Car
n Indirect base class
♦ Inherited two or more levels up hierarchy
l UniversityCommunityMember->Employee->Faculty->Administrator
n Single inheritance
♦ Inherits from one base class

n Multiple inheritance
♦ Inherits from multiple base classes
l Base classes possibly unrelated
♦ This chapter focuses on single inheritance
l Multiple inheritance is one of those "special cases" (like globals) that is
general discouraged so I like to stay away from that in the main discussion –
if time at the end of the class we can look into it more

8
Inheritance Hierarchy Example
l Inheritance Hierarch for University
Community Members

9
Types of Inheritance - Intro
l Three types of inheritance
n public

♦ Every object (instance) of derived class is also an object (instance) of


base class
l Base-class objects are not objects (instances) of derived classes
l Example: All cars are vehicles, but not all vehicles are cars
♦ The derived class can access non-private members of base
class
♦ To access private base-class members
l Derived class must use inherited non-private member functions
l This means derived classes can NOT directly access
private base class members
n private
♦ Alternative to composition – better to use composition
n protected
♦ Rarely used

10
Inheritance – Introduction cont.
l Abstraction
n Focuses on commonalities among objects in system
n So with abstraction and object oriented programming we
focus on the relationships between objects
♦ We focus on the commonalities rather than the special cases

l “is-a” relationship vs. “has-a” relationship


n “is-a”
♦ Inheritance
♦ Derived class object can be treated as base class object
♦ Example: Car is a vehicle
l Vehicle properties/behaviors also apply to a car
n “has-a”
♦ Composition
♦ Object contains one or more objects of other classes as members
♦ Example: Car has a steering wheel

11
Inheritance – Introduction cont.
l A derived class can access the non-private members
of its base class
n Any base class members that should not be accessible to the
member class functions of the derived class should be made
private

l Member functions of a derived class can NOT directly


access private members of the base class.
n If a derived class could access its base class’s private
members:
♦ Classes that inherit from that derived class could access that data as
well
l This would allow access to what should be private data, and
the benefits of information hiding would be lost.
n A derived class can change the states of private base class
members but ONLY through non-private member functions
provided by the base class and inherited into the base class

12
Base Classes and Derived Classes
l Base classes and derived classes
l Object of one class “is an” object of another class
n Example: Rectangle is a quadrilateral
♦ Class Rectangle inherits from class Quadrilateral
l Quadrilateral is the base class
l Rectangle is the derived class

l Because every derived class "is an" object of its base


class and one base class can have many derived
classes this means:
n Base class typically represents larger set of objects than
derived classes
♦ Example:
l Base class: Vehicle
§ Includes cars, trucks, boats, bicycles, etc.
l Derived class: Car
§ Smaller, more-specific subset of vehicles

13
Inheritance Examples

Base class Derived classes

Student GraduateStudent, UndergraduateStudent


Shape Circle, Triangle, Rectangle, Sphere, Cube
Loan CarLoan, HomeImprovementLoan, MortgageLoan
Employee Faculty, Staff
Account CheckingAccount, SavingsAccount

14
Base Classes and Derived Classes
l Inheritance hierarchy
n Inheritance relationships form a tree-like hierarchy structure
n Each class becomes
♦ Base class
l Supplies data/behaviors to other classes
AND/OR
♦ Derived class
l Inherits data/behaviors from other classes

l Although classes can exist independently, once


they become part of an inheritance relationship
they become affiliated with other classes

l UML with inheritance will resemble the hierarchy

15
Inheritance Hierarchy Examples
l Each arrow represents an is a relationship.
n Starting from the bottom of the diagram you can follow the arrows and apply the is a
relationship to the topmost base class
n So an AdministratorTeacher is a Administrator, is a Faculty member, is an Employee and
is a Community member follow the path
n An Administrator Teacher is also a Teacher

Fig. 12.2 | Inheritance hierarchy for university CommunityMembers.


16
Inheritance Hierarchy Examples
l Each arrow represents an is a relationship.
n This hierarchy could be expanded

Fig. 12.3 | Inheritance hierarchy for Shapes.

17
Specifying public Inheritance
l class Student : public Person

Derived Class Base Class

l To specify the class Student is derived from


the class Person, the Student class definition
should begin like shown above
l This is an example of public inheritance
n public inheritance is the most commonly used form of
inheritance

18
public Inheritance
l public inheritance
n Specify with:
class TwoDimensionalShape : public Shape
♦ Class TwoDimensionalShape inherits from class Shape

l With ALL forms of inheritance (public, private and protected):


n private members of the base class are:
♦ NOT accessible directly from that class's derived class
♦ BUT these private base class members are still inherited (they are still
considered parts of the derived class)
l These private base class members can be:
§ Manipulated through inherited public member functions

l With public inheritance:


n All other base class members (other than private) retain their original member
access when they become members of the derived class
♦ So public and protected members of the base class become public and
protected members of the derived class
♦ Using these inherited base class members the derived class can manipulate
private members of the base class

l friend functions
n ARE NOT INHERITED

19
Protected Members
l Up until now we have used two access specifications when we
defined classes: private and public
n C++ provides a third class access specification: protected

• Protected members of a base class are similar to private


members except they may be accessed by:
• member functions and friends of a derived class.

l Protected members of a base class may be accessed by:


n Base class members (so member functions of the base class)
n Base class friends
n Derived class members (member functions of a derived class)
n Derived class friends

l Protected members are inaccessible to all other code not in


the base class or derived class

20
Protected Members/Redefined base class
member functions
l Derived-class members
n Refer to public and protected members of base class by
♦ Simply using the public or protected member names directly or by going
through member functions (going through member functions is often better
design as we will discuss so keep that in mind)

l Derived classes can customize or redefine base class member


functions, in this case:
n When base class member functions are redefined in the derived class,
derived object instance calls to that function will call the derived class
redefined version of the function
n Redefined base class member functions can be accessed directly though by
the derived class – they can be only accessed from the derived class by:
♦ preceding the base class member name with the base-class name and
binary scope resolution operator (::)
l This another correct use of the scope resolution operator (besides static) – not
like a lot of what I've seen in some people's CSIS 135 programs (I've seen the
incorrect use in people's programs when they are just trying to get he program
to "work" instead of using object oriented principles)
n We'll discuss redefining members of the base class and using
protected data (and protected is generally inferior design) using some
examples

21
Examples Base Class & Derived Class
l We're going to look at a series of examples involving the
following two classes:
♦ CommissionEmployee
l First name, last name, SSN, commission rate, gross sale amount
l these employees are paid solely on commissions
♦ BasePlusCommissionEmployee
l First name, last name, SSN, commission rate, gross sale amount
l And also: base salary
l these employees get a base salary plus commissions

l We're first going to look at these classes designed as


two separate unrelated classes

l We'll then look at them designed with inheritance


n Then we'll vary all of these to illustrate some key inheritance
concepts

22
CommissionEmployee class
l Example 1
n So first we'll create this class on it's own with no inheritance
involved

l Note validation was not done for the various


private string members as they are manipulated
through the constructor and set functions
n This was just for convenience purposes and in a real
situation would be validated

l This class works much like what we are used to


and have been doing with our classes so far
n A client test program was also created

23
1 // Fig. 12.4: CommissionEmployee.h
2 // CommissionEmployee class definition represents a commission employee.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6 #include <string> // C++ standard string class Example 1
7 using std::string;
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
Class CommissionEmployee constructor
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate (percentage)
28 double getCommissionRate() const; // return commission rate

24
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 private:
33 string firstName;
34 string lastName; Declare private Example 1
35 string socialSecurityNumber; data members
36 double grossSales; // gross weekly sales
Commission
37 double commissionRate; // commission percentage
Employee.h
38 }; // end class CommissionEmployee
39
(2 of 2)
40 #endif

25
1 // Fig. 12.5: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
11 double sales, double rate )
12 {
13 firstName = first; // should validate Initialize data members
14 lastName = last; // should validate
15 socialSecurityNumber = ssn; // should validate
16 setGrossSales( sales ); // validate and store gross sales Example 1
17 setCommissionRate( rate ); // validate and store commission rate
18 } // end CommissionEmployee constructor Commission
19 Employee.cpp
20 // set first name
21 void CommissionEmployee::setFirstName( const string &first ) (1 of 4)
22 {
23 firstName = first; // should validate
24 } // end function setFirstName
25
26 // return first name
27 string CommissionEmployee::getFirstName() const
28 {
29 return firstName;
30 } // end function getFirstName

26
31
32 // set last name
33 void CommissionEmployee::setLastName( const string &last )
34 {
35 lastName = last; // should validate
36 } // end function setLastName
37
38 // return last name
39 string CommissionEmployee::getLastName() const Example 1
40 {
41 return lastName; Commission
42 } // end function getLastName Employee.cpp
43
44 // set social security number (2 of 4)
45 void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
46 {
47 socialSecurityNumber = ssn; // should validate
48 } // end function setSocialSecurityNumber
49
50 // return social security number
51 string CommissionEmployee::getSocialSecurityNumber() const
52 {
53 return socialSecurityNumber;
Function setGrossSales
54 } // end function getSocialSecurityNumber
55 validates gross sales amount
56 // set gross sales amount
57 void CommissionEmployee::setGrossSales( double sales )
58 {
59 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
60 } // end function setGrossSales

27
61
62 // return gross sales amount
63 double CommissionEmployee::getGrossSales() const
64 {
65 return grossSales;
66 } // end function getGrossSales
Function setCommissionRate
67 validates commission rate
68 // set commission rate
69 void CommissionEmployee::setCommissionRate( double rate )
70 { Example 1
71 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
Commission
72 } // end function setCommissionRate Employee.cpp
73
74 // return commission rate (3 of 4)
75 double CommissionEmployee::getCommissionRate() const
76 {
77 return commissionRate;
78 } // end function getCommissionRate

28
79
80 // calculate earnings
81 double CommissionEmployee::earnings() const
82 {
Function earnings
83 return commissionRate * grossSales; calculates earnings
84 } // end function earnings
85
86 // print CommissionEmployee object
87 void CommissionEmployee::print() const
88 {
Function print displays
89 cout << "commission employee: " << firstName << ' ' << CommissionEmployee object
lastName
90 << "\nsocial security number: " << socialSecurityNumber
91 << "\ngross sales: " << grossSales Example 1
92 << "\ncommission rate: " << commissionRate;
Commission
93 } // end function print
Employee.cpp

(4 of 4)

29
1 // Fig. 12.6: fig12_06.cpp
2 // Testing class CommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7 Example 1
8 #include <iomanip>
9 using std::setprecision; testCommEmp.cpp
10
11 #include "CommissionEmployee.h" // CommissionEmployee class definition (1 of 2)
12
13 int main()
14 { Instantiate CommissionEmployee object
15 // instantiate a CommissionEmployee object
16 CommissionEmployee employee(
17 "Sue", "Jones", "222-22-2222", 10000, .06 );
18
19 // set floating-point output formatting
20 cout << fixed << setprecision( 2 );
21
22 // get commission employee data
23 cout << "Employee information obtained by get functions: \n"
24 << "\nFirst name is " << employee.getFirstName()
25 << "\nLast name is " << employee.getLastName() Use CommissionEmployee’s
26 << "\nSocial security number is " get functions to retrieve the
27 << employee.getSocialSecurityNumber()
object’s instance variable values
28 << "\nGross sales is " << employee.getGrossSales()
29 << "\nCommission rate is " << employee.getCommissionRate() << endl;

30
30
31 employee.setGrossSales( 8000 ); // set gross sales
32 employee.setCommissionRate( .1 ); // set commission rate
33
34
Use CommissionEmployee’s set functions
cout << "\nUpdated employee information output by print function: \n"
35 << endl; to change the object’s instance variable values
36 employee.print(); // display the new employee information
37 Call object’s print function to
38 // display the employee's earnings display employee information
39 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
40
41 return 0; Call object’s earnings
42 } // end main
function to calculate earnings
Employee information obtained by get functions:

First name is Sue


Example 1
Last name is Jones
Social security number is 222-22-2222 testCommEmp.cpp
Gross sales is 10000.00
Commission rate is 0.06 (2 of 2)
Updated employee information output by print function:

commission employee: Sue Jones


social security number: 222-22-2222
gross sales: 8000.00
commission rate: 0.10

Employee's earnings: $800.00

31
BaseCommissionEmployee class
l Example 2
n Now we're going to create a completely independent
BaseCommissionEmployee class to show why
inheritance is better for certain examples like this
n As we look at it note all the similarities between this class
and the CommissionEmployee class

l Class BasePlusCommissionEmployee
n Much of the code is similar to CommissionEmployee
♦ private data members
♦ public methods
♦ constructor
n Additions
♦ private data member baseSalary
♦ Methods setBaseSalary and getBaseSalary

32
1 // Fig. 12.7: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class definition represents an employee
3 // that receives a base salary in addition to commission.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7
8
#include <string> // C++ standard string class
using std::string;
Example 2
9 BasePlus
10 class BasePlusCommissionEmployee Commission
11 { Employee.h
12 public:
13 BasePlusCommissionEmployee( const string &, const string &, (1 of 2)
14 const string &, double = 0.0, double = 0.0, double = 0.0 );
15
16 void setFirstName( const string & ); // set first name Constructor takes one more argument,
17 string getFirstName() const; // return first name
which specifies the base salary
18
19 void setLastName( const string & ); // set last name
20 string getLastName() const; // return last name
21
22 void setSocialSecurityNumber( const string & ); // set SSN
23 string getSocialSecurityNumber() const; // return SSN
24
25 void setGrossSales( double ); // set gross sales amount
26 double getGrossSales() const; // return gross sales amount
27
28 void setCommissionRate( double ); // set commission rate
29 double getCommissionRate() const; // return commission rate

33
30
31 void setBaseSalary( double ); // set base salary Define get and set functions for
32 double getBaseSalary() const; // return base salary data member baseSalary
33
34 double earnings() const; // calculate earnings
35 void print() const; // print BasePlusCommissionEmployee object
36 private: Example 2
37 string firstName; BasePlus
38 string lastName; Commission
39 string socialSecurityNumber; Employee.h
40 double grossSales; // gross weekly sales
41 double commissionRate; // commission percentage (2 of 2)
42 double baseSalary; // base salary
43 }; // end class BasePlusCommissionEmployee Add data member baseSalary
44
45 #endif

34
1 // Fig. 12.8: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5 Example 2
6 // BasePlusCommissionEmployee class definition BasePlus
7 #include "BasePlusCommissionEmployee.h" Commission
8 Employee.cpp
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( (1 of 4)
11 const string &first, const string &last, const string &ssn,
12 double sales, double rate, double salary )
13 { Constructor takes one more argument,
14 firstName = first; // should validate which specifies the base salary
15 lastName = last; // should validate
16 socialSecurityNumber = ssn; // should validate
17 setGrossSales( sales ); // validate and store gross sales
18 setCommissionRate( rate ); // validate and store commission rate
19 setBaseSalary( salary ); // validate and store base salary
20 } // end BasePlusCommissionEmployee constructor
21 Use function setBaseSalary to validate data
22 // set first name
23 void BasePlusCommissionEmployee::setFirstName( const string &first )
24 {
25 firstName = first; // should validate
26 } // end function setFirstName

35
27
28 // return first name
29 string BasePlusCommissionEmployee::getFirstName() const
30 {
31 return firstName;
32 } // end function getFirstName
Example 2
33 BasePlus
34 // set last name Commission
35 void BasePlusCommissionEmployee::setLastName( const string &last )
Employee.cpp
36 {
37 lastName = last; // should validate
(2 of 4)
38 } // end function setLastName
39
40 // return last name
41 string BasePlusCommissionEmployee::getLastName() const
42 {
43 return lastName;
44 } // end function getLastName
45
46 // set social security number
47 void BasePlusCommissionEmployee::setSocialSecurityNumber(
48 const string &ssn )
49 {
50 socialSecurityNumber = ssn; // should validate
51 } // end function setSocialSecurityNumber
52

36
53 // return social security number
54 string BasePlusCommissionEmployee::getSocialSecurityNumber() const
55 {
56 return socialSecurityNumber;
57 } // end function getSocialSecurityNumber
58 Example 2
59 // set gross sales amount BasePlus
60 void BasePlusCommissionEmployee::setGrossSales( double sales )
Commission
61 {
Employee.cpp
62 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
63 } // end function setGrossSales
(3 of 4)
64
65 // return gross sales amount
66 double BasePlusCommissionEmployee::getGrossSales() const
67 {
68 return grossSales;
69 } // end function getGrossSales
70
71 // set commission rate
72 void BasePlusCommissionEmployee::setCommissionRate( double rate )
73 {
74 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
75 } // end function setCommissionRate
76
77 // return commission rate
78 double BasePlusCommissionEmployee::getCommissionRate() const
79 {
80 return commissionRate;
81 } // end function getCommissionRate
82

37
83 // set base salary
84 void BasePlusCommissionEmployee::setBaseSalary( double salary )
85 {
86 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
87 } // end function setBaseSalary
Function setBaseSalary validates data
88 and sets instance variable baseSalary
89 // return base salary
90 double BasePlusCommissionEmployee::getBaseSalary() const
91 {
92 return baseSalary;
93 } // end function getBaseSalary Function getBaseSalary returns the
94 value of instance variable baseSalary
95 // calculate earnings
96 double BasePlusCommissionEmployee::earnings() const
97 {
98 return baseSalary + ( commissionRate * grossSales );
99 } // end function earnings
100 Update function earnings to calculate the
101 // print BasePlusCommissionEmployee object earnings of a base-salaried commission employee
102 void BasePlusCommissionEmployee::print() const
103 {
104 cout << "base-salaried commission employee: " << firstName << ' '
105 << lastName << "\nsocial security number: " << socialSecurityNumber
106 << "\ngross sales: " << grossSales
107 << "\ncommission rate: " << commissionRate
Update function print
108 << "\nbase salary: " << baseSalary;
109 } // end
to display base salary
function print
Example 2
BasePlus
Commission
Employee.cpp (3 of 4)
1 // Fig. 12.9: fig12_09.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip> Example 2
9 using std::setprecision;
testBase.cpp (1 of 2)
10
11 // BasePlusCommissionEmployee class definition
12 #include "BasePlusCommissionEmployee.h"
13
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 );
22
Instantiate BasePlusCommissionEmployee object

39
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
Use BasePlusCommissionEmployee’s
27 << "\nSocial security number is "
get functions to retrieve the object’s instance
28 << employee.getSocialSecurityNumber()
variable values
29 << "\nGross sales is " << employee.getGrossSales()
30 << "\nCommission rate is " << employee.getCommissionRate()
31 << "\nBase salary is " << employee.getBaseSalary() << endl;
32
33 employee.setBaseSalary( 1000 ); // set base salary
34
35
Use BasePlusCommissionEmployee’s
cout << "\nUpdated employee information output by print function: \n"
36 << endl; setBaseSalary function to set base salary
37 employee.print(); // display the new employee information
38 Call object’s print function to
39 // display the employee's earnings display employee information
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
41
42 return 0;
43 } // end main
Call object’s earnings function
Example 2 to calculate employee’s earnings
testBase.cpp (1 of 2)

40
Similarities Example 1 & Example 2
l There are more similarities than differences between the code for the
CommissionEmployee class and the code for the
BasePlusCommissionEmployee class
n These two classes are classes that a sales organization would likely need both of in
their payroll system

l When I created the BasePlusCommissionEmployee class I of course


copied and pasted the CommissionEmployee class and then made the
relevant changes

l The problems with the copy/paste approach assuming one organization


needs and uses both of these classes
n time consuming
n error prone, easy to miss changes and make mistakes
n spreads many physical copies of the same code throughout the system
♦ if you want to change something in the CommissionEmployee class that likely also
affects the BasePlusCommissionEmployee class so maintenance is error prone
and a large task – this also makes it less reusable

l The solution to the problems with the copy/paste approach


n Inheritance

41
Software Engineering Observation
l With inheritance, the common data members
and member functions of all the classes in the
hierarchy are declared in a base class.
n When changes are required for these common
features, software developers need to make the
changes only in the base class—derived classes then
inherit the changes.

n Without inheritance, changes would need to be made to all


the source code files that contain a copy of the code in
question.

42
Inheritance First Attempt (Example 3)
l Example 3
l For this first attempt at Inheritance we are going to leave the
CommissionEmployee class as is and attempt to rewrite
BasePlusCommissionEmployee as a derived class of Commission
Employee
n We're going to see there are a few problems with this approach and there are some changes
to CommissionEmployee we should make for the inheritance

l Class BasePlusCommissionEmployee
n Derived from class CommissionEmployee
♦ Is a CommissionEmployee
♦ Inherits all members (remember the inherited private members will not be directly accessible)
n DEFAULT BEHAVIOR OF CONSTRUCTORS/DESTRUCTORS IN INHERITANCE:
Constructor is not inherited/Destructor is not inherited as we'll see in a second
♦ Use base-class initializer syntax to initialize base-class data members
♦ NOTE: The new C++11 standard has a way to inherit constructors we'll test this out in some examples
later – but for test purposes if I ask about the default behavior constructors are NOT inherited
♦ This first example will use the default behavior of constructors/destructors NOT being inherited
by the derived class
n Has an additional data member baseSalary (specialization by extension)
♦ Also has the additional get and set functions for this member (more specialization)
n We will also want to redefine the earnings and print functions to customize (specialization by
enhancement)

43
1 // Fig. 12.10: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7 #include <string> // C++ standard string class
Include the base-class header file
8 using std::string;
in the derived-class header file
9
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration
11
12 class BasePlusCommissionEmployee : public CommissionEmployee
13 {
14 public:
15 BasePlusCommissionEmployee( const string &, const string &,
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
Class BasePlusCommissionEmployee derives
18 void setBaseSalary( double ); // set base salary
publicly from class CommissionEmployee
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object Example 3
23 private:
BasePlus
24 double baseSalary; // base salary Commission
25 }; // end class BasePlusCommissionEmployee Employee.h
26
27 #endif (1 of 1)

44
Comments – Example 3 Specification (.h)
l The colon (:) in line 12 is used to indicate inheritance and public
indicates the type of inheritance
n We said with public inheritance the derived class inherits all the
members of the base class
♦ This is true except for the constructor and the destructor (if there were
one) (remember we are talking about default behavior here with no new
standard stuff yet)
l This means our derived class BasePlusCommissionEmployee must
include its own constructor but inherits all other members of the base
class CommissionEmployee
n Note that we cannot see the inherited members of
CommissionEmployee just by looking at
BasePlusCommissionEmployee's source code but:
♦ they ARE inherited and thus can be used by any object of the
BasePlusCommissionEmployee class
n Note that our derived class does redefine earnings() and
print() even though they are inherited because we specialized
them to enhance/customize their functionality (we did this by
redefining them)

45
1 // Fig. 12.11: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8 Example 3
9 // constructor BasePlus
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( Commission
11 const string &first, const string &last, const string &ssn,
Employee.cpp
12 double sales, double rate, double salary )
13 // explicitly call base-class constructor
(1 of 2)
14 : CommissionEmployee( first, last, ssn, sales, rate )
15 {
16 setBaseSalary( salary ); // validate and store base salary
17 } // end BasePlusCommissionEmployee constructor
18
19 // set base salary
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 {
Initialize base class data member by calling the base-class constructor
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary; using base-class initializer syntax – REQUIRED with non-inherited
23 } // end function setBaseSalary constructor/destructor (remember constructors and destructors are by
24 DEFAULT not inherited, the new standard has some way to maybe
25 // return base salary change this but this will be the way we do it most of the time)
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary

46
Comments – Example 3 Implementation Part 1 (.cpp)

l The implementation for the constructor shows


base-class initializer syntax
n This is used to pass arguments to the base class
(CommissionEmployee) constructor
n C++ requires that a derived-class constructor call its
base class constructor to initialize the base class
members that are inherited into the derived class
♦ If no base class constructor is called using this syntax it
will attempt to call the default or no-arg constructor if
there is one
l Since this class does not have a default or a no-arg
constructor, we would get an error if we did this
l Remember a default constructor with no args is only
provided by C++ if the class does not supply any other
constructor

47
Including the base class header file
l Note that I included the base class's header file in the derived
class's header file (#include "CommissionEmployee.h")
l Base class header file must be included in derived class header file
for three reasons, the compiler must
1. Know that base class exists
♦ in order to use the base class's name in the constructor or elsewhere
2. Know size of inherited data members
♦ A client program that creates an instance of an object must include the class
definition to reserve the proper amount of memory for the object
♦ With inheritance, a derived class's object's size regarding this depends on the
data members declared explicitly in its class definition AND the data members
inherited from both its direct and indirect base classes
l Including the base class's definition in the derived class's header allows this to
happen (the compiler to correctly determine the memory requirements for the
base class's data members that become part of a derived-class object) and
thus
3. Ensure that inherited class members are used properly
♦ For example that private base class members aren't directly accessed

48
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 // derived class cannot access the base class’s private data
35 return baseSalary + ( commissionRate * grossSales );
36 } // end function earnings
37
Compiler generates errors because base class’s data
38 // print BasePlusCommissionEmployee object
member commissionRate and grossSales
39 void BasePlusCommissionEmployee::print() const
are private inherited members
40 {
41 // derived class cannot access the base class’s private data
42 cout << "base-salaried commission employee: " << firstName << ' '
43 << lastName << "\nsocial security number: " << socialSecurityNumber
44 << "\ngross sales: " << grossSales
45 << "\ncommission rate: " << commissionRate Compiler generates errors because the base
46 << "\nbase salary: " << baseSalary; class’s data members firstName,
47 } // end function print lastName, socialSecurityNumber,
grossSales and commissionRate are
Example 3 private

BasePlus
Commission
Employee.cpp

(1 of 2)

49
Comments – Example 3 Implementation Part 2 (.cpp)

l Remember that with public inheritance the derived


class can NOT directly access the base class's private
members
n So we get errors in both the earnings() function and the
print() function

l How to fix this?


n Although the derived class cannot directly access private
members of the base class it can use public members to
modify them
♦ Let's fix Example 3 so it will work

n Note: we could also use protected members in the base class


to avoid this problem which we will do in the next example BUT
THIS APPROACH IS BETTER than using protected IN
MOST CASES – we'll discuss why later

50
Performance Tip
l In a derived-class constructor, initializing
member objects and invoking base-class
constructors explicitly in the member initializer
list:
n prevents duplicate initialization in the case where a default
constructor is called, and then data members are modified
again in the derived-class constructor’s body.

51
Linking Process
l The linking process requires:
n the object code for all classes used in the program AND the
object code of the direct and indirect base classes of any derived
classes used in the program

l If a client wants to create an application using the class


BasePlusCommissionEmployee that is derived from
CommissionEmployee:
n When compiling the application, the Client's object code must be
linked with the object code for both the derived class and the
base class
n The client code is also linked with object code for any C++
standard libraries used

l So the client gets to see the specifications and gets


access to all implementations it may need

52
Inheritance & protected data (Example 4)
l Example 4
n We can use protected data members to allow the
BasePlusCommissionEmployee derived class to directly
access the CommissionEmployee private base class data
members of:
♦ firstName, lastName, socialSecurityNumber, grossSales, and
commissionRate

n Remember we said a base class's protected members can be


accessed by:
♦ the base class's members and friends
♦ and any derived class's members and friends

l Use protected data


n Enable class BasePlusCommissionEmployee to directly
access private base class data members
n Base class’s protected members are inherited by all derived
classes of that base class

53
1 // Fig. 12.12: CommissionEmployee.h
2 // CommissionEmployee class definition with protected data.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6 #include <string> // C++ standard string class
7 using std::string;
Example 4
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23

54
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate
28 double getCommissionRate() const; // return commission rate
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 protected:
33 string firstName;
Declare protected data
34 string lastName;
35 string socialSecurityNumber;
36 double grossSales; // gross weekly sales
Example 4
37 double commissionRate; // commission percentage
38 }; // end class CommissionEmployee Commission
39 Employee.h
40 #endif
(2 of 2)

55
1 // Fig. 12.13: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
11 double sales, double rate )
12 {
13 firstName = first; // should validate
14
15
lastName = last; // should validate
socialSecurityNumber = ssn; // should validate
Example 4
16 setGrossSales( sales ); // validate and store gross sales Commission
17 setCommissionRate( rate ); // validate and store commission rate Employee.cpp
18 } // end CommissionEmployee constructor
19 (1 of 4)
20 // set first name
21 void CommissionEmployee::setFirstName( const string &first )
22 {
23 firstName = first; // should validate
24 } // end function setFirstName
25
26 // return first name
27 string CommissionEmployee::getFirstName() const
28 {
29 return firstName;
30 } // end function getFirstName

56
31
32 // set last name
33 void CommissionEmployee::setLastName( const string &last )
34 {
35 lastName = last; // should validate
36 } // end function setLastName
37
38 // return last name
39 string CommissionEmployee::getLastName() const
40 {
41 return lastName;
42 } // end function getLastName
43
44
45
// set social security number
void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
Example 4
46 { Commission
47 socialSecurityNumber = ssn; // should validate Employee.cpp
48 } // end function setSocialSecurityNumber
49 (2 of 4)
50 // return social security number
51 string CommissionEmployee::getSocialSecurityNumber() const
52 {
53 return socialSecurityNumber;
54 } // end function getSocialSecurityNumber
55
56 // set gross sales amount
57 void CommissionEmployee::setGrossSales( double sales )
58 {
59 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
60 } // end function setGrossSales

57
61
62 // return gross sales amount
63 double CommissionEmployee::getGrossSales() const
64 {
65 return grossSales;
66 } // end function getGrossSales
67
68 // set commission rate
69 void CommissionEmployee::setCommissionRate( double rate )
70 {
71 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
72 } // end function setCommissionRate
73
74 // return commission rate Example 4
75 double CommissionEmployee::getCommissionRate() const Commission
76 { Employee.cpp
77 return commissionRate;
78 } // end function getCommissionRate (3 of 4)
79
80 // calculate earnings
81 double CommissionEmployee::earnings() const
82 {
83 return commissionRate * grossSales;
84 } // end function earnings

58
85
86 // print CommissionEmployee object
87 void CommissionEmployee::print() const
88 {
89 cout << "commission employee: " << firstName << ' ' << lastName
90 << "\nsocial security number: " << socialSecurityNumber
91 << "\ngross sales: " << grossSales
92 << "\ncommission rate: " << commissionRate;
93 } // end function print

Example 4
Commission
Employee.cpp

(4 of 4)

59
1 // Fig. 12.14: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6 Example 4
7 #include <string> // C++ standard string class BasePlus
8 using std::string; Commission
9 Employee.h
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration
11 (1 of 1)
12 class BasePlusCommissionEmployee : public CommissionEmployee
13 { BasePlusCommissionEmployee
14 public: still inherits publicly from
15 BasePlusCommissionEmployee( const string &, const string &,
CommissionEmployee
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
18 void setBaseSalary( double ); // set base salary
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object
23 private:
24 double baseSalary; // base salary
25 }; // end class BasePlusCommissionEmployee
26
27 #endif

60
1 // Fig. 12.15: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee( Call base-class constructor using
11 const string &first, const string &last, const string &ssn,
base-class initializer syntax
12 double sales, double rate, double salary )
13 // explicitly call base-class constructor
14 : CommissionEmployee( first, last, ssn, sales, rate )
15 {
16 setBaseSalary( salary ); // validate and store base salary
Example 4
BasePlus
17 } // end BasePlusCommissionEmployee constructor
18
Commission
19 // set base salary
Employee.cpp
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 { (1 of 2)
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
23 } // end function setBaseSalary
24
25 // return base salary
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary

61
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 // can access protected data of base class
35 return baseSalary + ( commissionRate * grossSales );
36 } // end function earnings
37
38 // print BasePlusCommissionEmployee object
Directly access base
39 void BasePlusCommissionEmployee::print() const
class’s protected data
40 {
41 // can access protected data of base class
42 cout << "base-salaried commission employee: " << firstName << ' '
43 << lastName << "\nsocial security number: " << socialSecurityNumber Example 4
44 << "\ngross sales: " << grossSales
BasePlus
45 << "\ncommission rate: " << commissionRate Commission
46 << "\nbase salary: " << baseSalary; Employee.cpp
47 } // end function print
(1 of 2)

62
1 // Fig. 12.16: fig12_16.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip>
Example 4
testInheritance2
9 using std::setprecision;
.cpp
10
11 // BasePlusCommissionEmployee class definition
12 #include "BasePlusCommissionEmployee.h"
(1 of 2)
13
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 );
22
Note that the output of all the test programs (with and without Inheritance)
are identical
-The advantages of the inheritance is in the code saved by having
the derived class absorb the duplicate members of the base
class
-In addition, this will make maintenance, modifying and
debugging easier and less error prone
-This also makes code more reusable
63
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
27 << "\nSocial security number is "
28 << employee.getSocialSecurityNumber()
29 << "\nGross sales is " << employee.getGrossSales() Example 4
30 << "\nCommission rate is " << employee.getCommissionRate() testInheritance2
31 << "\nBase salary is " << employee.getBaseSalary() << endl; .cpp
32
33 employee.setBaseSalary( 1000 ); // set base salary (2 of 2)
34
35 cout << "\nUpdated employee information output by print function: \n"
36 << endl;
37 employee.print(); // display the new employee information
38
39 // display the employee's earnings
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
41
42 return 0;
43 } // end main

64
Notes on using protected data
l Using protected data members
l Advantages
n Derived class can modify values directly
♦ Avoid set/get method call overhead
l Slight increase in performance
n In most cases though, it is better to use private data members to encourage proper
software engineering and leave code optimization issues to the compiler
l Disadvantages
n Using protected data members causes two serious problems
1. No validity checking
♦ Derived class can assign illegal values to private members since they don’t have to use set
functions to access them
2. Implementation dependent
♦ Derived class functions more likely to be written so that they are dependent on base class
implementation (base class member variables) if protected is used
l It's better to have the classes be dependent on the base-class services (non-private member
functions) than on the actual base class implementation (private members)
§ if the implementation of the inherited public functions change the derived class doesn't have to
worry about the changes (if it only uses the functions and not the members)
§ but if the inherited private members directly change and the derived class directly accesses them
the derived class will also have to change
♦ Base class implementation changes to private members may result in derived class
modifications if the derived class directly accesses them – this is not true in the case of just
using inherited public functions (think of the soda machine)
l Fragile (brittle) software
65
Software Engineering Tips
l It is appropriate to use the protected access specifier
when:
n a base class should provide a service (i.e., a member function)
only to its derived classes (and friends), not to other clients.

l Declaring base-class data members private (as


opposed to declaring them protected):
n enables programmers to change the base-class implementation
without having to change derived-class implementations.

l When possible, avoid including protected data


members in a base class.
n Instead, include non-private member functions that access
private data members, ensuring that the object maintains a
consistent state.

66
Inheritance good Software Engineering (Example 5)

l Example 5
l Reexamine hierarchy
n Use the best software engineering practice
♦ Declare data members as private
♦ Provide public get and set functions
♦ Use get methods to obtain values of data members always
whenever possible
n We will have the print() and earnings() functions call
the base class functions needed rather than directly
accessing base class implementation data
♦ This means if the base class for some reason decided to
change the data member names, the earnings() and
print() function definitions of the derived class would not
require modification
l These types of changes only change things in the
base class not the derived class

67
1 // Fig. 12.17: CommissionEmployee.h
2 // CommissionEmployee class definition with good software engineering.
3 #ifndef COMMISSION_H
4 #define COMMISSION_H
5
6
7
#include <string> // C++ standard string class
using std::string;
Example 5
8 Commission
9 class CommissionEmployee Employee.h
10 {
11 public: (1 of 2)
12 CommissionEmployee( const string &, const string &, const string &,
13 double = 0.0, double = 0.0 );
14
15 void setFirstName( const string & ); // set first name
16 string getFirstName() const; // return first name
17
18 void setLastName( const string & ); // set last name
19 string getLastName() const; // return last name
20
21 void setSocialSecurityNumber( const string & ); // set SSN
22 string getSocialSecurityNumber() const; // return SSN
23
24 void setGrossSales( double ); // set gross sales amount
25 double getGrossSales() const; // return gross sales amount
26
27 void setCommissionRate( double ); // set commission rate
28 double getCommissionRate() const; // return commission rate

68
29
30 double earnings() const; // calculate earnings
31 void print() const; // print CommissionEmployee object
32 private:
33 string firstName;
Declare private data
34 string lastName;
35 string socialSecurityNumber;
36 double grossSales; // gross weekly sales Example 5
37 double commissionRate; // commission percentage Commission
38 }; // end class CommissionEmployee Employee.h
39
40 #endif (2 of 2)

69
1 // Fig. 12.18: CommissionEmployee.cpp
2 // Class CommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 #include "CommissionEmployee.h" // CommissionEmployee class definition
7
8 // constructor
Example 5
Commission
9 CommissionEmployee::CommissionEmployee(
10 const string &first, const string &last, const string &ssn,
Employee.cpp
11 double sales, double rate )
12 : firstName( first ), lastName( last ), socialSecurityNumber( ssn ) (1 of 4)
13 {
14 setGrossSales( sales ); // validate and store gross sales
Use member initializers
to set the values
15 setCommissionRate( rate ); // validate and store commission rate
16 } // end CommissionEmployee constructor
of members firstName, lastname
17 and socialSecurityNumber
18 // set first name
19 void CommissionEmployee::setFirstName( const string &first )
20 {
21 firstName = first; // should validate
22 } // end function setFirstName
23
24 // return first name
25 string CommissionEmployee::getFirstName() const
26 {
27 return firstName;
28 } // end function getFirstName

70
29
30 // set last name
31 void CommissionEmployee::setLastName( const string &last )
32 {
33 lastName = last; // should validate
34 } // end function setLastName
35
36 // return last name
Example 5
37 string CommissionEmployee::getLastName() const Commission
38 { Employee.cpp
39 return lastName;
40 } // end function getLastName (2 of 4)
41
42 // set social security number
43 void CommissionEmployee::setSocialSecurityNumber( const string &ssn )
44 {
45 socialSecurityNumber = ssn; // should validate
46 } // end function setSocialSecurityNumber
47
48 // return social security number
49 string CommissionEmployee::getSocialSecurityNumber() const
50 {
51 return socialSecurityNumber;
52 } // end function getSocialSecurityNumber
53
54 // set gross sales amount
55 void CommissionEmployee::setGrossSales( double sales )
56 {
57 grossSales = ( sales < 0.0 ) ? 0.0 : sales;
58 } // end function setGrossSales

71
59
60 // return gross sales amount
61 double CommissionEmployee::getGrossSales() const
62 {
63 return grossSales;
64 } // end function getGrossSales
65
66 // set commission rate
Example 5
67 void CommissionEmployee::setCommissionRate( double rate ) Commission
68 { Employee.cpp
69 commissionRate = ( rate > 0.0 && rate < 1.0 ) ? rate : 0.0;
70 } // end function setCommissionRate (3 of 4)
71
72 // return commission rate
73 double CommissionEmployee::getCommissionRate() const
74 {
75 return commissionRate;
76 } // end function getCommissionRate
77
78 // calculate earnings Use get functions to obtain
79 double CommissionEmployee::earnings() const the values of data members
80 {
81 return getCommissionRate() * getGrossSales();
82 } // end function earnings
83

72
84 // print CommissionEmployee object
85 void CommissionEmployee::print() const
86 {
87 cout << "commission employee: "
88 << getFirstName() << ' ' << getLastName()
89 << "\nsocial security number: " << getSocialSecurityNumber()
90 << "\ngross sales: " << getGrossSales()
91 << "\ncommission rate: " << getCommissionRate();
92 } // end function print Use get functions to obtain
the values of data members

Example 5
Commission
Employee.cpp

(4 of 4)

73
Performance Tip
l Using a member function to access a data
member’s value can be slightly slower than
accessing the data directly.
n However, today’s optimizing compilers are carefully
designed to perform many optimizations implicitly
♦ (such as inlining set and get member-function calls).
♦ As a result, programmers should write code that adheres to
proper software engineering principles, and leave
optimization issues to the compiler.
l A good rule is, “Do not second-guess the compiler.”

74
1 // Fig. 12.19: BasePlusCommissionEmployee.h
2 // BasePlusCommissionEmployee class derived from class
3 // CommissionEmployee.
4 #ifndef BASEPLUS_H
5 #define BASEPLUS_H
6
7 #include <string> // C++ standard string class
Example 5
8 using std::string; BasePlus
9 Commission
10 #include "CommissionEmployee.h" // CommissionEmployee class declaration Employee.h
11
12 class BasePlusCommissionEmployee : public CommissionEmployee (1 of 1)
13 {
14 public:
15 BasePlusCommissionEmployee( const string &, const string &,
16 const string &, double = 0.0, double = 0.0, double = 0.0 );
17
18 void setBaseSalary( double ); // set base salary
19 double getBaseSalary() const; // return base salary
20
21 double earnings() const; // calculate earnings
22 void print() const; // print BasePlusCommissionEmployee object
23 private:
24 double baseSalary; // base salary
25 }; // end class BasePlusCommissionEmployee
26
27 #endif

75
1 // Fig. 12.20: BasePlusCommissionEmployee.cpp
2 // Class BasePlusCommissionEmployee member-function definitions.
3 #include <iostream>
4 using std::cout;
5
6 // BasePlusCommissionEmployee class definition
7 #include "BasePlusCommissionEmployee.h"
8
9 // constructor
10 BasePlusCommissionEmployee::BasePlusCommissionEmployee(
Example 5
11 const string &first, const string &last, const string &ssn,
12 double sales, double rate, double salary ) BasePlus
13 // explicitly call base-class constructor Commission
14 : CommissionEmployee( first, last, ssn, sales, rate ) Employee.cpp
15 {
16 setBaseSalary( salary ); // validate and store base salary (1 of 2)
17 } // end BasePlusCommissionEmployee constructor
18
19 // set base salary
20 void BasePlusCommissionEmployee::setBaseSalary( double salary )
21 {
22 baseSalary = ( salary < 0.0 ) ? 0.0 : salary;
23 } // end function setBaseSalary
24
25 // return base salary
26 double BasePlusCommissionEmployee::getBaseSalary() const
27 {
28 return baseSalary;
29 } // end function getBaseSalary

76
30
31 // calculate earnings
32 double BasePlusCommissionEmployee::earnings() const
33 {
34 return getBaseSalary() + CommissionEmployee::earnings();
35 } // end function earnings
36
Invoke base class’s earnings function
37 // print BasePlusCommissionEmployee object
38 void BasePlusCommissionEmployee::print() const
39 {
40 cout << "base-salaried ";
41
42 // invoke CommissionEmployee's print function
43 CommissionEmployee::print();
44
45 cout << "\nbase salary: " << getBaseSalary(); Invoke base class’s print function
46 } // end function print

Both earnings() and print() are redefined base class member


functions Example 5
BasePlus
Note that we also call the getBaseSalary() function
Commission
rather than directly access the baseSalary member,
Employee.cpp
this way if it changes we don't also have to change the
function
(2 of 2)
Note the syntax used to invoke a redefined base class member function
from a derived class, places the base-class name and the binary scope
resolution operator (::) before the base-class member function name
77
Redefined base class member functions
l Redefined base-class member functions are good engineering
n because these functions avoid duplicating code and can call the base class
member functions they are redefined from to get additional information

l When a base-class member function is redefined in a derived


class, the derived-class version often calls the base-class
version to do additional work.
n Failure to use the :: operator prefixed with the name of the base class when
referencing the base class’s member function causes infinite recursion,
because the derived-class member function would then call itself.

l Including a base-class member function with a different signature in


the derived class hides the base-class version of the function.
n Attempts to call the base-class version through the public interface of a
derived-class object in this case result in compilation errors.

78
1 // Fig. 12.21: fig12_21.cpp
2 // Testing class BasePlusCommissionEmployee.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6 using std::fixed;
7
8 #include <iomanip>
9 using std::setprecision;
10
Example 5
11 // BasePlusCommissionEmployee class definition testInheritance3.cpp
12 #include "BasePlusCommissionEmployee.h"
13 (1 of 2)

79
14 int main()
15 {
16 // instantiate BasePlusCommissionEmployee object
17 BasePlusCommissionEmployee
18 employee( "Bob", "Lewis", "333-33-3333", 5000, .04, 300 );
19
20 // set floating-point output formatting
21 cout << fixed << setprecision( 2 ); Create BasePlusCommissionEmployee object
22
23 // get commission employee data
24 cout << "Employee information obtained by get functions: \n"
25 << "\nFirst name is " << employee.getFirstName()
26 << "\nLast name is " << employee.getLastName()
27 << "\nSocial security number is " Use inherited get methods to access
28 << employee.getSocialSecurityNumber() base class private members
29 << "\nGross sales is " << employee.getGrossSales()
30 << "\nCommission rate is " << employee.getCommissionRate()
31 << "\nBase salary is " << employee.getBaseSalary() << endl;
32 Use BasePlusCommissionEmployee
33 employee.setBaseSalary( 1000 ); // set base salary
get method to access private member
34
35 cout << "\nUpdated employee information output by print function: \n"
36 << endl;
Use BasePlusCommissionEmployee set method
37 employee.print(); // display the new to modify
employee private data member baseSalary
information
38
39 // display the employee's earnings Example 5
40 cout << "\n\nEmployee's earnings: $" << employee.earnings() << endl;
testInheritance3.cpp
41
42 return 0;
43 } // end main (2 of 2)

80
Examples 1-5
l They all work identically but the best
engineered example is Example 5
n You want to start trying to use good software
engineering techniques in your code

81
C++11 (New Standard) Inheriting Base Class
Constructors
l Some of these new standard things are implemented in some compilers and not
others so I'm just mentioning them as something you might want to try but something
that will be more relevant in the future

l The new standard allows use to explicitly inherit a base class constructor
n you do it with the following using declaration which can be placed anywhere in the derived class
definition (you will have to explore I'm not sure but it sound like the .h or the .cpp)
♦ using BaseClass::BaseClass; //BaseClass is the name of the base class

♦ The general result of the above using declaration is that for each constructor in the base class the
compiler generates a derived class constructor that calls the corresponding base class constructor
l These generated constructors perform only DEFAULT INITIALIZATION for any derived class specialized
member variables

l General rules when inheriting constructors in the new standard:


n Each inherited constructor has the same access level (public, protected or private) as its
corresponding base class constructor
n The default, copy and move (something else new with C++11) constructors are not inherited
n If the constructor is "deleted" in the base class it's corresponding constructor in the derived class is
also deleted
n If the derived class does not explicitly define constructors (the regular way) the compiler generates a
default constructor in the derived class (a do nothing I assume) even if it inherits constructors from
the base class
n If a constructor that you explicitly define in the derived class (the regular way) has the same
parameter list as a base class constructor you inherit then the base class constructor version is not
inherited
n A base class constructor's default arguments are not inherited. Instead the compiler generates
overloaded constructors in the dervied class
Constructors, Destructors & Inheritance
l Concept: When an object of a derived class is being
instantiated: the base class constructor is called before
the derived class constructor. When the object of the
derived class is destroyed, the derived class destructor is
called before the base class destructor.

l We know that constructors are automatically called by the


compiler whenever an object of a class is created
n The object of the derived class can be regarded as having an
object of the base class embedded within it since all of the base
class's members are inherited by the derived class
n When an object of the derived class is created the compiler will
ALWAYS call the base class constructor before it calls the derived
class constructor
♦ This order is reversed when the object of the derived class is destroyed
n This order permits the derived class constructors to use data
or member functions from the base class when they do their
work

83
Constructors, Destructors & Inheritance
l Instantiating derived-class objects begins a chain of constructor calls
n Derived-class constructor invokes base class constructor
♦ Implicitly (by calling the default or no-arg constructor) or explicitly (via
base class member initializer)
♦ If the base class is derived from another class it too is required to invoke the
constructor one up the inheritance change before itself and so on
♦ The very top Base class of inheritance hierarchy
l is the Last constructor called in chain
l is the First constructor body to finish executing
l Example: CommissionEmployee/BasePlusCommissionEmployee
hierarchy
§ CommissionEmployee constructor called last
§ CommissionEmployee constructor body finishes execution first
l The class at the bottom of the hierarchy is the first constructor called and the
last one to finish executing
n Initializing data members
♦ Each base-class constructor initializes its data members that are inherited by
derived class

84
Software Engineering Observation
l When a program creates a derived-class object
n the derived-class constructor immediately calls the base-
class constructor
n the base-class's member initializers execute followed by
the base class constructor’s body executing
n then the derived class’s member initializers execute
n and finally the derived-class constructor’s body executes.

l This process cascades up the hierarchy if the


hierarchy contains more than two levels.

85
Constructors, Destructors & Inheritance
l Destroying derived-class object
n Chain of destructor calls
♦ Reverse order of constructor chain
♦ Destructor of derived-class called first
♦ Destructor of next base class up hierarchy next
l Continue up hierarchy until final base reached

§ After final base-class destructor, object removed from memory


l Base-class constructors, destructors,
assignment operators (overloaded assignment
operators)
n are NOT inherited by derived classes by default
(ignoring the new C++11 standard's new option for
constructors only)

86
More Constructors, Destructors & Inheritance
l Suppose that we create an object of a derived class
where both the base class and the derived class
contain objects of other classes (composition – so
now we have inheritance and composition).
n When an object of that derived class is created, first the
constructors for the base class’s member objects execute
n then the base-class constructor executes
n then the constructors for the derived class’s member objects
execute
n then the derived class’s constructor executes.
n Destructors for derived-class objects are called in the reverse of
the order in which their corresponding constructors are called.

87
Base Access Specification
l When we created our derived classes we specified
what's called a base access specification before the
name of the class we were deriving from:
n class Student : public Person
♦ So public is the base access specification

l The base access specification is NOT the same as


member access specification
n member access specification: determines the type of access
to/for members defined in the class
n base access specification: determines the type of access for
inherited members in regard to the base class

88
public, protected and private Inheritance
l We said with inheritance the base class can be executed through
public, private, or protected inheritance
n protected and private inheritance are rare and each should only
be used if there is a very good reason

l Here is a summary of the differences:


n public inheritance
♦ Base class public members à derived class public members
♦ Base class protected members à derived class protected members
♦ Base class private members are not DIRECTLY accessible by the derived class
n protected inheritance (not is-a relationship)
♦ Base class public and protected members à derived class protected members
♦ Base class private members are not DIRECTLY accessible by the derived class
n private inheritance (not is-a relationship)
♦ Base class public and protected members à derived class private members
♦ Base class private members are not DIRECTLY accessible by the derived class

89
Base Access Specification
Base Class How members of the base class appear in the
Access Derived class
Specification
private lPrivate members of the base class are inaccessible to the derived class

lProtected members of the base class become private members of the


derived class
lPublic members of the base class become private members of the
derived class
protected lPrivate members of the base class are inaccessible to the derived class

lProtected members of the base class become protected members of the


derived class
lPublic members of the base class become protected members of the
derived class
public lPrivate members of the base class are inaccessible to the derived class

lProtected members of the base class become protected members of the


derived class
Public members of the base class become public members of the derived
class

90
Software Engineering with Inheritance
l Customizing existing software
n Inheriting from existing classes
♦ Can include additional members
♦ Can redefine base-class members
♦ No direct access to base class’s source code
l Only links to object code
n Independent software vendors (ISVs)
♦ Develop proprietary code for sale/license
l Available in object-code format
♦ Users derive new classes
l Without accessing ISV proprietary source code

91
Software Engineering Tips
l At the design stage in an object-oriented system,
the designer often determines that certain
classes are closely related.
n The designer should “factor out” common attributes and
behaviors and place these in a base class
♦ and then use inheritance to form derived classes, giving them
with capabilities beyond those inherited from the base class.

l The creation of a derived class does not affect


its base class’s source code. Inheritance
preserves the integrity of a base class.

92

You might also like