C++: A payroll with three kinds of pay

A payroll is the textbook case for polymorphism: one loop, many ways of working out pay.

What to build

An Employee hierarchy with salaried, hourly and commission employees, processed through base-class pointers.

Requirements

  • S NAME SALARY: pay is the salary.
  • H NAME HOURS RATE: pay is hours × rate, with hours over 40 paid at 1.5 times the rate, rounded down.
  • C NAME BASE SALES PERCENT: pay is base + sales × percent / 100, rounded down.
  • Store all the employees as Employee* in one vector, print each pay through a virtual call, then the total, and delete every object.

Input

The first line has n. Each of the next n lines describes one employee.

Output

One line per employee, NAME PAY, then total T.

Constraints

1 ≤ n ≤ 100, and all numbers are whole and from 0 to 100000.

Example

Input:

3
S Asha 30000
H Bilal 45 200
C Chen 10000 50000 10

Output:

Asha 30000
Bilal 9500
Chen 15000
total 54500

Why it works

The loop only knows it has an Employee*, and the virtual pay() runs the rule for the real kind of employee. Adding a new kind of employee needs a new class but no change to the loop.

Examples

Example 1 · Input
3
S Asha 30000
H Bilal 45 200
C Chen 10000 50000 10
Expected output
Asha 30000
Bilal 9500
Chen 15000
total 54500
Example 2 · Input
1
H X 40 100
Expected output
X 4000
total 4000

Hints

Hint 1

Give `Employee` a name and a pure virtual `int pay() const`. Each kind of employee overrides it.

Hint 2

Hourly overtime: hours above 40 are paid at one and a half times the rate, so that part is `(hours - 40) * rate * 3 / 2`.

Hint 3

Keep everyone in a `vector<Employee*>`, add up the pay in one loop, and delete them all at the end.

Solution

Show one correct solution (try it yourself first)
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Employee {
protected:
    string name;
public:
    Employee(string n) : name(n) {}
    virtual ~Employee() {}
    string getName() const { return name; }
    virtual int pay() const = 0;
};

class Salaried : public Employee {
    int salary;
public:
    Salaried(string n, int s) : Employee(n), salary(s) {}
    int pay() const override { return salary; }
};

class Hourly : public Employee {
    int hours, rate;
public:
    Hourly(string n, int h, int r) : Employee(n), hours(h), rate(r) {}
    int pay() const override {
        if (hours <= 40) return hours * rate;
        return 40 * rate + (hours - 40) * rate * 3 / 2;
    }
};

class Commission : public Employee {
    int base, sales, percent;
public:
    Commission(string n, int b, int s, int p) : Employee(n), base(b), sales(s), percent(p) {}
    int pay() const override { return base + sales * percent / 100; }
};

int main() {
    int n;
    cin >> n;
    vector<Employee*> staff;
    for (int i = 0; i < n; i++) {
        string kind, name;
        cin >> kind >> name;
        if (kind == "S") {
            int s;
            cin >> s;
            staff.push_back(new Salaried(name, s));
        } else if (kind == "H") {
            int h, r;
            cin >> h >> r;
            staff.push_back(new Hourly(name, h, r));
        } else {
            int b, s, p;
            cin >> b >> s >> p;
            staff.push_back(new Commission(name, b, s, p));
        }
    }
    long long total = 0;
    for (Employee* e : staff) {
        cout << e->getName() << " " << e->pay() << endl;
        total += e->pay();
    }
    cout << "total " << total << endl;
    for (Employee* e : staff) delete e;
    return 0;
}

Lesson: Virtual functions and polymorphism →