sociologia segun origen memetica memes meme los importancia fenomeno ensayo definicion comunicacion autores analisis c++ virtual-functions override redefinition

c++ - segun - Anular una función miembro con diferente tipo de retorno



meme y memetica (5)

Considere el siguiente ejemplo:

#include <iostream> using namespace std; class base { public: virtual int func() { cout << "vfunc in base class/n"; return 0; } }; class derived: public base { public: double func() { cout << "vfunc in derived class/n"; return 0; } }; int main() { base *bptr = new derived; bptr->func(); return 0; }

El compilador da un error para el código anterior de que hay un tipo conflictivo para la función anulada. ¿Por qué no es posible anular una función en la clase derivada con un tipo de retorno diferente?

Creo que, para anular una función, el método virtual de la clase base necesita ser redefinido en la clase derivada. Para redefinir un método, las firmas de los métodos deben ser las mismas. Dado que el tipo de retorno no es parte de la firma, creo que incluso si hay una diferencia en el tipo de retorno, ¿el método seguirá siendo redefinido? En ese caso, para el código anterior, la función de func virtual se redefine en la clase derivada con un tipo de retorno diferente. Pero el compilador arroja un error. ¿Mi entendimiento es correcto?


La anulación esencialmente significa que se llamará al método de la clase Base o al método de la clase Derivada en tiempo de ejecución, dependiendo del objeto real señalado por el puntero.
Implica que:
es decir: cualquier lugar donde se pueda llamar al método de clase Base puede ser reemplazado por una llamada al método de clase Derivada sin ningún cambio en el código de llamada.

Para lograr esto, la única manera posible es restringir los tipos de retorno de los métodos virtuales de reemplazo para que devuelvan el mismo tipo que la clase Base o un tipo derivado de eso (tipos de retorno de variante) y el Estándar impone esta condición.

Si la condición anterior no estaba en su lugar, dejaría una ventana para romper el código existente mediante la adición de una nueva funcionalidad.


La anulación no es posible, ya que las firmas son diferentes. El propósito básico de anular es el polimorfismo, pero no es posible en el ejemplo anterior.


Para anular una función virtual, el valor de retorno debe ser exactamente el mismo *. C ++ no convertirá automáticamente entre double e int aquí. Después de todo, ¿cómo sabría qué tipo de retorno desea cuando llama desde un puntero de clase derivado? Tenga en cuenta que si cambia parte de la firma (parámetros, constancia, etc.), también puede cambiar el valor de retorno.

* - estrictamente hablando, debe ser ''covariante''. Lo que esto significa es que el tipo que devuelve debe ser un subconjunto del tipo de retorno de la función principal. Por ejemplo, si la clase padre devuelve una base * , podría devolver un derived * . Como los s derived también son s de base , el compilador le permite anular de esta manera. Pero no puede devolver tipos totalmente no relacionados, como int y double ; solo porque haya una conversión implícita no significa que el compilador le permita hacer este tipo de anulación.


Si desea anularlo, debe intentar utilizar la plantilla.

Vea lo siguiente:

#include <iostream> using namespace std; class base { public: template<typename X> X func() { cout << "vfunc in base class/n"; return static_cast<X>(0); } }; class derived: public base { public: template<typename X> X func() { cout << "vfunc in derived class/n"; return static_cast<X>(2); } }; int main() { derived *bptr = new derived; cout << bptr->func<int>() << endl; cout << dynamic_cast<base*>(bptr)->func<int>() << endl; derived *bptr2 = new derived; cout << bptr->func<double>() << endl; cout << dynamic_cast<base*>(bptr)->func<int>() << endl; return 0; }

Por supuesto, no necesita declararlo en dos clases diferentes de esa manera, podría hacer:

class base { public: int func() { cout << "vfunc in base class/n"; return 0; } double func(){ cout << "vfunc for double class/n"; return 2.; } };


Vea esta pregunta . Para resumir, solo puede anular una función virtual utilizando un tipo de retorno diferente si los tipos son covariant .