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 ununique_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 queunique_ptr
puede hacer, esta es probablemente su mejor opción. (Por supuesto, unshared_ptr
puede hacer mucho más también, pero también se puede usar simplemente como un reemplazounique_ptr
paraunique_ptr
). -
boost::scoped_ptr
es similar aunique_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 aunique_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.