Considere el siguiente programa simple que es un ejemplo de polimorfismo en tiempo de ejecución.
Lo principal a tener en cuenta sobre el programa es que la función de clase derivada se llama utilizando un puntero de clase base. La idea es que las funciones virtuales se llaman según el tipo de objeto apuntado o referido, no según el tipo de puntero o referencia. En otras palabras, las funciones virtuales se resuelven tarde, en tiempo de ejecución.

#include<iostream>

using namespace std;

  

class Base

{

public:

    virtual void show() { cout<<" In Base
"
; }

};

  

class Derived: public Base

{

public:

    void show() { cout<<"In Derived
"
; }

};

  

int main(void)

{

    Base *bp = new Derived;

    bp->show(); 

    return 0;

}

Producción:

In Derived

¿Cuál es el uso?
Las funciones virtuales nos permiten crear una lista de punteros de clase base y llamar a métodos de cualquiera de las clases derivadas sin siquiera conocer el tipo de objeto de clase derivada. Por ejemplo, considere un software de gestión de empleados para una organización, deje que el código tenga una clase base simple Empleado , la clase contiene funciones virtuales como raiseSalary (), transferir(), promover(), .. etc. Diferentes tipos de empleados como Gerente, Ingeniero, ..etc pueden tener sus propias implementaciones de las funciones virtuales presentes en la clase base Empleado. En nuestro software completo, solo necesitamos pasar una lista de empleados en todas partes y llamar a las funciones apropiadas sin siquiera saber el tipo de empleado. Por ejemplo, podemos aumentar fácilmente el salario de todos los empleados iterando a través de la lista de empleados. Cada tipo de empleado puede tener su propia lógica en su clase, no debemos preocuparnos porque si raiseSalary () está presente para un tipo de empleado específico, solo se llamaría a esa función.

class Employee

{

public:

    virtual void raiseSalary()

     }

 

    virtual void promote()

    { }

};

 

class Manager: public Employee {

    virtual void raiseSalary()

    

           }

 

    virtual void promote()

    { }

};

 

 

void globalRaiseSalary(Employee *emp[], int n)

{

    for (int i = 0; i < n; i++)

        emp[i]->raiseSalary();

                               

                               

}

como globalRaiseSalary (), puede haber muchas otras operaciones que se pueden realizar adecuadamente en una lista de empleados sin siquiera saber el tipo de objeto real.
Las funciones virtuales son tan útiles que los lenguajes posteriores como Java mantienen todos los métodos como virtuales de forma predeterminada.

¿Cómo hace el compilador esta magia de resolución tardía?
El compilador mantiene dos cosas en esta magia:
virtualFuns
vtable: Una tabla de punteros de función. Se mantiene por clase.
vptr: Un puntero a vtable. Se mantiene por objeto (Ver esta para un ejemplo).

El compilador agrega código adicional en dos lugares para mantener y usar vptr.
1) Código en cada constructor. Este código establece vptr del objeto que se está creando. Este código establece vptr apuntar a vtable de la clase.
2) Código con llamada a función polimórfica (p. Ej. bp-> mostrar () en el código anterior). Dondequiera que se realice una llamada polimórfica, el compilador inserta código para buscar primero vptr utilizando un puntero de clase base o una referencia (en el ejemplo anterior, dado que el objeto apuntado o referido es de tipo derivado, se accede a vptr de la clase derivada). Una vez vptr se busca, vtable de la clase derivada se puede acceder. Utilizando vtable, dirección de la función de clase derivada derivada show() se accede y se llama.

¿Es esta una forma estándar de implementación del polimorfismo en tiempo de ejecución en C ++?
Los estándares C ++ no exigen exactamente cómo se debe implementar el polimofismo en tiempo de ejecución, pero los compiladores generalmente usan variaciones menores en el mismo modelo básico.

Cuestionario sobre funciones virtuales.

Referencias:
http://en.wikipedia.org/wiki/Virtual_method_table
http://en.wikipedia.org/wiki/Virtual_function
http://www.drbio.cornell.edu/pl47/programming/TICPP-2nd-ed-Vol-one-html/Frames.html

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema discutido anteriormente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *