2009-03-07 11 views
43

Tengo muchos objetos boost::shared_ptr<MyClass>, y en algún momento intencionalmente quiero delete algunos de ellos para liberar algo de memoria. (Sé que en ese momento ya no necesitaré los objetos apuntados a MyClass). ¿Cómo puedo hacer eso?Cómo eliminar intencionalmente un impulso :: shared_ptr?

Supongo que no puede simplemente llamar al delete() con el puntero sin procesar que obtengo con get().

que he visto en una función get_deleter(shared_ptr<T> const & p)boost::shared_ptr, pero no estoy seguro de cómo usarlo, y también se dice experimental justo al lado de ella. (Creo que tengo Boost 1.38.)

¿Tal vez simplemente asigne un nuevo boost::shared_ptr vacío a la variable? Eso debería descartar el valor anterior y eliminarlo.

+15

NOOOOO: No llame a eliminar después de una llamada a get(). El puntero inteligente todavía tiene una copia y llamará a eliminar cuando libere el objeto. –

Respuesta

80

que acaba de hacer

ptr.reset(); 

Véase el shared_ptr manual. Es equivalente a

shared_ptr<T>().swap(ptr) 

Usted llama reset en cada puntero inteligente que no se debe hacer referencia al objeto más. El último reset (o cualquier otra acción que ocasione que la cuenta de referencia caiga a cero, en realidad) hará que el objeto sea liberado usando el eliminador automáticamente.

Quizás se encuentre interesado en el Smart Pointer Programming Techniques. Tiene una entrada sobre delayed deallocation.

8

El punto de boost::shared_ptr<T> es que el objeto pointee se borrará exactamente en el momento en ninguna shared_ptr<T> s punto en el que - es decir, cuando el último shared_ptr<T> apuntando a este objeto sale del ámbito o se reasigna para apuntar a un objeto diferente Por lo tanto, todo lo que tiene que hacer para eliminar un objeto es asegurarse de que no haya shared_ptr<T> s apuntando a él. P.ej. si solo tiene un único shared_ptr<T> llamado p apuntando a un objeto, permita que caiga fuera del alcance, o llame al p.reset() (equivalente a p = NULL para un puntero simple), o asígnelo para apuntar a otra cosa.

Si tiene dos shared_ptr<T> s apuntando al objeto, tendrá que reasignarlos a ambos.

EDIT: Gracias a dehmann por señalar que no es p = NULL; código realidad válida para un shared_ptr<T> ... :)

+3

Suena bien, pero una cosa: no se puede escribir p = NULL, porque p es un shared_ptr, no un puntero. – Frank

+1

Sí, para una pregunta relacionada sobre cómo usar NULL cuando se usa shared_ptrs, vea http://stackoverflow.com/questions/621220/null-pointer-with-boostsharedptr/621249#621249 –

+1

@dehmann: Vaya, está absolutamente derecho ... –

4

Lo que se quiere hacer es devolver referencias débiles utilizando boost::weak_ptr que se pueden convertir a una shared_ptr cuando sea necesario. Esto puede permitirle controlar la vida útil del objeto en el shared_ptr y aquellos que desean acceder a él pueden conservar el weak_ptr e intentar convertirlo a un shared_ptr. Si esa conversión falla, pueden volver a realizar una consulta y devolver el objeto a la memoria.

9

Si desea poder eliminar objetos intencionalmente (lo hago todo el tiempo), entonces tiene que usar la propiedad individual. Ha sido atraído a usar shared_ptr cuando no es apropiado para su diseño.

Cuestiones relacionadas