tipos lenguaje herencia ejemplos definicion datos constructores caracteristicas c++ inheritance casting downcasting downcast

herencia - lenguaje c++ ejemplos



Descenso de herencia de C++ (6)

Tengo mi clase base de la siguiente manera:

class point //concrete class { ... //implementation } class subpoint : public point //concrete class { ... //implementation }

¿Cómo echo desde un objeto de punto a un objeto de punto? He intentado los tres de los siguientes:

point a; subpoint* b = dynamic_cast<subpoint*>(&a); subpoint* b = (subpoint*)a; subpoint b = (subpoint)a;

¿Qué pasa con estos moldes?


El objetivo de un lanzamiento dinámico es "verificar en el tiempo de ejecución si un objeto es de un cierto tipo en la jerarquía". Entonces, veamos lo que tienes:

  1. Tienes un objeto puntual No es un punto secundario.
  2. Estás preguntando un lanzamiento dinámico si el objeto es un punto secundario. No es.
  3. Debido a que no es un punto secundario, dynamic_cast falla, es su forma de decirle que el objeto no es del tipo que está tratando de lanzarlo.

Por el contrario, esto habría funcionado:

subpoint c; point *a = &c; subpoint* b = dynamic_cast<subpoint*>(&a); subpoint* b = (subpoint*)a;


¿Cómo echo desde un objeto de punto a un objeto de punto?

No puedes; a menos que uno de los point tenga un operador de conversión o que el punto subpoint tenga un constructor de conversión, en cuyo caso los tipos de objeto se pueden convertir sin necesidad de un molde.

Puede lanzar desde una referencia de point (o puntero) a una referencia de punto (o puntero), si el objeto referido era en realidad de tipo subpoint :

subpoint s; point & a = s; subpoint & b1 = static_cast<subpoint&>(a); subpoint & b2 = dynamic_cast<subpoint&>(a);

El primero ( static_cast ) es más peligroso; no hay verificación de que la conversión sea válida, por lo que si a no se refiere a un punto subpoint , el uso de b1 tendrá un comportamiento indefinido.

El segundo ( dynamic_cast ) es más seguro, pero solo funcionará si el point es polimórfico (es decir, si tiene una función virtual). Si a refiere a un objeto de tipo incompatible, arrojará una excepción.


¿Qué pasa con estos moldes?

El hecho de que intentes hacerlos. Un point no es un point subpoint , me sorprendería si funcionara.


En general, esto no funcionará porque el point no es un point ; solo lo contrario es verdad. Sin embargo, hay otros problemas también.

En orden:

subpoint* b = dynamic_cast<subpoint*>(&a);

dynamic_cast solo funciona en tipos polimórficos, es decir, tipos que declaran al menos una función virtual. Supongo que ese point no tiene funciones virtuales, lo que significa que no se puede usar con dynamic_cast .

subpoint* b = (subpoint*)a;

Para que este molde funcione, el point necesita declarar a un operador de conversión como subpoint * , p. Ej., point::operator subpoint *() .

subpoint b = (subpoint)a;

Para que este molde funcione, el punto necesita declarar que un operador de conversión para subpoint o subpoint necesita tener un constructor que tome un parámetro convertible desde un point .


Para el primer ejemplo, dynamic_cast solo funciona si hay al menos un método virtual en la clase base. Y si el objeto no es realmente del tipo que intentas lanzar, dará como resultado NULL.

Para el segundo ejemplo necesita &a lugar de a , pero una vez que lo haya arreglado obtendrá un comportamiento indefinido porque el tipo de objeto es incorrecto.

El tercer ejemplo requiere un método de point operator subpoint() para hacer una conversión al crear una copia.


a no se puede convertir en un punto subpoint . esa implementación no está allí.