AnyCompiler

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;
}
Output
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().