C++ Polimorfismo con ejemplo
⚡ Resumen inteligente
Polimorfismo en C++ Permite que una única función miembro adopte múltiples formas, comportándose de manera diferente según el objeto que la invoca. Se basa en la herencia y se presenta en dos variantes, que se resuelven en tiempo de compilación o en tiempo de ejecución.

¿Qué es el polimorfismo en C++?
In C++El polimorfismo hace que una función miembro se comporte de manera diferente según el objeto que la llama/invoca. Polimorfismo es una palabra griega que significa tener muchas formas. Ocurre cuando tienes una jerarquía de privadas emparentados por herencia.
Por ejemplo, supongamos que tenemos la función makeSound(). Cuando un gato llama a esta función, producirá un maullido. Cuando una vaca invoca la misma función, emitirá el sonido de un maullido.
Aunque tenemos una función, se comporta de manera diferente en diferentes circunstancias. La función tiene muchas formas; por tanto, hemos logrado el polimorfismo.
Con la idea central ya establecida, C++ Organiza este comportamiento en dos categorías distintas.
Tipos de polimorfismo
C++ admite dos tipos de polimorfismo:
- Polimorfismo en tiempo de compilación y
- Polimorfismo en tiempo de ejecución.
La primera categoría resuelve todas las llamadas a funciones antes de que se ejecute el programa.
Compilar polimorfismo de tiempo
Se invocan las funciones sobrecargadas haciendo coincidir el número y el tipo de argumentos. La información está presente durante el tiempo de compilación. Esto significa que C++ El compilador seleccionará la función correcta en el momento de la compilación.
El polimorfismo en tiempo de compilación se logra mediante la sobrecarga de funciones y la sobrecarga de operadores.
Sobrecarga de funciones
La sobrecarga de funciones ocurre cuando tenemos muchas funciones con nombres similares pero argumentos diferentes. Los argumentos pueden diferir en términos de número o tipo.
Ejemplo
#include <iostream> using namespace std; void test(int i) { cout << " The int is " << i << endl; } void test(double f) { cout << " The float is " << f << endl; } void test(char const *ch) { cout << " The char* is " << ch << endl; } int main() { test(5); test(5.5); test("five"); return 0; }
Salida:
Aquí hay una captura de pantalla del código:
Code Explicación:
- Incluya el archivo de encabezado iostream en nuestro código. Podremos utilizar sus funciones.
- Incluya el espacio de nombres estándar en nuestro código. Podremos utilizar sus clases sin llamarlo.
- Cree una función llamada prueba que tome un parámetro entero i. El { marca el comienzo del cuerpo de la prueba de función.
- Declaración que se ejecutará si se invoca/llama la función de prueba anterior.
- Fin del cuerpo de la prueba de función anterior.
- Cree una función llamada prueba que tome un parámetro flotante f. El { marca el comienzo del cuerpo de la prueba de función.
- Declaración que se ejecutará si se invoca/llama la función de prueba anterior.
- Fin del cuerpo de la prueba de función anterior.
- Cree una función llamada prueba que tome un parámetro de carácter ch. El { marca el comienzo del cuerpo de la prueba de función.
- Declaración que se ejecutará si se invoca/llama la función de prueba anterior.
- Fin del cuerpo de la prueba de función anterior.
- Llame a la función principal(). El { marca el comienzo del cuerpo de la función.
- Llame a la función test y pásele 5 como valor del argumento. Esto invoca la función de prueba que acepta un argumento entero, es decir, la primera función de prueba.
- Llame a la función test y pásele 5.5 como valor del argumento. Esto invocará la función de prueba que acepta un argumento flotante, es decir, la segunda función de prueba.
- Llame a la función test y pásele cinco como valor del argumento. Esto invocará la función de prueba que acepta un argumento de carácter, es decir, la tercera función de prueba.
- El programa debe devolver un valor si se ejecuta correctamente.
- El final del cuerpo de la función main().
Tenemos tres funciones con el mismo nombre pero diferentes tipos de argumentos. Hemos logrado el polimorfismo.
OperaSobrecarga de Tor
In Operator Overloading, definimos un nuevo significado para un C++ operadorTambién modifica el funcionamiento del operador. Por ejemplo, podemos definir el operador + para concatenar dos cadenas. Lo conocemos como el operador de suma para añadir valores numéricos. Tras nuestra definición, cuando se coloca entre números enteros, los suma. Cuando se coloca entre cadenas, las concatena.
Ejemplo
#include<iostream> using namespace std; class ComplexNum { private: int real, over; public: ComplexNum(int rl = 0, int ov = 0) { real = rl; over = ov; } ComplexNum operator + (ComplexNum const &obj) { ComplexNum result; result.real = real + obj.real; result.over = over + obj.over; return result; } void print() { cout << real << " + i" << over << endl; } }; int main() { ComplexNum c1(10, 2), c2(3, 7); ComplexNum c3 = c1+c2; c3.print(); }
Salida:
Aquí hay una captura de pantalla del código:
Code Explicación:
- Incluya el archivo de encabezado iostream en nuestro programa para poder utilizar sus funciones.
- Incluya el espacio de nombres estándar en nuestro programa para poder usar sus clases sin llamarlo.
- Crea una clase llamada ComplexNum. El { marca el comienzo del cuerpo de la clase.
- Utilice el modificador de acceso privado para marcar las variables como privadas, lo que significa que solo se puede acceder a ellas desde dentro de la clase.
- Defina dos variables enteras, reales y superiores.
- Utilice el modificador de acceso público para marcar el constructor como público, lo que significa que será accesible incluso desde fuera de la clase.
- Crea el constructor de la clase e inicializa las variables.
- Inicializa el valor de la variable real.
- Inicialice el valor de la variable over.
- Fin del cuerpo del constructor.
- Necesitamos anular el significado del operador +.
- Crea el tipo de datos resultado del tipo ComplexNum.
- Utilice el operador + con números complejos. Esta línea sumará la parte real de un número con la parte real de otro número.
- Utilice el operador + con números complejos. Esta línea sumará la parte imaginaria de un número a la parte imaginaria de otro número.
- El programa devolverá el valor de la variable resultado tras una ejecución exitosa.
- Fin de la definición del nuevo significado del operador +, es decir, la sobrecarga.
- Llame al método print().
- Imprima el nuevo número complejo después de la suma en la consola.
- Fin del cuerpo de la función print().
- Fin del cuerpo de la clase ComplexNum.
- Llame a la función principal().
- Pasar los valores de las partes reales y complejas que se van a sumar. La primera parte de c1 se sumará a la primera parte de c2, es decir, 10+3. La segunda parte de c1 se sumará a la segunda parte de c, es decir, 2+7.
- Realizar una operación utilizando el operador + sobrecargado y almacenar el resultado en la variable c3.
- Imprime el valor de la variable c3 en la consola.
- Fin del cuerpo de la función main().
Mientras que el polimorfismo en tiempo de compilación decide pronto, la segunda categoría pospone la elección hasta la ejecución.
Polimorfismo en tiempo de ejecución
Esto sucede cuando el método de un objeto se invoca/llama durante el tiempo de ejecución en lugar de durante el tiempo de compilación. El polimorfismo en tiempo de ejecución se logra mediante la anulación de funciones. La función a llamar/invocar se establece durante el tiempo de ejecución.
Anulación de funciones
La anulación de funciones ocurre cuando a una función de la clase base se le da una nueva definición en una clase derivada. En ese momento, podemos decir que la función base ha sido anulada.
Por ejemplo:
#include <iostream> using namespace std; class Mammal { public: void eat() { cout << "Mammals eat..."; } }; class Cow: public Mammal { public: void eat() { cout << "Cows eat grass..."; } }; int main(void) { Cow c = Cow(); c.eat(); return 0; }
Salida:
Aquí hay una captura de pantalla del código:
Code Explicación:
- Importe el archivo de encabezado iostream a nuestro programa para usar sus funciones.
- Incluya el espacio de nombres estándar en nuestro programa para poder usar sus clases sin llamarlo.
- Crea una clase llamada Mamífero. El { marca el comienzo del cuerpo de la clase.
- Utilice el modificador de acceso público para configurar la función que estamos a punto de crear como de acceso público. Será accesible desde fuera de esta clase.
- Crea una función pública llamada comer. El { marca el comienzo del cuerpo de la función.
- Imprime la declaración agregada a la función cout cuando se invoca la función eat().
- El final del cuerpo de la función eat().
- Fin del cuerpo de la clase Mamífero.
- Cree una clase llamada Vaca que herede la clase Mamífero. Vaca es la clase derivada, mientras que Mamífero es la clase base. El { marca el comienzo de esta clase.
- Utilice el modificador de acceso público para marcar la función que estamos a punto de crear como de acceso público. Será accesible desde fuera de esta clase.
- Anule la función eat() que se definió en la clase base. El { marca el comienzo del cuerpo de la función.
- La declaración que se imprimirá en la consola cuando se invoque esta función.
- Fin del cuerpo de la función comer().
- Fin del cuerpo de la clase Vaca.
- Llame a la función principal(). El { marca el comienzo del cuerpo de esta función.
- Cree una instancia de la clase Cow y asígnele el nombre c.
- Llame a la función eat() definida en la clase Cow.
- El programa debe devolver un valor al finalizar con éxito.
- Fin de la función main().
C++ Función virtual
Una función virtual es otra forma de implementar polimorfismo en tiempo de ejecución en C++. Es una función especial definida en una clase base y redefinida en la clase derivada. Para declarar una función virtual, debe utilizar la palabra clave virtual. La palabra clave debe preceder a la declaración de la función en la clase base.
Si se hereda una clase de función virtual, la clase virtual redefine la función virtual para satisfacer sus necesidades. Por ejemplo:
#include <iostream> using namespace std; class ClassA { public: virtual void show() { cout << "The show() function in base class invoked..." << endl; } }; class ClassB :public ClassA { public: void show() { cout << "The show() function in derived class invoked..."; } }; int main() { ClassA* a; ClassB b; a = &b; a->show(); }
Salida:
Aquí hay una captura de pantalla del código:
Code Explicación:
- Incluya el archivo de encabezado iostream en el código para usar sus funciones.
- Incluya el espacio de nombres estándar en nuestro código para usar sus clases sin llamarlo.
- Crea una clase llamada ClassA.
- Utilice el modificador de acceso público para marcar a un miembro de la clase como de acceso público.
- Cree una función virtual llamada show(). Será una función pública.
- El texto que se imprimirá cuando se invoque show(). El final es un C++ palabra clave, que significa línea final. Mueve el cursor del mouse a la siguiente línea.
- Fin del cuerpo de la función virtual show().
- Fin del cuerpo de la clase ClassA.
- Creando una nueva clase llamada ClassB que hereda la clase ClassA. ClassA se convierte en la clase base mientras que ClassB se convierte en la clase derivada.
- Utilice el modificador de acceso público para marcar a un miembro de la clase como de acceso público.
- Redefina la función virtual show() derivada en la clase base.
- El texto que se imprimirá en la consola cuando se invoque la función show() definida en la clase derivada.
- Fin del cuerpo de la función show().
- Fin del cuerpo de la clase derivada, ClassB.
- Llame a la función principal(). La lógica del programa debe agregarse dentro de su cuerpo.
- Cree una variable de puntero denominada a. Apunta a la clase denominada ClassA.
- Cree una instancia de la clase denominada ClassB. La instancia recibe el nombre b.
- Asigne los valores almacenados en la dirección b en la variable a.
- Invoca la función show() definida en la clase derivada. Se ha implementado la vinculación tardía.
- Fin del cuerpo de la función main().
Una vez explicados ambos mecanismos, la siguiente tabla los compara uno al lado del otro.
Polimorfismo en tiempo de compilación vs. Polimorfismo en tiempo de ejecución
Estas son las principales diferencias entre los dos:
| Polimorfismo en tiempo de compilación | Polimorfismo en tiempo de ejecución |
|---|---|
| También se le denomina unión temprana o polimorfismo estático. | También se denomina unión tardía/dinámica o polimorfismo dinámico. |
| El método se llama/invoca durante el tiempo de compilación. | El método se llama/invoca durante el tiempo de ejecución. |
| Implementado mediante sobrecarga de funciones y sobrecarga de operadores. | Implementado mediante anulación de métodos y funciones virtuales. |
| Ejemplo, sobrecarga de métodos. Muchos métodos pueden tener nombres similares pero diferentes números o tipos de argumentos. | Ejemplo, anulación de método. Muchos métodos pueden tener un nombre similar y el mismo prototipo. |
| Ejecución más rápida ya que el descubrimiento del método se realiza durante la compilación. | La ejecución es más lenta, ya que el descubrimiento de métodos se realiza durante el tiempo de ejecución. |
| Less Se proporciona flexibilidad para la resolución de problemas ya que todo se sabe durante el tiempo de compilación. | Se proporciona mucha flexibilidad para resolver problemas complejos ya que los métodos se descubren durante el tiempo de ejecución. |







