Step 2 of 9
virtual and override
Inheritance becomes powerful when code works with the base type but each object behaves according to its real type. A function that takes const Animal& should make a Dog bark and a Cat meow. That's polymorphism ("many forms").
By default, C++ doesn't do this: through a base reference, the base version of a function runs. Marking the function virtual changes that: the call is decided at run time, by the actual object.
#include <iostream>
#include <string>
class Notifier {
public:
virtual std::string send(const std::string& msg) const { return "log: " + msg; }
std::string channel() const { return "base"; } // not virtual
virtual ~Notifier() = default;
};
class Email : public Notifier {
public:
std::string send(const std::string& msg) const override { return "email: " + msg; }
std::string channel() const { return "smtp"; } // hides, doesn't override
};
class Sms : public Notifier {
public:
std::string send(const std::string& msg) const override { return "sms: " + msg.substr(0, 5); }
};
void alert(const Notifier& n) {
std::cout << n.send("server down") << " via " << n.channel() << "\n";
}
int main() {
alert(Notifier{});
alert(Email{});
alert(Sms{});
}
log: server down via base
email: server down via base
sms: serve via base
Reading the output
sendisvirtual, soalertcalls the real object's version: log, email and sms.channelis not virtual, so through aNotifier&it's always the base version, even for anEmail. That's almost never what you want in a class hierarchy.
override
Write override after every function that's meant to replace a virtual one. The compiler then checks that a matching virtual function exists in the base. Without it, a typo or a missing const silently creates a brand new function, and the base version keeps running. With it, that's a compile error.
virtual ~Base() = default
A class meant to be used through base references or pointers needs a virtual destructor. You'll see exactly why in step 5; for now, always include it.
Your turn: make Knife and Grenade override attack, returning "slash" and "boom".