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
Account::describe()explicitly calls the base version, even thoughdescribeis virtual. Without theAccount::prefix, the override would call itself forever.add_interestchangesbalance_directly, which is allowed because it'sprotected.owner_isprivate, soSavingscouldn't touch it.using Account::Account;inherits the base constructors, soSavings s("Mia")works without writing a constructor.
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 turn: finish Medic. Its describe() returns the base description plus " +heal", and heal(Unit& u) restores u by the protected power_ amount (use u.restore(...)).
Previous: Virtual destructors Next: Composition over inheritance