2010-04-26 17 views
17

¿Hay un deallocator RS-op en Boost para usar con boost::shared_ptr de objetos estáticos, etc.n-op para el impulso :: shared_ptr

Sé que es ultra-trivial para escribir, pero no lo hago quiero rociar mi código con funciones muy pequeñas si ya hay una disponible.

+4

Si no es necesario destruir el objeto, ¿por qué lo coloca en un shared_ptr en primer lugar? –

+5

Muy útil si te has pasado de la raya con punteros inteligentes en todas partes, y quieres pasar una pila o variable miembro a una función que requiere 'shared_ptr'. –

+1

@Mark Ransom: Me haces pensar en las bases de código que me hacen temblar. : P –

Respuesta

10

sí hay uno aquí:

#include <boost/serialization/shared_ptr.hpp> // for null_deleter 

class Foo 
{ 
    int x; 
}; 

Foo foo; 
boost::shared_ptr<Foo> sharedfoo(&foo, boost::serialization::null_deleter()); 

Hay, por supuesto, un peligro con el hecho de que lo que necesita saber la función que llama no almacenar el shared_ptr para su uso posterior, ya que en realidad va en contra de la política de shared_ptr en que el objeto subyacente sigue siendo válido hasta el de la última instancia de shared_ptr.

+0

Parece que esto es lo más cercano posible. –

1

¿No sería más limpio simplemente tomar una referencia adicional para que nunca se llame al deslocalizador? (Aunque todavía no es muy limpio.)

No puedo decir que no haya ninguna función en Boost que haga el trabajo, pero no parece que sea algo que quisieran incluir.

EDIT: Después de leer los comentarios y un poco de documentación, que se reduce a esto: la fuga

  1. de referencia. En algún punto, ejecute esto:

    new shared_ptr(my_global_shared_ptr); 
    

    Ventajas: conceptualmente fácil. Desventajas: estás filtrando algo en el montón.

  2. Desbloqueo personalizado. Como shared_ptr requiere poco de la función de desasignación, una función de identidad anónima como la proporcionada en la otra respuesta funcionaría bien.

    Ventajas: aprovecha Boost y no tiene absolutamente ningún gasto. Disconvantages: requiere un poco de documentación.

  3. Objeto global no estático. Si hay un shared_ptr global para su objeto, ese debería ser el único medio de acceso al mismo. Reemplace la declaración de global por shared_ptr intializada por new my_class. Creo que esto es lo mejor

+0

¿Cómo harías para tomar una referencia adicional? No pensé que se podía acceder al conteo de 'shared_ptr's. –

+0

@Mark Ransom: creo que quiere decir copiar el 'shared_ptr' y almacenarlo en alguna parte. –

+0

Sí, pero esa copia adicional será destruida eventualmente. No parece muy práctico. –

3

solución utiliza Boost.Lambda:

#include <boost/shared_ptr.hpp> 
#include <boost/lambda/lambda.hpp> 

int main() 
{ 
    int *p = new int(5); 

    { 
     boost::shared_ptr<int> sp(p, boost::lambda::_1); 
    } 

    delete p; 
} 

'boost :: lambda :: _ 1' crea un vacío funtor que toma un argumento.

Es probable que desee poner un // comentario allí para que las personas sepan por qué lo hizo.

+1

Eso caería en la categoría * "No quiero rociar mi código" *. –

+0

Esta solución implica más rociado que usar un impulso hipotético :: no_op_deallocator() en lugar del boost :: lambda :: _ 1? – scjohnno

+2

Una solución muy inteligente, pero creo que preferiría tener la función trivial en alguna parte y darle un nombre descriptivo. –

0

FWIW, esto es lo que estoy usando. Lo uso en pruebas unitarias para adaptar un local en un shared_ptr.

// The class NoOp_sptr_Deleter can be used to construct a shared_ptr<>() 
// that will NOT delete the pointee. 
// This can be helpful in unit-testing. Wrapping a local as a shared_ptr. 
// Do take care with the lifetimes though. 
struct NoOp_sptr_Deleter 
{ 
    void operator()(void const *) const {} 
}; 

template<typename T> 
boost::shared_ptr<T> FakeSharedPtrFromRef(T& aRef) 
{ 
    return boost::shared_ptr<T>(&aRef, NoOp_sptr_Deleter()); 
} 
+0

El OP solicitó específicamente soluciones que ya proporciona Boost o stdlib. Él * sabe * que es ultra trivial escribir tal función/functor. – Xeo

Cuestiones relacionadas