2011-01-12 8 views
29

Tengo un puntero a un objeto. Me gustaría almacenarlo en dos contenedores que tienen la propiedad. Así que creo que sería bueno convertirlo en un shared_ptr de C++ 0x. ¿Cómo podría convertir un puntero sin formato a un shared_pointer?Crear shared_ptr desde el puntero sin formato

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

Gracias

Respuesta

28

Se necesitan para asegurarse de que no inicializa ambos objetos shared_ptr con el mismo puntero cruda, o se eliminarán dos veces. Un (pero sigue siendo malo) mejor manera de hacerlo:

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; 

ADVERTENCIA: el código anterior muestra las malas prácticas! raw_ptr simplemente no debería existir como una variable. Si inicializa directamente sus punteros inteligentes con el resultado de new, reduce el riesgo de inicializar accidentalmente otros punteros inteligentes de forma incorrecta. Lo que debe hacer es:

shared_ptr<classA> my_ptr(new classA); 

shared_ptr<classA> other_ptr(my_ptr); 

Lo bueno es que el código es más concisa también.

EDITAR

Probablemente debería elaborar sobre cómo funcionaría con un mapa. Si tuviera un puntero sin procesar y dos mapas, podría hacer algo similar a lo que mostré arriba.

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 exponer el puntero sin formato en una variable. Al hacer eso, le da a un mantenedor una oportunidad más fácil de arruinar y colocar el puntero RAW en otro puntero compartido. Solo use 'my_ptr (new ClassA());' De esa manera un mantenedor tiene que hacer un trabajo extra para arruinar las cosas. –

+0

@Martin York Estaba editando para incluir un punto al respecto; Añadiré una nota más explícita. Pero estás en lo cierto. :) – Dawson

+0

'// o shared_ptr my_ptr = raw_ptr;' está mal en 'std :: shared_ptr', porque debe ser explícito como' // o shared_ptr my_ptr (raw_ptr); '. – Justme0

3

Se puede utilizar una variedad de maneras, pero reset() sería bueno:

map1[ID].reset(obj); 

Y para hacer frente a la cuestión de tener dos mapas se refieren a la misma shared_ptr, podemos tener:

map2[ID] = map1[ID]; 

Tenga en cuenta que el truco en general para evitar una doble eliminación es tratar de evitar los punteros sin procesar en absoluto. Por lo tanto deben evitarse:

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

pero en su lugar poner el nuevo objeto montón directamente en un shared_ptr.

+0

no es mala práctica per se, es c-práctica! – g24l

Cuestiones relacionadas