2011-01-12 18 views
29

Ho un puntatore a un oggetto. Vorrei memorizzarlo in due contenitori che hanno entrambi la proprietà. Quindi penso che sarebbe bello renderlo un shared_ptr di C++ 0x. Come posso convertire un puntatore raw in un shared_pointer?Creazione di shared_ptr dal puntatore raw

typedef unordered_map<string, shared_ptr<classA>>MAP1; 
MAP1 map1; 
classA* obj = new classA(); 
map1[ID] = how could I store obj in map1?? 

Grazie

risposta

28

È necessario assicurarsi che non si inizializza entrambi gli oggetti shared_ptr con lo stesso puntatore cruda, oppure verranno eliminati due volte. Un modo migliore (ma ancora male) per farlo:

classA* raw_ptr = new classA; 
shared_ptr<classA> my_ptr(raw_ptr); 

// or shared_ptr<classA> my_ptr = raw_ptr; 

// ... 

shared_ptr<classA> other_ptr(my_ptr); 
// or shared_ptr<classA> other_ptr = my_ptr; 
// WRONG: shared_ptr<classA> other_ptr(raw_ptr); 
// ALSO WRONG: shared_ptr<classA> other_ptr = raw_ptr; 

ATTENZIONE: il codice qui sopra mostra una cattiva pratica! raw_ptr semplicemente non dovrebbe esistere come variabile. Se si inizializzano direttamente i puntatori intelligenti con il risultato di new, si riduce il rischio di inizializzare accidentalmente altri puntatori intelligenti in modo errato. Quello che dovresti fare è:

shared_ptr<classA> my_ptr(new classA); 

shared_ptr<classA> other_ptr(my_ptr); 

Ciò che è bello è che il codice è più conciso pure.

EDIT

probabilmente dovrei elaborare su come avrebbe funzionato con una mappa. Se tu avessi un puntatore raw e due mappe, potresti fare qualcosa di simile a quello che ho mostrato sopra.

unordered_map<string, shared_ptr<classA> > my_map; 
unordered_map<string, shared_ptr<classA> > that_guys_map; 

shared_ptr<classA> my_ptr(new classA); 

my_map.insert(make_pair("oi", my_ptr)); 
that_guys_map.insert(make_pair("oi", my_ptr)); 
// or my_map["oi"].reset(my_ptr); 
// or my_map["oi"] = my_ptr; 
// so many choices! 
+2

Don; t esporre il puntatore raw in una variabile. In questo modo si offre a un maintainer un'opportunità più semplice per rovinare e mettere il puntatore RAW in un altro puntatore condiviso. Basta usare 'my_ptr (new ClassA());' In questo modo un manutentore deve fare del lavoro extra per rovinare tutto. –

+0

@ Martin York Stavo modificando per includere un punto a riguardo; Aggiungerò una nota più esplicita. Ma tu hai ragione. :) – Dawson

+0

'// o shared_ptr my_ptr = raw_ptr;' non è corretto in 'std :: shared_ptr', perché dovrebbe essere esplicito come' // o shared_ptr my_ptr (raw_ptr); '. – Justme0

3

È possibile utilizzare una varietà di modi, ma reset() sarebbe bene:

map1[ID].reset(obj); 

E per affrontare il problema di avere due carte si riferiscono alla stessa shared_ptr, possiamo avere:

map2[ID] = map1[ID]; 

Si noti che il trucco in generale per evitare una doppia eliminazione è cercare di evitare affatto i puntatori grezzi. Quindi evitare:

classA* obj = new classA(); 
map1[ID].reset(obj); 

ma invece mettere il nuovo oggetto mucchio direttamente in uno shared_ptr.

+0

non è una cattiva pratica in sé, è c-practice! – g24l

Problemi correlati