Recall from the problem statement at the beginning of Section 12.6 that, for the current pay period, our fictitious company has decided to reward BasePlusCommissionEmployee
s by adding 10 percent to their base salaries. When processing Employee
objects polymorphically in Section 12.6.5, we did not need to worry about the “specifics.” Now, however, to adjust the base salaries of BasePlusCommissionEmployee
s, we have to determine the specific type of each Employee
object at execution time, then act appropriately. This section demonstrates the powerful capabilities of runtime type information (RTTI) and dynamic casting, which enable a program to determine an object’s type at execution time and act on that object accordingly.1
1. Some compilers require that RTTI be enabled before it can be used in a program. The compilers we used for testing this book’s examples—GNU C++ 4.7, Visual C++ 2012 and Xcode 4.5 LLVM—each enable RTTI by default.
Figure 12.19 uses the Employee
hierarchy developed in Section 12.6 and increases by 10 percent the base salary of each BasePlusCommissionEmployee
. Line 21 declares three-element vector employees
that stores pointers to Employee
objects. Lines 24–29 populate the vector
with the addresses of dynamically allocated objects of classes SalariedEmployee
(Figs. 12.11–12.12), CommissionEmployee
(Figs. 12.13–12.14) and BasePlusCommissionEmployee
(Figs. 12.15–12.16). Lines 32–52 iterate through the employees vector
and display each Employee
’s information by invoking member function print
(line 34). Recall that because print
is declared virtual
in base class Employee
, the system invokes the appropriate derived-class object’s print
function.
1 // Fig. 12.19: fig12_19.cpp
2 // Demonstrating downcasting and runtime type information.
3 // NOTE: You may need to enable RTTI on your compiler
4 // before you can compile this application.
5 #include <iostream>
6 #include <iomanip>
7 #include <vector>
8 #include <typeinfo>
9 #include "Employee.h"
10 #include "SalariedEmployee.h"
11 #include "CommissionEmployee.h"
12 #include "BasePlusCommissionEmployee.h"
13 using namespace std;
14
15 int main()
16 {
17 // set floating-point output formatting
18 cout << fixed << setprecision( 2 );
19
20 // create vector of three base-class pointers
21 vector < Employee * > employees( 3 );
22
23 // initialize vector with various kinds of Employees
24 employees[ 0 ] = new SalariedEmployee(
25 "John", "Smith", "111-11-1111", 800 );
26 employees[ 1 ] = new CommissionEmployee(
27 "Sue", "Jones", "333-33-3333", 10000, .06 );
28 employees[ 2 ] = new BasePlusCommissionEmployee(
29 "Bob", "Lewis", "444-44-4444", 5000, .04, 300 );
30
31 // polymorphically process each element in vector employees
32 for ( Employee *employeePtr : employees )
33 {
34 employeePtr->print(); // output employee information
35 cout << endl;
36
37 // attempt to downcast pointer
38 BasePlusCommissionEmployee *derivedPtr =
39 dynamic_cast < BasePlusCommissionEmployee * >( employeePtr );
40
41 // determine whether element points to a BasePlusCommissionEmployee
42 if ( derivedPtr != nullptr ) // true for "is a" relationship
43 {
44 double oldBaseSalary = derivedPtr->getBaseSalary();
45 cout << "old base salary: $" << oldBaseSalary << endl;
46 derivedPtr->setBaseSalary( 1.10 * oldBaseSalary );
47 cout << "new base salary with 10% increase is: $"
48 << derivedPtr->getBaseSalary() << endl;
49 } // end if
50
51 cout << "earned $" << employeePtr->earnings() << "
";
52 } // end for
53
54 // release objects pointed to by vector's elements
55 for ( const Employee *employeePtr : employees )
56 {
57 // output class name
58 cout << "deleting object of "
59 << typeid( *employeePtr ).name() << endl;
60
61 delete employeePtr;
62 } // end for
63 } // end main
salaried employee: John Smith
social security number: 111-11-1111
weekly salary: 800.00
earned $800.00
commission employee: Sue Jones
social security number: 333-33-3333
gross sales: 10000.00; commission rate: 0.06
earned $600.00
base-salaried commission employee: Bob Lewis
social security number: 444-44-4444
gross sales: 5000.00; commission rate: 0.04; base salary: 300.00
old base salary: $300.00
new base salary with 10% increase is: $330.00
earned $530.00
deleting object of class SalariedEmployee
deleting object of class CommissionEmployee
deleting object of class BasePlusCommissionEmployee