Funciones virtuales en C++: ¿por qué las necesita un principiante?

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Funciones virtuales en C++: ¿por qué son imprescindibles?

\n\n

Imagine que es un director que está filmando una película sobre animales. Tiene un guion: "Todos los animales emiten un sonido". Graba una escena con un perro: ladra. Una escena con un gato: maúlla. Todo lógico. Ahora imagine que su asistente (el compilador) le trae una caja con animales de juguete y le dice: "¡Grabe!". Usted presiona el botón y el juguete... se queda en silencio. ¿Por qué? Porque olvidó las funciones virtuales.

\n\n

En programación con C++, este problema aparece constantemente. Usted escribe una clase "Animal", dentro de ella el método sound(). Luego crea las clases "Perro" y "Gato", que heredan de "Animal". Y todo parece estar bien, hasta que intenta trabajar con estos objetos a través de un puntero a la clase base. Ahí es donde descubre que C++ por defecto llama al método de la clase base, no al redefinido en la clase derivada. Las funciones virtuales resuelven este problema de una vez por todas.

\n\n

En este artículo analizaremos en detalle qué son las funciones virtuales, para qué sirven, cómo funcionan internamente y por qué el C++ moderno es impensable sin ellas.

\n\n

¿Qué es una función virtual en palabras sencillas?

\n\n

Una función virtual es un método de clase que se marca con la palabra clave virtual. Dicha función puede ser redefinida en clases derivadas, y al ser llamada a través de un puntero o referencia a la clase base, se ejecutará la versión de la clase derivada.

\n\n

¿Suena complicado? Pongamos un ejemplo de la vida real. Imagine un control remoto para robots. Tiene una clase base "Robot" con un método doWork(). Hay un robot aspiradora y un robot mensajero. Si presiona el botón "Trabajar", deberían ejecutarse los algoritmos correspondientes: la aspiradora comienza a limpiar, el mensajero a entregar un paquete. Sin funciones virtuales, usted presionaría el botón y el robot simplemente se quedaría quieto (se llamaría al método de la clase base).

\n\n

En C++, las funciones virtuales son la base del polimorfismo. El polimorfismo permite trabajar de manera uniforme con objetos de diferentes tipos, siempre que hereden de un ancestro común.

\n\n

El problema sin funciones virtuales: un ejemplo práctico

\n\n

Veamos qué sucede si no se usa virtual.

\n\n
#include <iostream>\n#include <vector>\n\nclass Animal {\npublic:\n    void sound() {\n        std::cout << "Some generic animal sound" << std::endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    void sound() {\n        std::cout << "Woof! Woof!" << std::endl;\n    }\n};\n\nclass Cat : public Animal {\npublic:\n    void sound() {\n        std::cout << "Meow!" << std::endl;\n    }\n};\n\nint main() {\n    std::vector<Animal*> animals;\n    animals.push_back(new Dog());\n    animals.push_back(new Cat());\n\n    for (Animal* a : animals) {\n        a->sound(); // ¿Qué se mostrará?\n    }\n\n    // Limpieza de memoria\n    for (Animal* a : animals) delete a;\n\n    return 0;\n}\n
\n\n

Ejecute este código. Verá:

\n
Some generic animal sound\nSome generic animal sound\n
\n\n

¿Por qué? Porque el compilador observa el tipo del puntero (Animal*), no el objeto real. Llama al método de la clase base. Esto se llama enlace temprano (early binding): la decisión sobre qué método llamar se toma en tiempo de compilación.

\n\n

Pero nosotros queremos enlace tardío (late binding): que la decisión se tome durante la ejecución del programa, según el tipo del objeto. Esto es precisamente lo que proporcionan las funciones virtuales.

\n\n

Solución: agregamos virtual

\n\n

Corrijamos el ejemplo añadiendo la palabra clave virtual.

\n\n
class Animal {\npublic:\n    virtual void sound() {  // Agregamos virtual\n        std::cout << "Some generic animal sound" <<                

Blogs

Book Recommendations