weak_ptr shared_ptr make_shared example c++ boost

c++ - make_shared - Obtener un impulso:: shared_ptr para esto



shared_ptr example (6)

¿Realmente está haciendo más copias compartidas de pFoo dentro de la barra? Si no estás haciendo algo loco por dentro, solo haz esto:

void bar(Foo &foo) { // ... }

Estoy haciendo un uso extenso de boost:shared_ptr en mi código. De hecho, la mayoría de los objetos que están asignados en el montón están en un shared_ptr . Desafortunadamente, esto significa que no puedo pasar this a ninguna función que tenga un shared_ptr . Considera este código:

void bar(boost::shared_ptr<Foo> pFoo) { ... } void Foo::someFunction() { bar(this); }

Hay dos problemas aquí. Primero, esto no se compilará porque el constructor T * para shared_ptr es explícito. En segundo lugar, si lo bar(boost::shared_ptr<Foo>(this)) a compilar con bar(boost::shared_ptr<Foo>(this)) habrá creado un segundo puntero compartido a mi objeto que eventualmente llevará a una doble eliminación.

Esto me lleva a mi pregunta: ¿Existe algún patrón estándar para obtener una copia del puntero compartido existente que usted sabe que existe dentro de un método en uno de esos objetos? ¿El uso de referencia intrusiva es mi única opción aquí?


Con C ++ 11 shared_ptr y enable_shared_from_this ahora está en la biblioteca estándar. El último es, como su nombre lo sugiere, para este caso exactamente.

http://en.cppreference.com/w/cpp/memory/shared_ptr

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

El ejemplo se basa en eso en los enlaces de arriba:

struct Good: std::enable_shared_from_this<Good>{ std::shared_ptr<Good> getptr() { return shared_from_this(); } };

utilizar:

std::shared_ptr<Good> gp1(new Good); std::shared_ptr<Good> gp2 = gp1->getptr(); std::cout << "gp2.use_count() = " << gp2.use_count() << ''/n'';


La función que acepta un puntero quiere hacer uno de dos comportamientos:

  • Posee el objeto que se está transfiriendo y elimínalo cuando se salga del alcance. En este caso, puede aceptar X * e inmediatamente ajustar un scoped_ptr alrededor de ese objeto (en el cuerpo de la función). Esto funcionará para aceptar "esto" o, en general, cualquier objeto asignado en el montón.
  • Comparta un puntero (no lo posee) con el objeto que se está pasando. En este caso, no desea usar un scoped_ptr en absoluto, ya que no desea eliminar el objeto al final de su función. En este caso, lo que teóricamente quieres es un shared_ptr (lo he visto llamar un linked_ptr en otro lugar). La biblioteca de impulso tiene una versión de shared_ptr , y esto también se recomienda en el libro Effective C ++ de Scott Meyers (elemento 18 en la 3ª edición).

Editar: Vaya, leí un poco la pregunta, y ahora veo que esta respuesta no está abordando exactamente la pregunta. Lo dejaré de todos modos, en caso de que esto pueda ser útil para cualquiera que trabaje con código similar.


Puede derivar de enable_shared_from_this y luego puede usar "shared_from_this ()" en lugar de "this" para generar un puntero compartido para su propio objeto.

Ejemplo en el enlace:

#include <boost/enable_shared_from_this.hpp> class Y: public boost::enable_shared_from_this<Y> { public: shared_ptr<Y> f() { return shared_from_this(); } } int main() { shared_ptr<Y> p(new Y); shared_ptr<Y> q = p->f(); assert(p == q); assert(!(p < q || q < p)); // p and q must share ownership }

Es una buena idea cuando se generan subprocesos desde una función de miembro para impulsar :: bind a shared_from_this () en lugar de esto. Garantizará que el objeto no se libere.


Simplemente use un puntero sin formato para su parámetro de función en lugar de shared_ptr. El objetivo de un puntero inteligente es controlar la duración del objeto, pero la duración del objeto ya está garantizada por las reglas de determinación del alcance de C ++: existirá al menos hasta el final de su función. Es decir, el código de llamada no puede posiblemente eliminar el objeto antes de que regrese su función; por lo tanto, la seguridad de un puntero "tonto" está garantizada, siempre y cuando no intente eliminar el objeto dentro de su función.

La única vez que necesita pasar un shared_ptr a una función es cuando desea pasar la propiedad del objeto a la función, o desea que la función haga una copia del puntero.