Secondo this, void*
non ha informazioni RTTI, pertanto il casting da void*
non è legale e ha senso.dynamic_cast da "void *"
Se non ricordo male, dynamic_cast
da void*
funzionava su gcc.
Potete chiarire il problema.
Secondo this, void*
non ha informazioni RTTI, pertanto il casting da void*
non è legale e ha senso.dynamic_cast da "void *"
Se non ricordo male, dynamic_cast
da void*
funzionava su gcc.
Potete chiarire il problema.
dynamic_cast
funziona solo sui tipi polimorfici, cioè classi contenenti funzioni virtuali.
In gcc si può dynamic_cast
avoid*
ma non da:
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
}
È vero che void*
non può essere dynamically_cast
da.
Probabilmente ti stai ricordando male. Con g ++ 4.5 e il seguente codice
struct A {
virtual ~A();
};
int main() {
A a;
void *p = &a;
A* pa = dynamic_cast<A*>(p);
}
ottengo il seguente errore:
cannot dynamic_cast 'p' (of type 'void*') to type 'struct A*' (source is not a pointer to class)
Credo che si confondono con dynalic_cast
-void*
. È legale e ottiene il puntatore all'oggetto di classe più derivato.
dynamic_cast
davoid*
è illegale - il tipo pressofuso da deve essere polimorfico - contiene almeno una funzione virtuale (conteggi distruttore virtuale troppo).
È possibile eseguire il cast di un puntatore a tipo polimorfico su void *
, ma non viceversa.
In 5.2.7 - Dynamic cast [expr.dynamic.cast]
si dice che per dynamic_cast<T>(v)
:
T
è un tipo di puntatore, v
sarà un rvalue di un puntatore per completare tipo di classeT
è un tipo di riferimento, v
sarà un lvalue di un tipo di classe completo (grazie usta per commentare il mio mancante)...
v
sarà un puntatore o un lvalue di tipo polimorficoQuindi, no, un valore (void*)
non è permesso.
Pensiamo a ciò che la vostra richiesta potrebbe significare: dicono che hai un puntatore che è davvero a un Derived1*
, ma il codice dynamic_cast
-ing sa solo che è un void*
.Diciamo che stai provando a trasmetterlo a un Derived2*
, dove entrambe le classi derivate hanno una base comune. A livello superficiale, si potrebbe pensare che tutti i puntatori puntino allo stesso oggetto Base
, che conterrebbe un puntatore alla tabella di distribuzione virtuale e RTTI rilevanti, quindi tutto potrebbe bloccarsi insieme. Tuttavia, si consideri che le classi derivate possono avere più classi base, e quindi il necessario oggetto secondario della classe Base
potrebbe non essere quello a cui punta Derived*
- disponibile solo come void*
. Non funzionerebbe. Conclusione: il compilatore deve conoscere questi tipi in modo che possa eseguire alcuni aggiustamenti ai puntatori in base ai tipi coinvolti.
Derived1* -----> [AnotherBase] [[VDT]Base] <-- but, need a pointer to start of [extra members] this sub-object for dynamic_cast
(Alcune risposte parlano della necessità per il puntatore si sta gettando da essere di un tipo polimorfico, con funzioni virtuali. Questo è tutto valido, ma un po 'fuorviante. Come potete vedere sopra, anche se il void*
è a un tal tipo che ancora non funzionerebbe in modo affidabile senza le informazioni di tipo completo, poiché il vero problema è che void*
sta presumibilmente puntando all'avvio dell'oggetto derivato, mentre è necessario un puntatore all'oggetto secondario della classe base da cui deriva il cast-to type.)
Se T è un tipo di puntatore, v deve essere un valore di un puntatore per completare il tipo di classe, ... Se T è un tipo di riferimento, v deve essere un lvalue di un tipo di classe completo, ... – usta
@usta: fixed , Grazie. –
A meno che il tipo di classe assegnato a una classe base accessibile non ambigua del tipo di classe dell'espressione casted-from, nel qual caso quest'ultimo non deve essere morfica. – usta