Ho una struttura a oggetti costituita da shared_ptr
s, più weak_ptr
s per evitare la circolarità. I puntatori grezzi sono un no-go come boost::serialization
ha bisogno di ripristinare i puntatori condivisi e deboli durante la deserializzazione tramite il rilevamento degli oggetti come tempo di serializzazione. I modelli di vita dell'oggetto sono complessi (simulazione di particelle) ma interamente prevedibili. Ogni volta che uso weak_ptr::lock()
, sono sicuro che il puntatore è ancora valido. In genere, utilizzo lock().get()
in quanto ho bisogno dell'oggetto per un tempo molto breve.Portable hack per individuare il puntatore raw da weak_ptr
Ora, lock().get()
ha implicazioni sulle prestazioni, poiché incrementerà il conteggio condiviso (in lock()
) e quindi diminuirà poco dopo (il valore temporaneo shared_ptr
è stato distrutto).
Questo boost.devel post dal 2002 dice che mentre weak_ptr
è stato in fase di sviluppo, la funzionalità di accesso al puntatore prima direttamente è stato considerato (da nominare unsafe_get
o leak
), ma non sono mai arrivati alla realizzazione vera e propria. La sua assenza costringe il programmatore a utilizzare l'interfaccia subottimale in determinate condizioni.
Ora, la domanda è come per emulare il unsafe_get
/leak
, in altre parole, ottenere il puntatore prima da weak_ptr
, non valida a rischio del programmatore, solo la lettura (non scrivere) i dati. Posso immaginare che alcuni trucchi come scoprire l'offset del puntatore grezzo all'interno di shared_ptr
o simili farebbero il lavoro.
Sto usando boost::shared_ptr
, ma la soluzione potrebbe funzionare anche per C++ 11 std::shared_ptr
.
Una buona domanda, ma suona onestamente come i puntatori grezzi sarebbe l'affare migliore qui. Gestisci gli oggetti separatamente (ad esempio raggruppa tutte le tue particelle in un contenitore) e passa intorno a indicatori deboli. –
Penso che anche se usi l'oggetto per un breve periodo, dovresti tenere premuto il comando 'shared_ptr' mentre lo stai usando:' auto s = w.lock(); if (s) s-> doSomething(); 'Penso che usare' lock(). get() 'sia una cattiva pratica e non più veloce. È possibile che l'azione stessa dell'uso del puntatore possa effettivamente innescare l'ultimo 'shared_ptr' da morire. –
Se si conosce il punto debole della vita degli oggetti senza un '.lock()' non usare 'weak_ptr'. Hai provato che questo è un collo di bottiglia per le prestazioni come una parte? – Yakk