Polimorfismo em C++ e tabelas de ponteiros para função em C
Nesta lição, você vai chamar a mesma operação em vários tipos de objeto com funções virtuais em C++ e ponteiros para função em C.
Introdução
O polimorfismo dinâmico (dynamic polymorphism) permite que o código chame uma operação comum, como calcular a área, enquanto cada tipo de objeto decide como fazer isso. C++ oferece isso diretamente com funções virtuais (virtual functions), e em C dá para imitar com ponteiros para função.
Pontos importantes
- Entenda como se faz em C antes de aprender as abstrações de C++.
- Use RAII e semântica de valor (value semantics) para expressar a posse dos recursos.
- Prefira as ferramentas com segurança de tipos de C++ a macros e conversões de tipo.
Exemplos de código C e C++
#include <stdio.h>
typedef struct Shape Shape;
struct Shape {
double value;
double (*area)(const Shape *shape);
};
double square_area(const Shape *shape) {
return shape->value * shape->value;
}
int main(void) {
Shape square = {4.0, square_area};
printf("area=%.1f\n", square.area(&square));
}
area=16.0
#include <iostream>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Square : Shape {
double side;
explicit Square(double value) : side(value) {}
double area() const override { return side * side; }
};
int main() {
Square square(4);
const Shape& shape = square;
std::cout << "area=" << shape.area() << '\n';
}
area=16
Comparação entre C e C++
Em C, struct Shape guarda um ponteiro para função area, e cada forma liga sua própria função de área, como square_area. Em C++, as funções virtuais criam esse mesmo mecanismo de escolha automaticamente. A classe base também deve ter um destrutor virtual (virtual destructor) para que excluir um objeto por um ponteiro da classe base seja seguro.
C usa convenções de nomes, callbacks, macros e structs com contexto.
C++ oferece abstrações com escopo claro, seguras quanto a tipos e que normalmente não custam nada a mais na execução.
Exercícios práticos
Execute as duas versões e depois mude o código para observar a diferença de segurança que cada linguagem oferece.
- Escreva primeiro o mecanismo em C e só depois use o recurso equivalente de C++.
- Troque a liberação manual de recursos por RAII.
- Verifique se o recurso causa alocações de memória ou chamadas de funções virtuais.
Pratique com um desafio
Use o conteúdo desta lição para resolver um problema real. Cada desafio roda no navegador, com testes instantâneos e uma revisão por IA.
Todos os desafios