Example Inheritance Implementing an employee hierarchy We are











- Slides: 11

Example: Inheritance

Implementing an employee hierarchy • We are building a program that deals with people employed by a firm; to keep things simple: • The firm keeps track each employee’s first name and last name • Some employees are paid hourly • Other are salaried Employee Hourly. Employee Salaried. Employee

Implementing an employee hierarchy (c 1) • A naïve implementation might represent these employees using the following data structures: struct Hourly. Employee { std: : string first_name, last_name; double hourly_wage; }; struct Salaried. Employee { std: : string first_name, last_name; double annual_salary; };

Implementing an employee hierarchy (c 2) • Recognizing that the firm tracks the first name and family name of both Hourly. Employees and Salaried. Employees, we might try this: struct Employee { std: : string first_name, last_name; }; struct Hourly. Employee { Employee emp; double hourly_wage; }; struct Salaried. Employee { Employee emp double annual_salary; };

Implementing an employee hierarchy struct Employee { std: : string first_name, last_name; }; struct Hourly. Employee { Employee emp; double hourly_wage; }; struct Salaried. Employee { Employee emp double annual_salary; }; • This implementation stores the common Employee data in the emp member (of Employee type) of an Hourly. Employee or Salaried. Employee object

Implementing an employee hierarchy Employee Hourly. Employee Salaried. Employee • This implementation stores the common Employee data in the emp member (of Employee type) of an Hourly. Employee or Salaried. Employee object • However, there is nothing that tells the compiler that an Hourly. Employee is an Employee and that Salaried. Employee is

Implementing an employee hierarchy • There is nothing that tells the compiler that an Hourly. Employee is an Employee and that Salaried. Employee is also an Employee • Accordingly, we couldn’t store the firm’s employees in single list, e. g. a vector<Employee*> or array. • This is because, to the compiler, an Hourly. Employee* is not an Employee* [and] an Salaried. Employee* is not an Employee*

Implementing an employee hierarchy • A derived class inherits properties from its base, so the relationship is called inheritance • A derived class is therefore larger than its base class in the sense that it holds more data and provides more functions

Implementing an employee hierarchy • Deriving Hourly. Employee and Salaried. Employee this way makes them both subtypes of Employee • Each can be used whenever an Employee is acceptable as they share the “common base”:

Implementing an employee hierarchy (c 4) • We can now create a vector<Employee*> and add Hourly. Employee* and Salaried. Employee* to it • We can do this because each of those objects is guaranteed to have that “common base”; • If we push_back an Hourly. Employee* to an vector<Employee*>, Hourly. Employee* will be implicitly converted to an Employee* • This means that the object being pointed to will be interpreted as an Employee object, giving us access only to the public members of that “common base”

Implementing an employee hierarchy (c 5) • Why are we using a vector<Employee*> instead of a vector<Employee>? Pointers and references opposed to vector<Employee*> ptrs_to_emps; vector<Employee> emps; variables? Hourly. Employee* he_ptr = &he; emps. push_back(he); ptrs_to_emps. push_back(he_ptr); ptrs_to_emps. push_back(&sh); for (auto e : ptrs_to_emps) cout << 't' << e->first_name << ' ' << e->last_name << endl; push_back makes a copy of the object being and places that copy in the vector. If that object is an Hourly. Employee*, then the pointer object will be implicitly converted to type Employee*. What this means the memory space being pointed to will be interpreted as that of an Employee opposed to that of an Hourly. Employee… emps. push_back(sh); for (auto e : emps) cout << 't' << e. first_name << ' ' << e. last_name << endl; push_back makes a copy of the object being and places that copy in the vector. If that object is an Hourly. Employee, then the object will be implicitly converted to an object of type Employee. What this means is that only the common base will be preserved in that object. . . That is, only the Employee part of the Hourly. Employee will be preserved… this is commonly referred to as splicing…