Según this, void*
no tiene información de RTTI, por lo tanto, la fundición de void*
no es legal y que tenga sentido.dynamic_cast de "void *"
Si no recuerdo mal, dynamic_cast
de void*
estaba trabajando en gcc.
Puede aclarar el problema.
Según this, void*
no tiene información de RTTI, por lo tanto, la fundición de void*
no es legal y que tenga sentido.dynamic_cast de "void *"
Si no recuerdo mal, dynamic_cast
de void*
estaba trabajando en gcc.
Puede aclarar el problema.
dynamic_cast
sólo funciona en tipos polimórficos, clases es decir que contienen funciones virtuales.
En gcc se puede dynamic_cast
avoid*
pero no de:
struct S
{
virtual ~S() {}
};
int main()
{
S* p = new S();
void* v = dynamic_cast<void*>(p);
S* p1 = dynamic_cast<S*>(v); // gives an error
}
Es cierto que void*
no puede ser dynamically_cast
ed from.
Probablemente esté recordando mal. Con g ++ 4.5 y el siguiente código
struct A {
virtual ~A();
};
int main() {
A a;
void *p = &a;
A* pa = dynamic_cast<A*>(p);
}
me sale el siguiente error:
cannot dynamic_cast 'p' (of type 'void*') to type 'struct A*' (source is not a pointer to class)
supongo que confundir con dynalic_cast
avoid*
. Eso es legal y obtiene el puntero al objeto de clase más derivado.
dynamic_cast
devoid*
es ilegal - el tipo fundido desde debe ser polimórfico - contener al menos una función virtual (recuentos destructor virtual también).
Puede convertir un puntero al tipo polimórfico en void *
, pero no al revés.
En 5.2.7 - Dynamic cast [expr.dynamic.cast]
dice que para dynamic_cast<T>(v)
:
T
es un tipo de puntero, v
a bordo otro valor p de un puntero para completar tipo de claseT
es un tipo de referencia, v
será un lvalue de un tipo de clase completo (gracias usta para comentar sobre mi falta esto)...
v
será un puntero a un valor-I o de un tipo polimórficoAsí que no, un valor (void*)
no está permitido.
Vamos a pensar en lo que podría significar su solicitud: Digamos que tienes un puntero que es realmente a un Derived1*
, pero el código dynamic_cast
-ing sólo sabe que es un void*
.Supongamos que intenta convertirlo a Derived2*
, donde ambas clases derivadas tienen una base común. Superficialmente, podría pensar que todos los punteros apuntarían al mismo objeto Base
, que contendría un puntero a la tabla de despacho virtual relevante y RTTI, para que todo pueda colgarse. Sin embargo, tenga en cuenta que las clases derivadas pueden tener múltiples clases base y, por lo tanto, el subobjeto de clase Base
necesario podría no ser aquel al que apunta el Derived*
, disponible solo como void*
. No funcionaria Conclusión: el compilador necesita conocer estos tipos para poder realizar algunos ajustes en los punteros en función de los tipos involucrados.
Derived1* -----> [AnotherBase] [[VDT]Base] <-- but, need a pointer to start of [extra members] this sub-object for dynamic_cast
(Algunas respuestas hablan de la necesidad de que el puntero está fundición de ser de un tipo polimórfico, que tiene funciones virtuales. Eso es lo único válido, pero un poco engañoso. Como se puede ver arriba, incluso si el void*
es de ese tipo, aún no funcionaría de manera confiable sin la información de tipo completo, ya que el problema real es que void*
presuntamente apunta al inicio del objeto derivado, mientras que se necesita un puntero al subobjeto de la clase base de donde deriva el tipo fundido.)
Si T es un tipo de puntero, v será un valor de r de un puntero para completar el tipo de clase, ... Si T es un tipo de referencia, v será un valor l de un tipo de clase completo, ... – usta
@usta: fijo , Gracias. –
A menos que el tipo de clase casted to sea una clase base accesible inequívoca del tipo de clase de la expresión fundida, en cuyo caso este último no necesita ser poli mórfico – usta