C++: A payment interface

Code that only needs to know what something can do should depend on an interface, not on a particular class.

What to build

A Payment interface with three payment methods that each charge their own fee.

Requirements

  • Make Payment an interface: pure virtual functions and a virtual destructor only.
  • Write Card, Mobile and Cash, each overriding name() and fee().
  • Handle every payment through a Payment*, and delete each object after use.

Input

The first line has q. Each of the next q lines has a method (card, mobile or cash) and an amount.

Output

One line per payment: METHOD: AMOUNT + FEE = TOTAL.

Constraints

1 ≤ q ≤ 100, and each amount is a whole number from 0 to 1000000.

Example

Input:

3
card 1000
mobile 1000
cash 500

Output:

card: 1000 + 20 = 1020
mobile: 1000 + 15 = 1015
cash: 500 + 0 = 500

Why it works

The printing code calls name() and fee() through the interface and never needs to know which method it has. A new method can be added as a new class without changing that code.

Examples

Example 1 · Input
3
card 1000
mobile 1000
cash 500
Expected output
card: 1000 + 20 = 1020
mobile: 1000 + 15 = 1015
cash: 500 + 0 = 500
Example 2 · Input
1
card 49
Expected output
card: 49 + 0 = 49

Hints

Hint 1

`Payment` has only pure virtual functions, `name()` and `fee(int amount)`, and a virtual destructor.

Hint 2

Write a function that takes the method's name and returns `new Card()`, `new Mobile()` or `new Cash()` as a `Payment*`.

Hint 3

Card: 2% of the amount. Mobile: 5 plus 1% of the amount. Cash: nothing. All rounded down.

Solution

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

class Payment {
public:
    virtual ~Payment() {}
    virtual string name() const = 0;
    virtual int fee(int amount) const = 0;
};

class Card : public Payment {
public:
    string name() const override { return "card"; }
    int fee(int amount) const override { return amount * 2 / 100; }
};

class Mobile : public Payment {
public:
    string name() const override { return "mobile"; }
    int fee(int amount) const override { return 5 + amount / 100; }
};

class Cash : public Payment {
public:
    string name() const override { return "cash"; }
    int fee(int) const override { return 0; }
};

Payment* make(const string& method) {
    if (method == "card") return new Card();
    if (method == "mobile") return new Mobile();
    return new Cash();
}

int main() {
    int q;
    cin >> q;
    while (q-- > 0) {
        string method;
        int amount;
        cin >> method >> amount;
        Payment* p = make(method);
        int f = p->fee(amount);
        cout << p->name() << ": " << amount << " + " << f << " = " << amount + f << endl;
        delete p;
    }
    return 0;
}

Lesson: Abstract classes and interfaces →