Obteniendo un ptr normal de boost::shared_ptr?

3 minutos de lectura

tengo algo como boost::shared_ptr<Type> t(makeSomething(), mem_fun(&Type::deleteMe))
Ahora necesito llamar a la función de estilo C que requiere un puntero para Type. ¿Cómo lo obtengo de boost::shared_ptr?

Utilizar el get() método:

boost::shared_ptr<foo> foo_ptr(new foo());
foo *raw_foo = foo_ptr.get();
c_library_function(raw_foo);

Asegúrese de que su shared_ptr no sale del alcance antes de que la función de la biblioteca termine con él; de lo contrario, podría resultar malo, ya que la biblioteca puede intentar hacer algo con el puntero después de que se haya eliminado. Tenga especial cuidado si la función de biblioteca mantiene una copia del puntero sin procesar después de que regrese.

  • quizás debería notar algo acerca de que shared_ptr sale del alcance antes de que c_library_function haya hecho lo suyo con raw_foo.

    – falstro

    2 de febrero de 2009 a las 22:06

  • roe: lo sé, solo necesitaba saber sobre get :). ¡Gracias Adán! 😀

    usuario34537

    2 de febrero de 2009 a las 22:07

  • Hola, @Adam Rosenfield, ¿podría explicar qué sucede en un escenario donde ocurre una excepción en el interior? c_library_function. ¿Eso significa que el raw_foo se deja colgado? o foo_ptr continúa y elimina raw_foo, ya que raw_foo está en manos de foo_ptr?

    – thassan

    5 de marzo de 2014 a las 4:46


Avatar de usuario de Michael Burr
miguel rebabas

Otra forma de hacerlo sería utilizar una combinación de los & y * operadores:

boost::shared_ptr<foo> foo_ptr(new foo());
c_library_function( &*foo_ptr);

Si bien personalmente preferiría usar el get() (realmente es la respuesta correcta), una ventaja que tiene es que puede usarse con otras clases que sobrecargan operator* (desreferencia de puntero), pero no proporciona una get() método. Podría ser útil en una plantilla de clase genérica, por ejemplo.

  • Me gustó tu respuesta un poco más que Adams, lo siento Adam.

    usuario34537

    2 de febrero de 2009 a las 23:50

  • @ acidzombie24 – No estoy seguro de por qué te gusta más esto. Es mejor usar el método Get() en probablemente el 99% o más de los casos.

    – Michael Burr

    3 de febrero de 2009 a las 8:43

  • Ese enfoque activará afirmaciones para punteros NULL. No es bueno.

    – Drew Dorman

    3 de marzo de 2009 a las 22:00

  • @DrewDormann hizo un buen punto aquí, acidzombie24. Vas a tener problemas con los punteros nulos.

    – Volpato

    10/09/2013 a las 18:22

  • En C++ moderno, &* ahora cae en la temida categoría de “Comportamiento indefinido”, y ya no es equivalente a .get(). .get() manejará correctamente nullptrcomo señaló @DrewDormann, pero incluso si &* no desencadena una afirmación, su compilador mayo trátalo como si pudiera nunca seas nulo. En particular, if (&*x == nullptr) no lo haré producir el mismo comportamiento que if (x.get() == nullptr) en muchos compiladores modernos, que tratarán al primero como siempre falso!

    – Sean Werkema

    22 de septiembre a las 17:06

avatar de usuario de cmp
cmp

Para std::shared_ptr (C++11 en adelante), también hay un método get para obtener el puntero sin procesar. Enlace

¿Ha sido útil esta solución?