dynamic_cast da “* vuoto”
-
29-09-2019 - |
Domanda
questo , void*
non ha informazioni RTTI, quindi, colata da void*
non è legale e ha senso.
Se non ricordo male, dynamic_cast
da void*
stava lavorando gcc.
Potete per favore chiarire la questione.
Soluzione
dynamic_cast
funziona solo sui tipi polimorfici, cioè classi contenenti funzioni virtuali.
In gcc è possibile dynamic_cast
a , ma non void*
dal :
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
}
Altri suggerimenti
In 5.2.7 - Dynamic cast [expr.dynamic.cast]
si dice che per dynamic_cast<T>(v)
:
- Se
T
è un tipo di puntatore,v
deve essere un rvalue di un puntatore al tipo di classe completa ??li> - Se
T
è un tipo di riferimento,v
deve essere un lvalue di un tipo di classe completa (grazie usta per commentando il mio manca questo)
...
- In caso contrario,
v
deve essere un puntatore o un lvalue di un tipo polimorfico
Quindi, no, un (void*)
Valore non è consentito.
pensare di Let su ciò che la vostra richiesta potrebbe significare: dici che hai un puntatore che è davvero a un Derived1*
, ma il codice dynamic_cast
-ing sa solo che è un void*
. Diciamo che si sta cercando di lanciare ad un Derived2*
, dove entrambe le classi derivate hanno una base comune. Superficialmente, si potrebbe pensare tutti i puntatori sarebbe puntare allo stesso oggetto Base
, che conterrebbe un puntatore alla tabella di invio virtuale pertinenti e RTTI, quindi tutto potrebbe appendere insieme. Ma, considerare che le classi derivate possono avere più classi di base, e quindi la sub-oggetto classe Base
necessaria potrebbe non essere quello a cui l'Derived*
- disponibile solo come void*
- punta. Non funzionerebbe. Conclusione: le esigenze del compilatore di conoscere questi tipi in modo che possa eseguire qualche aggiustamento per i 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 stai lanciando da essere di un tipo polimorfico, con funzioni virtuali. Questo è tutto valido, ma un po 'fuorviante. Come potete vedere sopra, anche se il void*
è quello di un tale tipo ancora non avrebbe funzionato in modo affidabile senza tutte le informazioni di tipo, come il problema reale è che void*
è presumibilmente indicando l'inizio del oggetto derivato, mentre è necessario un puntatore al sub-oggetto classe base da cui il cast Tipo deriva -per).
E 'vero che non può essere void*
dynamically_cast
ed da.
Si sono probabilmente mis-ricordo. 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:
non può dynamic_cast 'p' (di tipo '* vuoto') di tipo 'struct A *' (fonte non è un puntatore alla classe)
Credo che si confondono con dynamic_cast
a void*
. Questo è legale e ottiene il puntatore all'oggetto classe più derivata.
dynamic_cast
da void*
è illegale - il tipo pressofuso da deve essere polimorfico -. Contenere almeno una funzione virtuale (conta distruttore virtuale troppo)
Si può lanciare un puntatore al tipo polimorfico a void *
, ma non viceversa.