Polimorfismo estático
Evite el coste de las llamadas virtuales
Polimorfismo estático es una lección gratuita de C++ Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C++ Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C++ Academy incluye 4 lecciones en total.
Dos tipos de polimorfismo
C++ admite dos variantes de polimorfismo.
- Dinámico: las funciones virtuales se resuelven en tiempo de ejecución mediante una vtable
- Estático: las plantillas y CRTP se resuelven en tiempo de compilación
El polimorfismo estático intercambia flexibilidad por velocidad.
El coste de virtual
Una llamada virtual requiere un salto indirecto a través de la vtable. Normalmente, el compilador no puede insertarla en línea, lo que impide muchas optimizaciones.
#include <iostream>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Square : Shape {
double s;
Square(double x) : s(x) {}
double area() const override { return s * s; }
};
int main() {
Shape* p = new Square(3);
std::cout << p->area() << "\n";
delete p;
return 0;
}Despacho estático con CRTP
Con CRTP, la clase base llama directamente al método derivado mediante una conversión en tiempo de compilación, por lo que el compilador puede insertar todo en línea.
#include <iostream>
template <typename T>
struct Shape {
double area() const { return static_cast<const T*>(this)->area(); }
};
struct Square : Shape<Square> {
double s;
Square(double x) : s(x) {}
double area() const { return s * s; }
};
int main() {
Square sq(3);
std::cout << sq.area() << "\n";
return 0;
}Nombres de las funciones de reenvío
Cuando la clase base y la derivada definen ambas area, asigne a la función de reenvío de la clase base un nombre distinto, como compute, para que llame sin ambigüedad a la implementación derivada.
#include <iostream>
template <typename T>
struct Shape {
double compute() const { return static_cast<const T*>(this)->area(); }
};
struct Circle : Shape<Circle> {
double r;
Circle(double x) : r(x) {}
double area() const { return 3.14159 * r * r; }
};
int main() {
Circle c(2);
std::cout << c.compute() << "\n";
return 0;
}Las plantillas como polimorfismo estático
Las plantillas de función simples también son polimorfismo estático: el mismo código funciona con cualquier tipo que proporcione la interfaz necesaria (duck typing en tiempo de compilación).
#include <iostream>
struct Dog { void speak() const { std::cout << "Woof\n"; } };
struct Cat { void speak() const { std::cout << "Meow\n"; } };
template <typename Animal>
void make_speak(const Animal& a) { a.speak(); }
int main() {
make_speak(Dog{});
make_speak(Cat{});
return 0;
}Cuando se conoce el tipo
El polimorfismo estático solo se aplica cuando el tipo concreto se conoce en tiempo de compilación. Si necesita almacenar objetos heterogéneos en un mismo contenedor y elegir el comportamiento en tiempo de ejecución, seguirá necesitando funciones virtuales.
Sin contenedores heterogéneos
No puede colocar Shape<Square> y Shape<Circle> en el mismo std::vector como una base común, porque son tipos no relacionados. Esta es la limitación principal del polimorfismo estático.
Ventaja de rendimiento
Al insertar en línea la llamada despachada, el compilador puede plegar constantes y eliminar por completo la sobrecarga de la llamada a función. En bucles estrechos sobre un único tipo conocido, el polimorfismo estático puede ser considerablemente más rápido.
#include <iostream>
template <typename T>
struct Op {
int apply(int x) const { return static_cast<const T*>(this)->apply(x); }
};
struct Doubler : Op<Doubler> {
int apply(int x) const { return x * 2; }
};
int main() {
Doubler d;
int sum = 0;
for (int i = 0; i < 5; ++i) sum += d.apply(i);
std::cout << sum << "\n";
return 0;
}Combinar ambos
Puede utilizar CRTP para la ruta crítica y un envoltorio virtual ligero cuando necesite borrado de tipos. Así obtiene velocidad donde importa y flexibilidad donde es necesaria.
Comprobaciones estáticas de la interfaz
Si una clase derivada olvida implementar el método requerido, el error aparece en tiempo de compilación cuando se instancia el reenviador de la clase base, no en tiempo de ejecución.
#include <iostream>
template <typename T>
struct Greeter {
void greet() const { static_cast<const T*>(this)->hello(); }
};
struct English : Greeter<English> {
void hello() const { std::cout << "Hello\n"; }
};
int main() {
English{}.greet();
return 0;
}Elegir la herramienta adecuada
Utilice polimorfismo estático cuando:
- El tipo se conoce en tiempo de compilación
- El rendimiento es fundamental
- No necesita un tipo base común en tiempo de ejecución
De lo contrario, prefiera las funciones virtuales por su claridad y flexibilidad.
Comprobación rápida
Elija la principal contrapartida del polimorfismo estático.
Resumen
Ha comparado el polimorfismo estático y el dinámico.
- Virtual = despacho en tiempo de ejecución, vtable, contenedores heterogéneos
- CRTP/plantillas = despacho en tiempo de compilación, posibilidad de inserción en línea, mayor velocidad
- El polimorfismo estático necesita que el tipo se conozca en tiempo de compilación
- Elija según sus necesidades de flexibilidad y rendimiento
Preguntas frecuentes
¿La lección «Polimorfismo estático» es gratis?
Sí — el texto completo de «Polimorfismo estático» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C++ Academy, actualiza a CoddyKit PRO. El curso de C++ Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Polimorfismo estático»?
Evite el coste de las llamadas virtuales Practicas C++ Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C++ Academy?
No se requiere experiencia previa. C++ Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.
¿Cuánto tiempo toma la lección «Polimorfismo estático»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C++ Academy?
Sí. Cada lección de C++ Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- El patrón CRTP
- Polimorfismo estático
- Mixins con CRTP
- Cuándo usar CRTP