C/C++ Arena

Step 6 of 9

Calling the base version, and protected

An override often wants to extend the base behavior rather than replace it: do what the base did, then add something. Call the base version by naming its class with ::.

#include <iostream>
#include <string>
#include <utility>

class Account {
public:
    explicit Account(std::string owner) : owner_(std::move(owner)) {}
    virtual ~Account() = default;
    virtual std::string describe() const { return owner_ + ": " + std::to_string(balance_); }
    void deposit(int amount) { balance_ += amount; }

protected:
    int balance_ = 0;          // derived classes may use this directly

private:
    std::string owner_;
};

class Savings : public Account {
public:
    using Account::Account;    // reuse the base constructors
    std::string describe() const override { return Account::describe() + " (savings)"; }
    void add_interest() { balance_ += balance_ * rate_ / 100; }

private:
    int rate_ = 5;
};

int main() {
    Savings s("Mia");
    s.deposit(200);
    s.add_interest();
    std::cout << s.describe() << "\n";
}
Mia: 210 (savings)

How it works

Access levels, one more time

Keyword Who can use it
public everyone
protected the class and classes derived from it
private only the class itself

Use protected sparingly. Every protected member is part of the contract with all future subclasses, so it's as hard to change later as a public one.

Your task

In Medic, describe() calls Unit::describe() and appends " +heal". heal(Unit& u) calls the public u.restore(power_). power_ is protected, so the Medic can read it.

Your task

Finish Medic. Its describe() returns the base description plus " +heal", and heal(Unit& u) restores u by the protected power_ amount (use u.restore(...)).

Challenge 2

Finish Sniper. toggle_scope() flips scoped_ and doubles the protected damage_ when scoping in (halves it when scoping out). describe() returns the base description, plus " [scoped]" while scoped. Reuse Weapon::describe().

Challenge 3

SavingsAccount allows only 3 withdrawals. Override withdraw: once 3 have succeeded, return false; otherwise let Account::withdraw do the real work, and only count the withdrawal if it succeeded.

Previous: Virtual destructors Next: Composition over inheritance