16.8 IMPLEMENTATION OF AN EXAMPLE IN REPEATED INHERITANCE


16.8 IMPLEMENTATION OF AN EXAMPLE IN REPEATED INHERITANCE

For an example in repeated inheritance, let's consider the hierarchy of Figure 16.13.

click to expand
Figure 16.13

Let's say that our overall goal is to figure out whether or not an employee is ready for a promotion. Let's assume that the following considerations enter into the promotion criteria:

  • Assuming that a Manager is in charge of one department, his/her performance will be judged on the basis of the following three criteria: (a) the year-to-year gain in the productivity of his/her department; (b) the satisfaction level of the employees in his/her department; and (c) the number of years in rank. (This obviously means that we will also need a Department class to keep track of the yearly productivity numbers.)

  • An ExecutiveManager will be assumed to supervise multiple departments. his/her performance will be measured by computing productivity gain numbers for all the departments under his/her supervision.

  • A SalesPerson's performance will be measured by the year-to-year change in the volume of sales and the number of years in rank.

For implementing the class hierarchy of Figure 16.13, the common base, Employee, will obviously have to be declared virtual. This fact will have to be reflected in all the downstream constructors and copy constructors, in accordance with the discussion in Sections 16.3 and 16.4 of this chapter.

We will now show a partial implementation of this hierarchy and leave it to the reader to complete it. However, before the implementation, we will show a header file containing some ancillary types that are used in the implementation. The header file contains the Department class and the enumerations needed for those data members of our classes that have specifically designated symbolic values.[1] Note that the data members of type Department will carry different meanings in different classes, and sometimes different meanings within the same class. An Employee's job will be in one specific Department (although it would be easy to change the structure of our classes so that an Employee could work in multiple departments at the same time). A Manager will be in charge of one Department. An ExecutiveManager will be in charge of multiple Departments. While a Manager will also work in the department of which he/she is in charge, a ExecutiveManager may not work in any of the departments that he/she is in charge of. Here is the header file:

 
//MI_Utilities.h #ifndef MI_UTILITIES_H #define MI_UTILITIES_H #include <iostream> #include <string> #include <vector> using namespace std; ////////////////////////// global constant ////////////////////////// //min number of years at job before promotion: const int MinYearsForPromotion = 4; /////////////////////////// enumerations //////////////////////////////// enum EducationLevel { HighSchool, enum EducationalLevel {Highschool, TradeSchool, College, CollegePlus, eUnknown }; static const string EducationLevels[] = { "highschool", "tradeschool", "college", "college plus", "unknown" }; enum PeopleSkill { Loner, Reserved, Friendly, ReachesOut, Empathizer, pUnknown }; static const string PeopleSkills[] = { "loner", "reserved", "friendly", "reaches out", "empathizer", "unknown" }; enum Leadership { CanLeadLargeGroups, CanLeadSmallGroups, NotLeader, 1Unknown }; static const string LeaderQualities[] = { "can lead large groups", "can lead only small groups", "unable to lead", "unknown" }; ///////////////////// utility class Department ////////////////////// class Department { string name; int productionLastYear; // Last year's production int productionPreviousYear; // Previous year's production // (previous means two years back) public: Department() {} Department (string nam) : name(nam) {} void setProductionLastYear(int dd){ productionLastYear = dd; } void setProductionPreviousYear(int dd) { productionPreviousYear = dd; } int getProductionLastYear() { return productionLastYear; } int getProductionPreviousYear() { return productionPreviousYear; } string getName() { return name; } void print() { cout << "Department name: " << name << endl; } }; #endif

Shown below is a partial implementation of the inheritance hierarchy of Figure 16.13. Each class is provided with a general-purpose constructor that initializes all the data members of a class. The Employee and Manager classes are also provided with one additional constructor for dealing with the situation of an ExecutiveManager or a SalesManager not belonging to any particular department.

In lines (A) and (F) of the program shown below, we declare Employee to be a virtual base of the classes Manager and SalesPerson, respectively. This creates a need for direct calls to the Employee constructor in the constructors of ExecutiveManager and SalesManager, as shown in lines (C), (D) and (H). The classes Manager, SalesPerson, and SalesManager are each provided with their own implementations for the virtual function productivityGainYtoY in lines (B), (E), and (G), respectively. Since this function is virtual, it will work polymorphically for the Manager types.

 
//RepeatInherit.cc #include "MI_Utilities.h" ////////////////////////// class Employee /////////////////////////// class Employee { protected: string name; string address; EducationLevel education; int yearsExperience; // years on job Department dept; PeopleSkill pSkill; // needed for sales positions Leadership leadership; // needed for management public: Employee(string nam, string add, EducationLevel edLevel, Department depart) name(nam), address(add), education(edLevel), yearsExperience(0), dept(depart), pSkill(pUnknown), leadership(1Unknown) {} // since senior level managers do not belong to any particular // department, the next constructor is for such employees: Employee(string nam, string add, EducationLevel edLevel) name(nam), address(add), education(edLevel), yearsExperience(0), pSkill(pUnknown), leadership(1Unknown) {} void setYearsExperience(int yy) { yearsExperience = yy; } void setPeopleSkill(PeopleSkill skill){ pSkill = skill; } string getName() const { return name; } string getAddress() const { return address; } EducationLevel getEducationLevel() const { return education; } virtual void print() { cout << name << endl; cout << address << endl; cout << EducationLevels[ education ] << endl; cout << "Years in job: " << yearsExperience << endl; cout << "People skill: " << PeopleSkills[ (int) pSkill ] << endl; cout << "Leadership quality: " << LeaderQualities[ (int) leadership ] << endl; } virtual "Employee() {} }; /////////////////////////// class Manager /////////////////////////// class Manager : virtual public Employee { //(A) Department dept; // note same name as dept in Employee // but different meaning. Here it is dept // supervised and not department worked in protected: bool employeeSatisfaction; int yearsInManagement; public: Manager(string name, string address, EducationLevel education, Department aDept) Employee (name, address, education), dept (aDept), yearsInManagement(0), employeeSatisfaction(false) {} // Since senior-level managers do not belong to any particular // department, the next constructor is actually for them Manager (string name, string address, EducationLevel education) : Employee(name, address, education) {} virtual double productivityGainYtoY() { //(B) int lastProd = dept.getProductionLastYear(); int prevProd = dept.getProductionPreviousYear(); return 100 * (lastProd-prevProd) / (double) prevProd; } void setDepartment(Department dept){ this->dept = dept; } int getYearsInManagement() { return yearsInManagement; } void setYearsInManagement(int y) { yearsInManagement = y; } bool getEmployeeSatisfaction() { return employeeSatisfaction; } void setEmployeeSatisfaction(bool satis) { employeeSatisfaction = satis; } virtual bool readyForPromotion(){ return ( (yearsInManagement >= MinYearsForPromotion) ? true : false) && (productivityGainYtoY() > 10) && employeeSatisfaction; } void print() { Employee::print(); dept.print(); } ~Manager(){} }; ////////////////////// class ExecutiveManager /////////////////////// // An ExecutiveManager supervises more than one department class ExecutiveManager : public Manager { short level; vector<Department> departments; // depts in charge of public: // no-arg const. needed in the second example for type conversion // from Manager to ExecutiveManager: ExecutiveManager() : Manager("", "", eUnknown), Employee("", "", eUnknown), //(C) level (0) {} ExecutiveManager(string name, string address, EducationLevel education, short level) : Manager(name, address, education), Employee(name, address, education), //(D) level(level) { departments = vector<Department>(); } void addDepartment (Department dept) {departments.push_back(dept);} void setLevel(int 1v1) { level = 1v1; } // overrides Manager's productivityGainYtoY() : double productivityGainYtoY() { //(E) double gain = 0.0; vector<Department>::iterator iter = departments.begin(); while (iter != departments.end() ) { int lastProd = iter->getProductionLastYear(); int prevProd = iter->getProductionPreviousYear() ; gain += (lastProd-prevProd) / prevProd; } return gain/departments.size(); } void print() { Employee:: print(); cout << "Departments supervised: " << endl; vector<Department>::iterator iter = departments.begin(); while (iter != departments.end() ) iter++->print(); } "ExecutiveManager(){} }; ///////////////////////// class SalesPerson ///////////////////////// class SalesPerson : virtual public Employee { //(F) int salesLastYear; int salesPreviousYear; protected: int yearsInSales; public: SalesPerson(string name, string address, EducationLevel education) : Employee(name, address, education, Department("Sales")), salesLastYear(0), salesPreviousYear(0), yearsInSales(0) {} int getSalesLastYear() { return salesLastYear; } void setSalesLastYear(int sales) { salesLastYear = sales; } int getSalesPreviousYear() { return salesPreviousYear; } void setSalesPreviousYear(int sales) { salesPreviousYear = sales; } int getYearsInSales() { return yearsInSales; } void setYearsInSales(int y) { yearsInSales = y; } virtual double productivityGainYtoY() { //(G) return 100 * (salesLastYear - salesPreviousYear) / (double) salesPreviousYear; } virtual bool readyForPromotion(){ return ( (yearsInSales >= MinYearsForPromotion) ? true : false) && (productivityGainYtoY() > 10); } ~SalesPerson(){} }; //////////////////////// class SalesManager ///////////////////////// class SalesManager : public SalesPerson, public Manager { int yearInSalesManagement; vector<SalesPerson> sellersSupervised; public: SalesManager(string name, string address, EducationLevel education) : Manager(name, address, education), SalesPerson(name, address, education), Employee(name, address, education) {} //(H) double productivityGainYtoY(){ return 0; // left for the reader to complete } ~SalesManager(){} }; /////////////////////////////// main //////////////////////////////// int main() { Department d1("Design"); d1.setProductionLastYear(110001); // for last year d1.setProductionPreviousYear(100000); // for two years back Manager manager1("Miz Importante", "UptownUSA", College, d1); //(I) manager1.setYearsInManagement(8); manager1.setEmployeeSatisfaction(true); if ( manager1.readyForPromotion() ) { cout << manager1.getName() << " " << "is ready for promotion." << endl; } else { cout << manager1.getName() << " " << "is not ready for promotion." << endl << endl; } Department d2("Manufacturing"); Department d3("Development"); SalesPerson salesman("Joe Seller", "DowntownUSA", College); //(J) salesman.setYearsInSales(5); salesman.setSalesPreviousYear(100); salesman.setSalesLastYear(100); if ( salesman.readyForPromotion() ) { cout << salesman.getName() << " " << "is ready for promotion." << endl; } else { cout << salesman.getName() << " " << "is not ready for promotion." << endl; } ExecutiveManager bigshot("Zushock Zinger", //(K) "MainstreetUSA", CollegePlus, 4); bigshot.addDepartment(d1); bigshot.addDepartment(d2); bigshot.addDepartment(d3); bigshot.print(); //(L) return 0; }

Line (I) of main defines a Manager whose name is Miz Importante and line (J) defines an SalesPerson of name Joe Seller. With regard to whether or not these individuals are ready for promotion, the program produces the output shown below. The output also shows the state of the bigshot object created in line (K).

      Miz Importante is ready for promotion.      Joe Seller is not ready for promotion.      Zushock Zinger          // output produced by line (L)      MainstreetUSA      college plus      Years in job: 0      People skill: unknown      Leadership quality: unknown      Departments supervised:      Department name: Design      Department name: Manufacturing      Department name: Development 

[1]Placing this information in a separate header will allow us to use the same header in the next two sections of this chapter.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net