unique_ptr smart shared_ptr make_unique c++ boost c++11 unique-ptr

shared_ptr - smart pointers c++ 11



unique_ptr boost equivalent? (5)

¿Qué hay de unique_ptr de la biblioteca interprocess ?

¿Hay alguna clase equivalente para C ++ 1x std :: unique_ptr en las bibliotecas de impulso? El comportamiento que estoy buscando es poder tener una función de fábrica segura para excepciones, como tal ...

std::unique_ptr<Base> create_base() { return std::unique_ptr<Base>(new Derived); } void some_other_function() { std::unique_ptr<Base> b = create_base(); // Do some stuff with b that may or may not throw an exception... // Now b is destructed automagically. }

EDITAR: En este momento, estoy usando este truco, que parece lo mejor que puedo obtener en este momento ...

Base* create_base() { return new Derived; } void some_other_function() { boost::scoped_ptr<Base> b = create_base(); // Do some stuff with b that may or may not throw an exception... // Now b is deleted automagically. }


A partir de Boost 1.57 hay una implementación de unique_ptr oficial en la biblioteca Boost.Move .

De la documentation :

(...) un reemplazo directo para std :: unique_ptr, también utilizable de compiladores C ++ 03.

El código está disponible en el archivo de encabezado <boost/move/unique_ptr.hpp> y vive en el espacio de nombres boost::movelib . Además, la biblioteca Boost.Move proporciona la función de fábrica make_unique() en <boost/move/make_unique.hpp> , también en el espacio de nombres boost::movelib .

Por lo tanto, el ejemplo de la pregunta podría implementarse de esta manera:

#include <boost/move/unique_ptr.hpp> using boost::movelib::unique_ptr; unique_ptr<Base> create_base() { return unique_ptr<Base>(new Derived); }

Vea un ejemplo en vivo en Wandbox . Tenga en cuenta que el código compila bien con gcc 4.6.4 en el modo C ++ 98 (!).

Lo que es interesante en boost::movelib::unique_ptr cuando se aplica a su caso con clases base / derivadas, la implementación proporciona una verificación en tiempo de compilación para la declaración de un destructor virtual en la clase base. Si lo omite, el código no se compilará (haga clic en el botón "Ejecutar (...)" para ver el mensaje de error del compilador).

Un problema menor es que incluye venir del directorio boost/move , pero el código vive en el espacio de nombres boost::movelib (diferencia sutil, pero puede ser molesto).

Vea también un hilo en la lista de correo de impulso para más detalles.

Gracias a Ion Gaztañaga por esta pieza de código absolutamente única y útil.


Es posible que desee probar la implementación de la ''prueba de concepto'' unique_ptr<> Howard Hinnant para C ++ 03 (exención de responsabilidad, no lo he hecho):

Uno de sus ejemplos es devolver un unique_ptr<int> :

unique_ptr<int> factory(int i) { return unique_ptr<int>(new int(i)); }


He usado unique_ptr Howard Hinnant. Si no eres realmente bueno para leer los errores de metaprogramación de tu compilador, es posible que quieras mantenerte alejado. Sin embargo, actúa como un único píxel en el 90% de los casos.

De lo contrario, sugeriría pasar los parámetros como boost::scoped_ptr& y cambiar internamente para robar la propiedad. Para obtener valores de retorno de estilo unique_ptr use un auto_ptr . Capture el valor de retorno auto_ptr en un shared_ptr o scoped_ptr para evitar el uso de auto_ptr directamente.


No es posible crear algo como unique_ptr sin C ++ 0x (donde forma parte de la biblioteca estándar, por lo que Boost no necesita proporcionarlo).

Específicamente sin referencias rvalue, que son una característica en C ++ 0x, una implementación robusta de unique_ptr es imposible, con o sin Boost.

En C ++ 03, hay algunas alternativas posibles, aunque cada uno tiene sus fallas.

  • boost::shared_ptr es probablemente el reemplazo más simple en términos de capacidades. Puedes usarlo de forma segura en cualquier lugar donde de otra manera usas un unique_ptr y funcionaría. Simplemente no sería tan eficiente, debido al recuento de referencias agregado. Pero si está buscando un reemplazo simple que pueda manejar todo lo que unique_ptr puede hacer, esta es probablemente su mejor opción. (Por supuesto, un shared_ptr puede hacer mucho más también, pero también se puede usar simplemente como un reemplazo unique_ptr para unique_ptr ).
  • boost::scoped_ptr es similar a unique_ptr pero no permite la transferencia de propiedad. Funciona muy bien siempre que el puntero inteligente esté destinado a conservar la propiedad exclusiva a lo largo de su vida útil.
  • std::auto_ptr funciona de manera muy similar a unique_ptr , pero tiene algunas limitaciones, principalmente que no se puede almacenar en contenedores de biblioteca estándar. Si simplemente está buscando un puntero que permita la transferencia de propiedad, pero que no está destinado a ser almacenado en contenedores o copiado, probablemente sea una buena apuesta.