2010-10-07 40 views
6

Tengo una aplicación C++ que hace un uso extenso de los punteros para mantener estructuras de datos bastante complejas. La aplicación realiza simulaciones matemáticas en enormes conjuntos de datos (que podrían tomar varios GB de memoria) y se compila utilizando Visual Studio de Microsoft.Introducción a los punteros inteligentes en C++

Ahora estoy reelaborando una parte importante de la aplicación. Para reducir errores (punteros colgantes, fugas de memoria, ...) quisiera comenzar a usar punteros inteligentes. Sacrificar la memoria o el rendimiento es aceptable siempre que sea limitado.

En la práctica, la mayoría de las clases se mantienen en grupos grandes (un grupo por clase) y aunque las clases pueden referirse entre sí, podría considerar el grupo como propietario de todas las instancias de esa clase. Sin embargo, si el grupo decide eliminar una instancia, no quiero que ninguna de las otras clases que aún hacen referencia a la instancia eliminada tenga un puntero colgante.

En otra parte guardo una colección de punteros a las instancias que son entregadas por otros módulos en la aplicación. En la práctica, los otros módulos mantienen la propiedad de la instancia aprobada, pero en algunos casos, los módulos no quieren ocuparse de la propiedad y solo quieren pasar la instancia a la colección, diciéndole "ahora es tuyo, gestiónalo".

¿Cuál es la mejor manera de comenzar a introducir punteros inteligentes? Simplemente reemplazar punteros [al azar] con punteros inteligentes no parece una forma correcta, y probablemente no ofrece todas las ventajas (o ninguna de ellas) de los punteros inteligentes. Pero, ¿qué es un método mejor?

¿Qué tipos de indicadores inteligentes debo investigar más? A veces uso std :: auto_ptr para la desasignación de la memoria asignada localmente, pero parece que se ha depreciado en C++ 0x. ¿Es std :: unique_ptr una mejor alternativa? ¿O debería ir directamente a punteros compartidos u otros tipos de punteros inteligentes?

La pregunta Replacing existing raw pointers with smart pointers parece similar, pero en lugar de preguntar qué tan fácil es, me pregunto cuál sería el mejor enfoque y qué tipo de punteros inteligentes son los más adecuados.

Gracias de antemano por sus ideas y sugerencias.

Respuesta

1

Estas son las 3 variedades que se encuentran en el nuevo estándar de C++ 11 (unique_ptr reemplaza auto_ptr)

http://www.stroustrup.com/C++11FAQ.html#std-unique_ptr

http://www.stroustrup.com/C++11FAQ.html#std-shared_ptr

http://www.stroustrup.com/C++11FAQ.html#std-weak_ptr

se puede leer el texto para cada puntero y hay una explicación de cuándo usarlo allí. Para la gestión de la memoria local unique_ptr es la elección. No es copiable pero se puede mover, así que al moverlo, el receptor se apropia de él.

Shared_ptr se utiliza si desea compartir una instancia de objeto sin que realmente haya nadie que tenga el objeto y asegurarse de que no se borre mientras alguien todavía tenga una referencia. Una vez que el último usuario de un objeto destruye el contenedor shared_ptr, se eliminará el objeto contenido.

weak_ptr se utiliza junto con shared_ptr. Le permite a uno "bloquear" para ver si el objeto shared_ptr de referencia todavía existe antes de intentar acceder al objeto interno.

3

Recomiendo usar unique_ptr cuando sea posible (esto puede requerir algún análisis del programa) y shared_ptr cuando esto sea imposible. En caso de duda, utilice un shared_ptr para maximizar la seguridad: al pasar el control a un contenedor, el recuento de referencias simplemente pasará a dos y luego volverá a uno y el contenedor eventualmente delete el objeto asociado automáticamente. Cuando el rendimiento se convierte en un problema, considere usar boost::intrusive_ptr.

+0

+1 buenos consejos. Tienes que estar haciendo un * lote * de creación/destrucción de objetos o copia de punteros para ver una diferencia de rendimiento entre 'shared_ptr' y' intrusive_ptr'. – Doug

Cuestiones relacionadas