Voglio mantenere il comportamento intelligente di std::shared_ptr
. Quindi c'è un modo per lanciare un puntatore void condiviso su un altro tipo senza confondere il conteggio dei riferimenti? Non riesco a ottenere il puntatore raw e creare un nuovo puntatore condiviso da esso.C'è un modo per trasmettere shared_ptr <void> a shared_ptr <T>?
risposta
È possibile utilizzare i cast del puntatore da rob mayoff's answer; ma fa attenzione. E 'facile da innescare involontariamente un comportamento indefinito qui:
struct MyClass {};
void* rawPtr = new MyClass;
shared_ptr<void> exampleVoid(rawPtr); // Undefined behavior;
// calls delete (void*)ptr;
shared_ptr<void> exampleVoidCons(new MyClass);
// OK, calls shared_ptr<void>::shared_ptr<MyClass>(MyClass*) which
// makes a deleter calling delete (MyClass*)ptr;
shared_ptr<MyClass> example(new MyClass); // OK, calls delete (MyClass*)ptr;
shared_ptr<void> castToVoid = static_pointer_cast<void>(example);
// OK, shared_ptr's deleter is erased so this still calls delete (MyClass*)ptr;
In genere questo comportamento indefinito si tradurrà in distruttore del tipo non essere chiamato. Ad esempio, see the output on ideone e nota che la versione inserita in un void*
non stampa mai che è stata distrutta.
See C++ 11 5.3.5 [expr.delete]/3:
Nella prima alternativa (cancella oggetto), se il tipo statico dell'oggetto da cancellare è diverso dal suo tipo dinamico, il tipo statico deve essere una classe base del tipo dinamico dell'oggetto da eliminare e il tipo statico deve avere un distruttore virtuale o il comportamento non è definito.
Poiché l'oggetto reale sarà mai un tipo dinamico void
, e void
è mai una classe di base di tipo dinamico, delete
ing un void*
innesca comportamento indefinito.
Una versione precedente di questa risposta aveva una porzione 'shared_ptr exampleVoid (new MyClass)' non corretta che ho ora fisso. Sentiti libero di rimuovere i voti per aver messo il mio piede nella mia bocca: P –
+1 per fornire una risposta più completa, riconoscendo anche che hai commesso un errore, ammettendo e correggendo dovrebbe essere incoraggiato, molti di noi sono qui per imparare e questo è parte del processo. –
Sono arrabbiato perché hai cancellato la risposta per la modifica proprio mentre stavo scrivendo un commento sull'esempio errato ;-) –
È possibile utilizzare std::static_pointer_cast
o std::dynamic_pointer_cast
a seconda del tipo di trasmissione desiderata.
Possibile duplicato di http://stackoverflow.com/questions/6795629/how-does-one-downcast-a-stdshared-ptr –
@BillyONeal: No, 'void' non è una classe base di tutti i tipi. Il C++ non è un OO puro. – MSalters
@MSalters: è per questo che ho scritto il commento anziché votare per chiudere (non volevo volerlo fare unilateralmente) –