c++ coding-style smart-pointers tr1

c++ - Uso idiomático de std:: auto_ptr o solo uso shared_ptr?



coding-style smart-pointers (5)

"Usar shared_ptr everywhere" es una buena regla predeterminada, y ciertamente un buen punto de partida para enseñar a las personas sobre el uso responsable de los smart punteros. Sin embargo, no siempre es la mejor opción.

Si no necesita propiedad compartida, shared_ptr es overkill: tiene que asignar un bloque de memoria separado para el recuento de referencias, lo que puede afectar el rendimiento, y es menos claro en cuanto a la documentación.

Personalmente, uso std::auto_ptr en muchos lugares donde boost::scoped_ptr también es suficiente: por ejemplo, mantener un objeto asignado en el montón antes de que la propiedad se transfiera a otro lugar, donde las operaciones intermedias podrían arrojarse.

C ++ 0x tendrá std::unique_ptr para complementar std::shared_ptr como una mejor alternativa a std::auto_ptr . Cuando esté ampliamente disponible comenzaré a usar eso.

Ahora que shared_ptr está en tr1, ¿qué crees que debería pasarle al uso de std::auto_ptr ? Ambos tienen diferentes casos de uso, pero todos los casos de uso de auto_ptr se pueden resolver también con shared_ptr . ¿Va a abandonar auto_ptr o continuar auto_ptr en los casos en que quiera expresar explícitamente que solo una clase tiene propiedad en un punto dado?

Mi opinión es que el uso de auto_ptr puede agregar claridad al código, precisamente al agregar matices y una indicación del diseño del código, pero por otro lado, agrega otro sutil problema al capacitar a los nuevos programadores: necesitan entender los punteros inteligentes y los detalles finos de cómo funcionan. Cuando utiliza un solo puntero inteligente en cualquier lugar, puede establecer una regla para "ajustar todos los punteros en shared_ptr " y terminar con ello.

¿Cuál es su opinión sobre esto?


Creo que "ajustar todos los punteros en shared_ptr " debería ser el modo predeterminado, y es un consejo adecuado para los programadores junior. Sin embargo, en los casos de propiedad especial que mencionó, auto_ptr es de hecho más apropiado y se debe alentar su uso bajo tales circunstancias.


Creo que la mejor práctica es sustituir todos los usos de std::auto_ptr por boost::scoped_ptr menos que std::tr1::shared_ptr cumpla mejor con los requisitos, si no te importa usar Boost. Por otro lado, seguramente fue intencional que scoped_ptr no se incluyó en TR1.


auto_ptr también es bueno en las firmas. Cuando una función toma un valor auto_ptr<T> , significa que consumirá el T Si una función devuelve un auto_ptr<T> , está claro que renuncia a la propiedad. Esto puede comunicar tus intenciones sobre la vida.

Por otro lado, el uso de scoped_ptr<T> implica que no desea preocuparse por la vida útil de la T Esto también implica que puedes usarlo en más lugares. Ambos punteros inteligentes son opciones válidas, sin duda puede tener ambos en un solo programa.


Para proporcionar un poco más de munición al campo ''avoid std::auto_ptr '': auto_ptr se está desaprobando en el próximo estándar (C ++ 0x). Creo que esto solo es suficiente munición para que cualquier argumento use algo más.

Sin embargo, como mencionó Konrad Rudolph , el reemplazo predeterminado para auto_ptr probablemente debería ser boost::scoped_ptr . La semántica de scoped_ptr más estrechamente con las de auto_ptr y está destinada para usos similares. El próximo estándar C ++ 09 tendrá algo similar llamado unique_ptr.

Sin embargo, usar shared_ptr cualquier lugar donde se scoped_ptr no romperá nada, solo agregará un poco de ineficiencia para lidiar con el recuento de referencias si el objeto nunca va a ser realmente compartido. Por lo tanto, para los punteros de miembros privados que nunca se entregarán a otro objeto, use scoped_ptr . Si el puntero se entregará a otra cosa (esto incluye su uso en contenedores o si lo único que desea hacer es transferir la propiedad y no mantenerla o compartirla) - use shared_ptr .