Employee Payroll Solution

(see also the comparable Java Solution)

//  Virtual Functions and Multiple Inheritance

#include < stdlib.h >
#include < iostream.h >
#include < string.h >

class Cell
{
public:
   Cell (void *dat, Cell *nxt)
   {
      data = dat;
      next = nxt;
   }
   void setNext(Cell *n) { next = n; }
   Cell *getNext() { return next; }
   void *objectOf() { return data; }
private:
   void *data;
   Cell *next;
};

class List
{
public:
   List () { head = tail = NULL; }
   void enqueue (void *t)
   { 
      if (head == NULL)
      {
         head = tail = new Cell(t, NULL);
         return;
      }
      tail->setNext(new Cell(t, NULL));
      tail = tail->getNext();
   }
   Cell *getHead() { return head; }
private:
   Cell *head;
   Cell *tail;
};

class Employee
{
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) {}
private:
   char name[30];
};

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

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

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

   float payroll()
   {
      float total=0;

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

   void display()
   {
      for (Cell *f = getHead() ; f != NULL ; f = f->getNext())
         ((Employee *)(f->objectOf()))->display();
      cout << "\n";
   }
private:
};

class WageEmployee : public Employee
{
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; }
private:
   float rate;
   float hours;
};

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

class SalesPerson : public WageEmployee
{
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 << "Name: "        << Employee::getName()
           << "\tCommission: " << commission
           << "\tSales: "      << SalesMade << "\n";
   }
private:
   float commission;
   float SalesMade;
};

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

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

void main()
{
   EmployeeList *emp = new EmployeeList();
   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->display();
   cout << "Payroll: " << emp->payroll() << "\n";

}