20-CS-122-001 Computer Science II Spring 2012
Inheritance: Employee Data Base

Virtual functions, classes, inheritance, lists, queues, stacks, applications

Prev      Next      Lectures      Java version      Source

// Virtual Functions and Multiple Inheritance
// EmployeeList class is not orthogonal to any Employee class.

#include <stdlib.h>
#include <iostream>
#include <string.h>
using namespace std;

class Cell {
 friend class List;
   
   void *data;
   Cell *next;
   
 public:
   Cell (void *dat, Cell *nxt) {
      data = dat;
      next = nxt;
   }
};

class List {
 protected:
   Cell *head;
   Cell *tail;

   Cell *next(Cell *current) { return current->next; }

   void *objectOf(Cell *cell) { return cell->data; }

 public:
   List () { head = tail = NULL; }
   
   void enqueue (void *t) { 
      if (head == NULL) {
         head = tail = new Cell(t, NULL);
         return;
      }
      tail->next = new Cell(t, NULL);      
      tail = tail->next;
   }
};

class Employee {
   char name[30];
   
 public:
   Employee() {}
   
   Employee (const char *nm) { strcpy(name,nm); }
   
   char *getName() { return name; }
   
// computePay() const { return 0; }               // normal function
   
// virtual float computePay() const { return 0; } // virtual
   virtual float computePay() const = 0;          // pure virtual
   
   virtual void display () {}
   
   virtual void setHours(float hrs) {}
   
   virtual void setSales(float sales) {}
   
   virtual void setSalary(float salary) { cout << "NO!\n"; }
};

class EmployeeList : public List {
 public:
   EmployeeList() : List () { }

   void setHours(char *name, int hrs) {
      for (Cell *f = head ; f != NULL ; f = next(f)) {
         if (!strcmp(((Employee *)(objectOf(f)))->getName(), name)) {
            ((Employee *)(objectOf(f)))->setHours(hrs);
            break;
         }
      }
   }

   void setSalary(char *name, float salary) {
      for (Cell *f = head ; f != NULL ; f = next(f)) {
         if (!strcmp(((Employee *)(objectOf(f)))->getName(), name)) {
            ((Employee *)(objectOf(f)))->setSalary(salary);
            break;
         }
      }
   }

   void setSales(char *name, float sales) {
      for (Cell *f = head ; f != NULL ; f = next(f)) {
         if (!strcmp(((Employee *)(objectOf(f)))->getName(), name)) {
            ((Employee *)(objectOf(f)))->setSales(sales);
            break;
         }
      }
   }

   float payroll() {
      float total=0;

      for (Cell *f = head ; f != NULL ; f = next(f))
         total += ((Employee *)(objectOf(f)))->computePay();
      return total;
   }

   void display() {
      for (Cell *f = head ; f != NULL ; f = next(f))
         ((Employee *)(objectOf(f)))->display();
      cout << "\n";
   }
};

class WageEmployee : public Employee {
   float rate;
   float hours;

 public:
   WageEmployee(const char *nm) : Employee(nm) {}
   
   WageEmployee(const char *nm, float r) : Employee(nm) { rate = r; }
   
   void setRate(float r)    { rate  = r; }
   
   void setHours(float hrs) { hours = hrs; }
   
   float getHours()         { return hours; }
   
   float getRate()          { return rate; }
   
   float computePay() const { return rate*hours; }
};

class Programmer : public WageEmployee {
 public:
   Programmer (const char *nm, float w) : WageEmployee(nm, w) { }
   void display() {
      cout << "Programmer Name: "   << Employee::getName()
           << "\tHours: " << WageEmployee::getHours()
           << "\tRate: "  << WageEmployee::getRate() << "\n";
   }
};

class SalesPerson : public WageEmployee {
   float commission;
   float SalesMade;
   
 public:
   SalesPerson (const char *nm, float c) : WageEmployee (nm) {
      commission = c;
   }
   
   void setCommission(float comm) { commission = comm; }
   
   void setSales(float sales) { SalesMade = sales; }
   
   float computePay() const { return commission*SalesMade; }
   
   void display() {
      cout << "Salesperson Name: " << Employee::getName()
           << "\tCommission: " << commission
           << "\tSales: "      << SalesMade << "\n";
   }
};

class Manager : public Employee {
   float monthlysalary;
   
public:
   Manager (const char *nm) : Employee (nm) { }
   
   Manager(const char *nm, float w) : Employee(nm) { monthlysalary = w; }
   
   void setSalary(float salary) { cout << "HEY!\n"; monthlysalary = salary; }
   
   float computePay() const     { return monthlysalary; }
   
   void display() {
      cout << "Manager Name: " << Employee::getName()
           << "\tMonthly Salary: " << monthlysalary << '\n';
   }
};

// Multiple Inheritance
class SalesManager : public SalesPerson, public Manager {
public:
   SalesManager(const char *nm, float w) : SalesPerson(nm, w), Manager (nm) {}
   
   float computePay() const {  // A must or else computePay() ambiguous
      return SalesPerson::computePay() + Manager::computePay();
   }
   
   void display() {
      SalesPerson::display();
      Manager::display();
   }
};

int main() {
   char *month[] = { "January", "February", "March", "April", "May", "June",
                     "July", "August", "September", "October", "November",
                     "December" };

   EmployeeList *emp = new EmployeeList();
   emp->enqueue(new SalesManager("Gee", 1000));
   emp->enqueue(new SalesManager("Gal", 1000));
   emp->enqueue(new SalesManager("Gem", 1000));
   emp->enqueue(new SalesPerson("John", 0.03));
   emp->enqueue(new SalesPerson("Joan", 0.04));
   emp->enqueue(new SalesPerson("Jack", 0.02));
   emp->enqueue(new Manager("Fred", 10000));
   emp->enqueue(new Manager("Frank", 5000));
   emp->enqueue(new Manager("Florence", 3000));
   emp->enqueue(new Programmer("Linda", 7));
   emp->enqueue(new Programmer("Larry", 5));
   emp->enqueue(new Programmer("Lewis", 3));

   emp->setHours("Linda", 35);
   emp->setHours("Larry", 23);
   emp->setHours("Lewis", 3);
   emp->setSales("John", 12000);
   emp->setSales("Joan", 10000);
   emp->setSales("Jack", 5000);
   emp->setSales("Gee", 4000);
   emp->setSales("Gal", 3000);
   emp->setSales("Gem", 2000);
   emp->setSalary("Gee", 1000);
   emp->setSalary("Gal", 2000);
   emp->setSalary("Gem", 3000);
   emp->display();
   cout << "Payroll: " << emp->payroll() << "\n";
}

// Sample Output
//   NO!
//   NO!
//   NO!
//   Salesperson Name: Gee   Commission: 1000        Sales: 4000
//   Manager Name: Gee       Monthly Salary: 5.60519e-45
//   Salesperson Name: Gal   Commission: 1000        Sales: 3000
//   Manager Name: Gal       Monthly Salary: 0
//   Salesperson Name: Gem   Commission: 1000        Sales: 2000
//   Manager Name: Gem       Monthly Salary: 2.24936e-40
//   Salesperson Name: John  Commission: 0.03        Sales: 12000
//   Salesperson Name: Joan  Commission: 0.04        Sales: 10000
//   Salesperson Name: Jack  Commission: 0.02        Sales: 5000
//   Manager Name: Fred      Monthly Salary: 10000
//   Manager Name: Frank     Monthly Salary: 5000
//   Manager Name: Florence  Monthly Salary: 3000
//   Programmer Name: Linda  Hours: 35       Rate: 7
//   Programmer Name: Larry  Hours: 23       Rate: 5
//   Programmer Name: Lewis  Hours: 3        Rate: 3