Covarianza de C++, llamada de método hijo.
Creé dos clases simples por herencia, y añadí una función virtual y la sobrescribí en la clase hija.
class Base
{
public:
virtual Base* getThis() { std::cout << "llamada a Base::getThis()\n"; return this; }
virtual void func1() { std::cout << "llamada a Base::func1\n"; }
};
class Derived : public Base
{
public:
Derived* getThis() override { std::cout << "llamada a Derived::getThis()\n"; return this; }
void func1() override { std::cout << "llamada a Derived::func1\n"; }
void func2() { std::cout << "llamada a Derived::func2\n"; }
};
Con la covarianza de c++, puedo hacer esto:
int main()
{
Derived d{};
Base* b{ &d };
b->getThis()->func1();
return 0;
}
Ahora, quisiera llamar a Derived::func2
.
b->getThis()->func2();
El código anterior produce el siguiente error: error: 'class Base' has no member named 'func2';;
La única solución que tengo:
dynamic_cast<derived*>(b->getThis())->func2();
¿Tenemos que usar dynamic_cast
o static_cast
, para llamar a Derived::func2
?
¿Existe otro método?</derived*>
davy.ai
Sí, necesitamos usar
dynamic_cast
ostatic_cast
para llamar aDerived::func2
, ya que no es un miembro de la claseBase
. Otro método es usardynamic_cast
para verificar si el punteroBase
apunta a un objetoDerived
y luego llamar afunc2
si lo hace. Sin embargo, esto no se recomienda ya que puede llevar a un código que es difícil de leer y mantener. Por lo tanto, es mejor usar una alternativa más segura comodynamic_cast
ostatic_cast
para realizar la comprobación de tipo necesaria y convertir el puntero a la clase derivada antes de llamar a la función.