Programação Orientada a Objetos em C++¶
C++ oferece polimorfismo de runtime por herança e funções virtuais, além de polimorfismo por valor e em compilação. Escolha conforme substituição e posse exigidas.
Interface de runtime¶
class shape {
public:
virtual ~shape() = default;
[[nodiscard]] virtual double area() const = 0;
};
class circle final : public shape {
public:
explicit circle(double radius) : radius_{radius} {
if (!(radius >= 0.0)) throw std::invalid_argument{"invalid radius"};
}
[[nodiscard]] double area() const override {
return std::numbers::pi * radius_ * radius_;
}
private:
double radius_;
};
O destrutor virtual torna segura a exclusão por ponteiro base. override pede
verificação do override; final impede derivação adicional.
Substituibilidade¶
Herança pública normalmente significa “é substituível por”, não apenas “reutiliza código”. O derivado preserva entradas, saídas, invariantes, falhas, complexidade e vida útil do contrato base.
Herança protegida acopla internals. Prefira composição quando só precisar do comportamento.
Slicing de objetos¶
Passar ou armazenar derivado por valor base copia somente o subobjeto base:
void inspect(shape value); // impossible here because shape is abstract;
// a concrete base would slice derived state
Objetos polimórficos normalmente são acessados por referências ou smart pointers proprietários.
Herança múltipla¶
Pode combinar interfaces puras independentes. Bases de implementação introduzem ambiguidade, construção complexa e diamantes. Herança virtual resolve um problema específico de base compartilhada, mas aumenta complexidade.
Polimorfismo estático¶
Templates e concepts não exigem base em runtime, favorecem otimização e valores, mas podem aumentar compilação, binário e diagnósticos. Resolvem problemas distintos.
Erros comuns¶
- destrutor não virtual em base polimórfica com exclusão proprietária;
- esquecer
overridee criar overload; - herança apenas para reutilização;
- cópia por valor base;
- ponteiros crus proprietários sem responsabilidade clara;
- esperar despacho derivado durante construção da base.
Exercícios¶
- Refatore herança usada apenas para reutilizar helper.
- Explique quando
std::varianté preferível a hierarquia virtual aberta. - Declare a posse de
std::vector<std::unique_ptr<shape>>.