2012-08-07 15 views
11

tengo mi clase base de la siguiente manera:C++ herencia downcasting

class point //concrete class 
{ 
... //implementation 
} 

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

¿Cómo CAST de un objeto de punto a un objeto inciso? 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?

Respuesta

22

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

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

Se podría emitidos, de una pointreferencia (o puntero) a un subpointreferencia (o puntero), si el objeto a que se refiere en realidad eran 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 se verifica que la conversión sea válida, por lo que si a no se refiere a un subpoint, entonces el uso de b1 tendrá un comportamiento indefinido. El segundo (dynamic_cast) es más seguro, pero solo funcionará si point es polimórfico (es decir, si tiene una función virtual). Si a se refiere a un objeto de tipo incompatible, arrojará una excepción.

+0

El objeto que se convertirá en realidad es de tipo punto, solo en una matriz de puntos. – CodeKingPlusPlus

0

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

0

¿Qué pasa con estos moldes?

El hecho de que usted intente hacerlas. Un point no es un subpoint, me sorprendería si funcionara.

1

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

En orden:


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

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


subpoint* b = (subpoint*)a; 

Para este reparto funcione, point necesidades para declarar un operador de conversión a subpoint *, por ejemplo, point::operator subpoint *().


subpoint b = (subpoint)a; 

Para este reparto funcione, punto necesita para declarar un operador de conversión a subpointosubpoint necesita tener un constructor que toma un convertible parámetro de point.

2

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 en lugar de a, pero una vez que lo haya solucionado, obtendrá un comportamiento indefinido porque el tipo de objeto es incorrecto.

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

+1

@MooingDuck, definimos "no funcionará"? Debería devolver un puntero NULL, que puede no ser el resultado esperado, pero compila y hace algo útil. –

+0

Debo haber leído mal tu respuesta, me parece bien ahora. –

1

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

  1. Tiene un objeto puntual. No es un punto secundario.
  2. Está pidiendo 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 manera de decirle que el objeto no es del tipo que está tratando de lanzarlo.

Por el contrario, esto habría trabajado:

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