Da trilha de C++ Este conceito ainda não saiu como card do dia. ir para o card de hoje

C++ POO Intermediário

Herança e virtual

A herança permite criar classes que reutilizam e estendem o comportamento de outra classe. Em C++, usamos herança pública para expressar a relação "é um": a classe derivada herda os membros públicos e protegidos da classe base. Métodos marcados como virtual podem ser sobrescritos na classe derivada, e a chamada é resolvida em tempo de execução (polimorfismo dinâmico). As palavras-chave override e final ajudam a evitar erros: override garante que você está realmente sobrescrevendo um método virtual, e final impede que a classe ou o método seja herdado/sobrescrito. Além disso, quando uma classe base possui métodos virtuais, seu destrutor também deve ser virtual para garantir que o destrutor correto seja chamado ao deletar um objeto via ponteiro para a base.

Pontos-chave

  • Herança pública (class Derivada : public Base) estabelece a relação "é um" e mantém a acessibilidade dos membros.
  • Métodos virtuais permitem polimorfismo: a implementação chamada depende do tipo dinâmico do objeto.
  • override verifica em tempo de compilação se o método realmente sobrescreve um virtual da base.
  • final impede que uma classe seja herdada ou que um método virtual seja sobrescrito.
  • Se a classe base tem métodos virtuais, o destrutor deve ser virtual para evitar vazamentos ao deletar via ponteiro para a base.
heranca_virtual.cpp
#include <iostream>
#include <memory>
#include <vector>

class Animal {
public:
    virtual void falar() const {
        std::cout << "Animal faz som\n";
    }
    virtual ~Animal() = default; // destrutor virtual
};

class Cachorro : public Animal {
public:
    void falar() const override {
        std::cout << "Cachorro late\n";
    }
};

class Gato final : public Animal {
public:
    void falar() const override {
        std::cout << "Gato mia\n";
    }
};

int main() {
    std::vector<std::unique_ptr<Animal>> animais;
    animais.push_back(std::make_unique<Cachorro>());
    animais.push_back(std::make_unique<Gato>());
    animais.push_back(std::make_unique<Animal>());

    for (const auto& a : animais) {
        a->falar(); // chamada polimórfica
    }
    return 0;
}

Exercícios

  1. 1
    Fácil

    Formas geométricas

    Crie uma classe base Forma com um método virtual area() que retorna 0.0. Depois, crie as classes Retangulo e Circulo que herdam publicamente de Forma e sobrescrevem area() com override. No main, crie um std::vector<std::unique_ptr<Forma>> com uma instância de cada e imprima a área de cada uma usando polimorfismo.

    Resolver
  2. 2
    Médio

    Funcionários e bônus

    Crie uma hierarquia de classes para representar funcionários. A classe base Funcionario deve ter um método virtual calcularBonus() const que retorna 0.0 e um método nome() const que retorna o nome. As classes Gerente e Desenvolvedor herdam de Funcionario e sobrescrevem calcularBonus(): Gerente recebe 20% do salário base, Desenvolvedor recebe 10%. Use override e garanta que o destrutor seja virtual. No main, crie um vetor de std::unique_ptr<Funcionario>, adicione um gerente e um desenvolvedor, e imprima o nome e o bônus de cada um.

    Resolver
  3. 3
    Desafio

    Instrumentos musicais com final

    Crie uma hierarquia de instrumentos musicais. A classe base abstrata Instrumento deve ter um método virtual puro tocar() const e um destrutor virtual. As classes Corda e Sopro herdam de Instrumento e implementam tocar(). A classe Violao herda de Corda e sobrescreve tocar(). A classe Flauta herda de Sopro e é marcada como final, impedindo herança adicional. No main, crie um vetor de std::unique_ptr<Instrumento>, adicione um Violao e uma Flauta, e chame tocar() para cada um. Além disso, tente (comentado) criar uma classe que herde de Flauta para ver o erro de compilação.

    Resolver

Continue estudando