C/C++ Arena

Step 3 of 9

Abstract classes

Sometimes the base class can't give a sensible default. What's the area of "a shape"? There isn't one: only circles, squares and triangles have areas. So the base declares the function but provides no body, by writing = 0. That's a pure virtual function.

A class with at least one pure virtual function is abstract: you can't create an object of it, only of classes derived from it that implement every pure virtual function. An abstract class with only pure virtual functions is an interface: a promise of what every derived class can do.

#include <iostream>
#include <string>

class Payment {
public:
    virtual double fee(double amount) const = 0;      // no body: must be overridden
    virtual std::string name() const = 0;
    virtual ~Payment() = default;
};

class Card : public Payment {
public:
    double fee(double amount) const override { return 0.30 + amount * 0.029; }
    std::string name() const override { return "card"; }
};

class Transfer : public Payment {
public:
    double fee(double) const override { return 1.0; }  // flat fee; parameter unused
    std::string name() const override { return "transfer"; }
};

void quote(const Payment& p, double amount) {
    std::cout << p.name() << ": " << p.fee(amount) << "\n";
}

int main() {
    quote(Card{}, 100);
    quote(Transfer{}, 100);
    // Payment p;   // error: cannot declare variable 'p' to be of abstract type
}
card: 3.2
transfer: 1

How it works

Your task

Each shape stores its own dimensions and implements area(): a circle is pi times r squared, a rectangle is width times height. Remember const and override, and use the value of pi given.

Your task

Write Circle (radius) and Rect (width, height) implementing area(). Use 3.14159265358979 for pi.

Challenge 2

Add Triangle(base, height) and Square(side), implementing both pure virtual functions (area() and name() returning "triangle" or "square"). Then write std::string largest(const std::vector<const Shape*>& shapes) returning the name of the shape with the biggest area (the first one on a tie, "" for none).

Challenge 3

An abstract class can still have ordinary functions that call the pure virtual ones. Account::withdraw_cost uses fee. Write Basic, whose fee is 2% of the amount, and Premium, whose fee is 0 up to 1000 and 1 above that.

Previous: virtual and override Next: Polymorphic containers