12.6.2. Creating Concrete Derived Class SalariedEmployee

Class SalariedEmployee (Figs. 12.1112.12) derives from class Employee (line 9 of Fig. 12.11). The public member functions include a constructor that takes a first name, a last name, a social security number and a weekly salary as arguments (lines 12–13); a virtual destructor (line 14); a set function to assign a new nonnegative value to data member weeklySalary (line 16); a get function to return weeklySalary’s value (line 17); a virtual function earnings that calculates a SalariedEmployee’s earnings (line 20) and a virtual function print (line 21) that outputs the employee’s type, namely, "salaried employee: " followed by employee-specific information produced by base class Employee’s print function and SalariedEmployee’s getWeeklySalary function.


 1   // Fig. 12.11: SalariedEmployee.h
 2   // SalariedEmployee class derived from Employee.
 3   #ifndef SALARIED_H
 4   #define SALARIED_H
 5
 6   #include <string> // C++ standard string class
 7   #include "Employee.h" // Employee class definition
 8
 9   class SalariedEmployee : public Employee
10   {
11   public:
12      SalariedEmployee( const std::string &, const std::string &,
13         const std::string &, double = 0.0 );
14      virtual ~SalariedEmployee() { } // virtual destructor
15
16      void setWeeklySalary( double ); // set weekly salary
17      double getWeeklySalary() const; // return weekly salary
18
19      // keyword virtual signals intent to override
20      virtual double earnings() const override; // calculate earnings
21      virtual void print() const override; // print object           
22   private:
23      double weeklySalary; // salary per week
24   }; // end class SalariedEmployee
25
26   #endif // SALARIED_H


Fig. 12.11. SalariedEmployee class header.


 1   // Fig. 12.12: SalariedEmployee.cpp
 2   // SalariedEmployee class member-function definitions.
 3   #include <iostream>
 4   #include <stdexcept>
 5   #include "SalariedEmployee.h" // SalariedEmployee class definition
 6   using namespace std;
 7
 8   // constructor
 9   SalariedEmployee::SalariedEmployee( const string &first,
10      const string &last, const string &ssn, double salary )
11      : Employee( first, last, ssn )
12   {
13      setWeeklySalary( salary );
14   } // end SalariedEmployee constructor
15
16   // set salary
17   void SalariedEmployee::setWeeklySalary( double salary )
18   {
19      if ( salary >= 0.0 )
20         weeklySalary = salary;
21      else
22         throw invalid_argument( "Weekly salary must be >= 0.0" );
23   } // end function setWeeklySalary
24
25   // return salary
26   double SalariedEmployee::getWeeklySalary() const
27   {
28      return weeklySalary;
29   } // end function getWeeklySalary
30
31   // calculate earnings;
32   // override pure virtual function earnings in Employee
33   double SalariedEmployee::earnings() const
34   {
35      return getWeeklySalary();
36   } // end function earnings
37
38   // print SalariedEmployee's information
39   void SalariedEmployee::print() const
40   {
41      cout << "salaried employee: ";                                
42      Employee::print(); // reuse abstract base-class print function
43      cout << " weekly salary: " << getWeeklySalary();
44   } // end function print


Fig. 12.12. SalariedEmployee class implementation file.

SalariedEmployee Class Member-Function Definitions

Figure 12.12 contains the member-function definitions for SalariedEmployee. The class’s constructor passes the first name, last name and social security number to the Employee constructor (line 11) to initialize the private data members that are inherited from the base class, but not directly accessible in the derived class. Function earnings (lines 33–36) overrides pure virtual function earnings in Employee to provide a concrete implementation that returns the SalariedEmployee’s weekly salary. If we did not define earnings, class SalariedEmployee would be an abstract class, and any attempt to instantiate a SalariedEmployee object would cause a compilation error. In class SalariedEmployee’s header, we declared member functions earnings and print as virtual (lines 20–21 of Fig. 12.11)—actually, placing the virtual keyword before these member functions is redundant. We defined them as virtual in base class Employee, so they remain virtual functions throughout the class hierarchy. Explicitly declaring such functions virtual at every level of the hierarchy promotes program clarity. Not declaring earnings as pure virtual signals our intent to provide an implementation in this concrete class.

Function print of class SalariedEmployee (lines 39–44 of Fig. 12.12) overrides Employee function print. If class SalariedEmployee did not override print, SalariedEmployee would inherit the Employee version of print. In that case, SalariedEmployee’s print function would simply return the employee’s full name and social security number, which does not adequately represent a SalariedEmployee. To print a SalariedEmployee’s complete information, the derived class’s print function outputs "salaried employee: " followed by the base-class Employee-specific information (i.e., first name, last name and social security number) printed by invoking the base class’s print function using the scope resolution operator (line 42)—this is a nice example of code reuse. Without the scope resolution operator, the print call would cause infinite recursion. The output produced by SalariedEmployee’s print function also contains the employee’s weekly salary obtained by invoking the class’s getWeeklySalary function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.33.157