dynamic_cast da “void *”

In base a questo , void* non ha informazioni RTTI, pertanto la trasmissione da void* non è legale e ha senso.

Se ricordo bene, dynamic_cast from void* stava lavorando su gcc.

Puoi chiarire il problema.

dynamic_cast funziona solo su tipi polimorfi, cioè classi che contengono funzioni virtuali.

In gcc puoi dynamic_cast per void* ma non da :

 struct S { virtual ~S() {} }; int main() { S* p = new S(); void* v = dynamic_cast(p); S* p1 = dynamic_cast(v); // gives an error } 

In 5.2.7 - Dynamic cast [expr.dynamic.cast] dice che per dynamic_cast(v) :

  • Se T è un tipo di puntatore, v deve essere un valore di un puntatore per completare il tipo di class
  • Se T è un tipo di riferimento, v deve essere un lvalue di un tipo di class completo (grazie usta per commentare questo mio mancante)

  • Altrimenti, v deve essere un puntatore a o un lvalue di un tipo polimorfico

Quindi, no, un valore (void*) non è permesso.

Pensiamo a cosa potrebbe significare la tua richiesta: diciamo che hai un puntatore che è davvero un Derived1* , ma il codice dynamic_cast -ing sa solo che è un void* . Diciamo che stai provando a lanciarlo su Derived2* , dove entrambe le classi derivate hanno una base comune. Superficialmente, si potrebbe pensare che tutti i puntatori puntino allo stesso object Base , che conterrebbe un puntatore alla tabella di distribuzione virtuale e RTTI rilevanti, in modo che tutto possa rimanere unito. Tuttavia, si consideri che le classi derivate possono avere più classi base, e quindi l’object secondario della class Base necessario potrebbe non essere quello a cui punta il 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] <- ma serve un puntatore all'inizio
                  [membri extra] questo sottooggetto per dynamic_cast

(Alcune risposte parlano della necessità che il puntatore da cui si esegue il casting sia di tipo polimorfico, con funzioni virtuali. Tutto ciò è valido, ma un po 'fuorviante. Come si può vedere sopra, anche se il void* è tale scriverlo non funzionerebbe in modo affidabile senza le informazioni complete del tipo, poiché il vero problema è che void* presumibilmente sta puntando all'avvio dell'object derivato, mentre è necessario un puntatore all'object secondario della class base da cui il cast digitare deriva.)

È vero che void* non può essere dynamically_cast da dynamically_cast ed.

Probabilmente 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(p); } 

Ottengo il seguente errore:

can not dynamic_cast ‘p’ (di tipo ‘void *’) per scrivere ‘struct A *’ (source non è un puntatore alla class)

Immagino tu confonda con dynalic_cast a void* . È legale e ottiene il puntatore all’object di class più derivato.

dynamic_cast from void* è illegale – il tipo cast da deve essere polimorfico – contiene almeno una funzione virtuale (anche il distruttore virtuale conta).

Puoi lanciare un puntatore al tipo polimorfico per void * , ma non viceversa.