Polimorfismo en C ++
La palabra polymorphismsignifica tener muchas formas. Normalmente, el polimorfismo ocurre cuando hay una jerarquía de clases y están relacionadas por herencia.
El polimorfismo de C ++ significa que una llamada a una función miembro hará que se ejecute una función diferente dependiendo del tipo de objeto que invoca la función.
Considere el siguiente ejemplo donde una clase base ha sido derivada por otras dos clases:
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0){
width = a;
height = b;
}
int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape {
public:
Rectangle( int a = 0, int b = 0):Shape(a, b) { }
int area () {
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape {
public:
Triangle( int a = 0, int b = 0):Shape(a, b) { }
int area () {
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// Main function for the program
int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// store the address of Rectangle
shape = &rec;
// call rectangle area.
shape->area();
// store the address of Triangle
shape = &tri;
// call triangle area.
shape->area();
return 0;
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Parent class area :
Parent class area :
El motivo de la salida incorrecta es que el compilador establece una vez la llamada a la función area () como la versión definida en la clase base. Se llamastatic resolution de la llamada a la función, o static linkage- la llamada a la función se fija antes de que se ejecute el programa. A esto también se le llama a vecesearly binding porque la función area () se establece durante la compilación del programa.
Pero ahora, hagamos una pequeña modificación en nuestro programa y precedamos la declaración de area () en la clase Shape con la palabra clave virtual para que se vea así:
class Shape {
protected:
int width, height;
public:
Shape( int a = 0, int b = 0) {
width = a;
height = b;
}
virtual int area() {
cout << "Parent class area :" <<endl;
return 0;
}
};
Después de esta ligera modificación, cuando se compila y ejecuta el código de ejemplo anterior, produce el siguiente resultado:
Rectangle class area
Triangle class area
Esta vez, el compilador mira el contenido del puntero en lugar de su tipo. Por tanto, dado que las direcciones de los objetos de las clases tri y rec se almacenan en forma *, se llama a la función area () respectiva.
Como puede ver, cada una de las clases secundarias tiene una implementación separada para el área de función (). Así es comopolymorphismse utiliza generalmente. Tienes diferentes clases con una función del mismo nombre, e incluso los mismos parámetros, pero con diferentes implementaciones.
Función virtual
UN virtual función es una función en una clase base que se declara usando la palabra clave virtual. Definir en una clase base una función virtual, con otra versión en una clase derivada, le indica al compilador que no queremos un enlace estático para esta función.
Lo que sí queremos es que la selección de la función que se llamará en cualquier punto del programa se base en el tipo de objeto para el que se llama. Este tipo de operación se conoce comodynamic linkageo late binding.
Funciones virtuales puras
Es posible que desee incluir una función virtual en una clase base para que pueda redefinirse en una clase derivada para adaptarse a los objetos de esa clase, pero que no existe una definición significativa que pueda dar para la función en la clase base. .
Podemos cambiar el área de función virtual () en la clase base a lo siguiente:
class Shape {
protected:
int width, height;
public:
Shape(int a = 0, int b = 0) {
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
El = 0 le dice al compilador que la función no tiene cuerpo y que se llamará a la función virtual anterior pure virtual function.