El uso de static_cast está bien en el ejemplo pero reinterpret_cast no lo es. Porque reinterpret_cast no es convertible vtable.
No, el problema es que reinterpret_cast
es completamente ajeno a la herencia. Simplemente devolverá la misma dirección sin cambios . Pero static_cast
sabe que está realizando un downcast: es decir, de conversión de una clase base a una clase derivada. Como conoce ambos tipos implicados, ajusta la dirección en consecuencia, es decir, hace lo correcto.
de pretender nuestra aplicación expone la hipotética clase OVERLAPPEDEX
que tiene una función virtual como esto Let:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr
El puntero que estamos puntos a la OVERLAPPED
subobjeto dado. reinterpret_cast
no cambiaría eso. Solo cambiaría el tipo. Obviamente, acceder a la clase OVERLAPPEDEX
a través de esta dirección fácilmente causaría estragos, ¡porque las ubicaciones de sus subobjetos ahora están mal!
what we believe we have when we access OVERLAPPEDEX through the pointer
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------+-----+------+-----------+------+------+------+
| vptr | OVERLAPPED | AssociatedClient | ClientState | <- what we actually have
+------+------------+------------------+-------------+
^
|
ptr
static_cast
sabe que para convertir una OVERLAPPED*
a OVERLAPPEDEX*
debe ajustar la dirección y hace lo correcto:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr after static_cast
Aunque, si uso C-Style lanzar allí (no reinterpretar_cast), ¿podría también salir mal?
Una conversión de estilo C se define como la primera uno de los siguientes que tiene éxito:
const_cast
static_cast
static_cast
, entonces const_cast
reinterpret_cast
reinterpret_cast
, luego const_cast
Como se puede ver, un static_cast
es probado antes de reinterpret_cast
, por lo que en este caso, una conversión de estilo C también haría lo correcto.
More info
no garantizados. Hay muy pocas garantías sobre lo que sucede en un reinterpret_cast
. Todas las implementaciones que conozco simplemente darán la misma dirección sin cambios.
No soy versado en C++, pero tengo entendido que un "reinterpretar elenco" significa exactamente lo que '* (destination_type *) &' significaría en C. Presumiblemente, "elemental estático" realmente toma relaciones de clases en cuenta y permite al compilador realizar trabajos de conversión no triviales. –