Para comprender el sistema de conversión, debe sumergirse en el modelo de objetos.
La representación clásica de un sencillo modelo de jerarquía de contención es: que si B
deriva de A
entonces el objeto B
, de hecho, contiene un subobjeto A
junto con sus propios atributos.
Con este modelo, downcasting es una manipulación de puntero simple, por un desplazamiento conocido en tiempo de compilación que depende del diseño de memoria de B
.
Esto es lo que static_cast hacer: un molde estático es apodado estática porque el cálculo de lo que es necesario para el reparto se realiza en tiempo de compilación, ya sea un apuntador aritmética o conversiones (*).
Sin embargo, cuando entra en juego la herencia virtual
las cosas tienden a ser un poco más difíciles. El problema principal es que con la herencia virtual
todas las subclases comparten una misma instancia del subobjeto. Para hacer eso, B
tendrá un puntero a A
, en lugar de A
, y el objeto de clase base A
se creará una instancia fuera de B
.
Por lo tanto, es imposible en el tiempo de compilación deducir la aritmética del puntero necesaria: depende del tipo de tiempo de ejecución del objeto.
Siempre que haya una dependencia de tipo de tiempo de ejecución, necesita RTTI (información de tipo de tiempo de ejecución), y hacer uso de RTTI para conversiones es el trabajo de dynamic_cast.
En resumen:
- tiempo de compilación abatido:
static_cast
- tiempo de ejecución abatido:
dynamic_cast
los otros dos son también en tiempo de compilación arroja, pero son tan específicas que es fácil recordar para qué son ... y huelen mal, así que mejor no usarlos de todos modos.
(*) Según lo observado por @curiousguy en los comentarios, esto solo vale para downcasting. Un static_cast
permite el upcasting independientemente de la herencia virtual o simple, aunque el lanzamiento también es innecesario.
¡Buena respuesta que me hizo entender cómo funciona la herencia virtual!+1 – undu
Me gusta su respuesta, pero aparentemente el OP estaba preguntando acerca de un error para DOWNCASTING en lugar de upcasting. – h9uest
@ h9uest: Gracias por señalar el error, cambié "up-casting" a "downcasting" y ahora todo está bien. –