tipos punteros puntero ejemplos declarar declaracion datos conversion como arreglos apuntadores c++ pointers polymorphism

punteros - c++-conversión de un puntero de clase base a un puntero de clase derivado



punteros en c ejemplos (3)

Debes cambiar el tipo de base para que sea polimórfico:

class Base { public: Base() {}; virtual ~Base(){}; };

Para convertir un supertipo en algún tipo derivado, debe usar dynamic_cast :

Base *b = new Derived<int>(1); Derived<int> *d = dynamic_cast<Derived<int> *>(b);

El uso de dynamic_cast aquí comprueba que el encasillado es posible. Si no hay necesidad de hacer esa comprobación (porque el reparto no puede fallar), también puedes usar static_cast :

Base *b = new Derived<int>(1); Derived<int> *d = static_cast<Derived<int> *>(b);

#include <iostream> using namespace std; class Base { public: Base() {}; ~Base() {}; }; template<class T> class Derived: public Base { T _val; public: Derived() {} Derived(T val): _val(val) {} T raw() {return _val;} }; int main() { Base * b = new Derived<int>(1); Derived<int> * d = b; cout << d->raw() << endl; return 0; }

Tengo un problema de polimorfismo en este momento y el código anterior lo resume todo. Creé un puntero de clase Base y puse el puntero de una nueva clase de plantilla derivada en él. Luego creé un nuevo puntero para la clase de plantilla derivada y quiero que tenga la referencia a la que apunta el puntero de la clase base. Aunque el puntero Base (b) apunta a un Derivado, la referencia no se puede pasar al puntero de clase Derivado (d) porque there''s no known conversion from Base * to Derived<int> * (como dice el compilador).

Entonces, ¿hay un truco o una forma alternativa de poder hacerlo? Gracias por adelantado.


Prueba esto:

Derived<int> * d = static_cast<Derived<int>* >(b);

A la baja, se puede lanzar una clase que es instancia de Base () y luego d-> raw () no estará definida (probabilidad de segmentación). Si ese fuera el caso, use dynamic_cast y tenga al menos una función ob base virtual (tener destructores virtuales es esencial cuando se trabaja con polimorfismo).

Las funciones virtuales se implementan bajo el puntero en la tabla virtual. Este puntero también se puede usar para identificar el verdadero tipo de clase. Esto es usado por dynamic_cast para verificar si esta conversión puede hacerse y trae una pequeña sobrecarga adicional cuando se convierte.


Puedes usar dynamic_cast

Derived<int> * d = dynamic_cast<Derived<int> *>(b);

Si la conversión falla (el puntero base no apunta al tipo derivado solicitado), devuelve nulo.

Sin embargo, para que dynamic_cast funcione, su clase base debe tener al menos una función virtual. Sugiero que hagas que el destructor sea virtual (esto también evita otros posibles problemas al eliminar tus objetos).

El uso de dynamic_cast puede indicar un mal diseño en tu código.

Tenga en cuenta que si está 100% seguro de que el puntero base apunta a su tipo derivado, puede reemplazarlo por static_cast, que es un poco más rápido. Personalmente prefiero el control de seguridad adicional en general.