2010-08-14 21 views
11

He estado usando C++ desde hace un tiempo y todavía no me siento muy cómodo con el uso de punteros inteligentes y solo los he usado al editar algún código que los use, nunca en mi propio código (podría ser vale la pena decir que soy un estudiante).¿Cómo usar los punteros inteligentes de C++?

¿Puede explicarnos cuáles son los tipos de punteros inteligentes, cómo funcionan y cuándo usarlos?

Además, ¿cuál es el "protocolo" al recibir o pasar punteros sin formato en las interfaces escritas por otras personas?

Gracias.

+1

Un poco de búsqueda en este mismo sitio le da los siguientes http://stackoverflow.com/search?q=smart+pointers – celavek

+0

Muchos diferentes posibles duplicados a esta pregunta ... –

Respuesta

15

C++ 98 no proporciona ningún puntero inteligente excepto auto_ptr que está plagado de sus propios problemas. C++ 0X intenta solucionar esto introduciendo algunas variedades más (shared_ptr, unique_ptr, etc.). Mientras tanto, la mejor opción es usar Boost. Eche un vistazo a los diferentes sabores disponibles para usted here. Boost está impulsado por la comunidad, ampliamente probado y, por supuesto, gratis. Existe una excelente documentación con código de muestra que lo ayudará a comenzar.

¿Puede explicarnos cuáles son los tipos de punteros inteligentes, cómo funcionan y cuándo usarlos?

Existen varias. En resumen:

scoped_ptr<boost/scoped_ptr.hpp> propiedad exclusiva simple de un solo objetos. No copiable

scoped_array<boost/scoped_array.hpp> simple única propiedad de matrices. No copiable

shared_ptr<boost/shared_ptr.hpp> propiedad de objetos compartidos entre múltiples punteros.

shared_array <boost/shared_array.hpp> matriz propiedad compartida entre múltiples punteros.

weak_ptr <boost/weak_ptr.hpp> para no ser dueño de observadores de un objeto propiedad de shared_ptr.

intrusive_ptr <boost/intrusive_ptr.hpp> compartido propiedad de objetos con un contador de referencias incrustado .

(Eso es de la documentación Boost y nota que tienen contenedores para estos punteros también!)

Además, ¿cuál es el "protocolo" al recibir o pasar punteros primas en las interfaces escritos por otras personas ?

Para mí las reglas más importantes son:

  • Const-calificación
  • No desasignar cosas que no asignó
  • Compruebe si hay transferencia de propiedad/mover la semántica
+2

Buena suma. No estoy de acuerdo con que auto_ptr esté plagado de problemas. Si no entiende lo que hace, puede tomarlo por sorpresa, pero eso se resuelve al leer la documentación. Además, el nuevo C++ 0x proporciona std :: unique_ptr, que es prácticamente una sustitución de auto_ptr, pero hace que la semántica del movimiento sea más obvia para los recién llegados. También sería bueno ver cuáles se han incluido en la nueva lib estándar. –

+0

concedido. He sido un poco duro y seguiremos viviendo con 'auto_ptr' (aunque mi copia del borrador, es decir, n3090 dice que está en desuso). – dirkgently

+0

La documentación de impulso de llamadas "excelente" es un poco exagerada :). La calidad sube y baja, dependiendo de la lib en cuestión. Pero buena respuesta en general, +1. – Lucas

0

Acerca del STL auto_ptr, recomiendo leer Herb Sutter's (autor de buenos libros en C++) GuruOfTheWeek: use este Link

1

Los tipos de puntero inteligente son una capa de abstracción para automatizar el proceso de asignación y desasignación de memoria, su función constructora, obtiene una memoria asignada (mediante puntero) y su función de destructor libera la memoria asignada. Por supuesto, el constructor y el destructor pueden estar en línea (por lo tanto, no hay sobrecarga para llamarlos). Por ejemplo:

{ 
    int* raw = new int(40); 
    auto_ptr<int> sp(raw); //inline constructor: internal_holder = raw 
    //... 
    //inline destructor: delete internal_holder 
} 

En C++ es bueno utilizar punteros indirectamente (ocultarlos detrás de las clases). La sobrecarga de crear un nuevo puntero inteligente es insignificante. Pero shared_ptr es más pesado debido a su comportamiento para el recuento de referencias (se hace referencia a la referencia).

Cuando queremos utilizar punteros sin procesar que se reciben de otras funciones que son escritas por otras personas, si estos punteros crudos no deberían ser liberados por nosotros mismos, entonces no deberíamos usar punteros inteligentes.

0

No existe una regla sobre cuándo usar punteros inteligentes. Más apropiadamente, usa punteros inteligentes siempre que sea posible. Los punteros crudos son una rareza en el código C++ bien escrito. Cuando reciba un puntero sin formato, envuélvalo en un puntero inteligente escrito y autogratis personalizado, si es su deber desasignarlo.

Cuestiones relacionadas