Inheritance e Polymorphism
Uma class pode herdar de outra com : public Base. Marcar um method da base class como virtual, e a versão da derived class como override, diz ao compilador para despachar dinamicamente: quando você chama o method através de um pointer ou reference à base class, a versão do tipo real em tempo de execução roda — não necessariamente a que o tipo estático sugeriria.
#include <iostream>
#include <string>
using namespace std;
class Animal {
public:
virtual string speak() const {
return "...";
}
};
class Dog : public Animal {
public:
string speak() const override {
return "Woof!";
}
};
class Cat : public Animal {
public:
string speak() const override {
return "Meow!";
}
};
int main() {
Dog dog;
Cat cat;
Animal* animals[2] = { &dog, &cat };
for (int i = 0; i < 2; i++) {
cout << animals[i]->speak() << endl;
}
return 0;
}Woof! Meow!
animals é um array de Animal* — um pointer à base class de tipagem estática — mas cada elemento ainda chama o speak() correto da sua derived class. Sem virtual, ambas as chamadas imprimiriam '...' em vez disso, já que o compilador resolveria a chamada estaticamente contra o tipo Animal declarado em vez de despachar em tempo de execução.
A seguir: operator overloading — dar aos seus próprios types a mesma sintaxe +, -, == que os types embutidos já têm.
Practice exercise
Defina uma class Shape com um virtual method name() que retorne "Shape". Defina uma class Circle que herde de Shape e faça override de name() para retornar "Circle". Crie um Circle através de um Shape* pointer e imprima seu name().