2009-11-20 5 views
31

scoped_ptr no se puede copiar y se está eliminando fuera del alcance. Por lo tanto, es un tipo de restricción shared_ptr. Así que parece que además de los casos en los que realmente necesita restringir la operación de copia, es mejor usar shared_ptr. Porque a veces no sabes que necesitas crear una copia de tu objeto o no. Entonces la pregunta es: además de los casos mencionados anteriormente, podríamos considerar que shared_ptr es mejor (o recomendado) para usar en lugar de scoped_ptr. ¿Funciona scoped_ptr mucho más rápido desde shared_ptr, o tiene alguna ventaja?shared_ptr vs scoped_ptr

Gracias!

Respuesta

64

shared_ptr es más pesado que scoped_ptr. Necesita asignar y liberar un objeto de recuento de referencia, así como el objeto gestionado, y gestionar el recuento de referencias seguras para subprocesos. En una plataforma en la que trabajé, esta fue una sobrecarga significativa.

Mi consejo (en general) es utilizar el objeto más simple que satisfaga sus necesidades. Si necesita compartir el recuento de referencias, use shared_ptr; si solo necesita eliminación automática una vez que haya terminado con una sola referencia, use scoped_ptr.

+16

Mike, no podría estar más de acuerdo. Siempre recomiendo a las personas que comiencen con 'boost :: scoped_ptr'. Si necesita una semántica de transferencia de propiedad (manteniendo la propiedad única), entonces "actualice" a 'std :: auto_ptr'. Si solo necesita propiedad compartida, entonces usa 'boost :: shared_ptr'. Además, la biblioteca 'Boost.ptr_container' es una buena alternativa a los contenedores de boost :: shared_ptr cuando los elementos realmente no necesitan ser compartidos. –

+2

Como comentario: si necesita punteros compartidos, puede deshacerse de las asignaciones adicionales asignando objetos usando 'make_shared' o' allocate_shared' en lugar de 'new'. –

+17

@David: en general estoy de acuerdo, pero omito 'auto_ptr' por completo. No se puede usar de forma segura en contenedores estándar, por lo que es probable que brinde algunas sorpresas desagradables si no es * realmente * cuidadoso. – jalf

3

scoped_ptr funciona mucho más rápido de shared_ptr. Es lo correcto. shared_ptr siempre asigna memoria usando su asignador o asignador predeterminado.

5

Su finalidad prevista es diferente, por lo que, en muchos casos, "shared_ptr vs scoped_ptr" no es una pregunta en absoluto. Claro, puedes usar un shared_ptr cuando todo lo que necesitas es un scoped_ptr. Pero, ¿cuál es el punto? shared_ptr tiene una sobrecarga ligeramente mayor con todo el recuento de referencias involucrado.

15

El rendimiento - shared_ptr tiene más funciones, pero también requiere una asignación adicional (también es más grande, pero eso rara vez importa).

[editar] La segunda asignación se puede evitar usando make_shared, pero luego weak_ptr mantendrá toda la asignación incluso después de que se destruya el objeto, lo que puede ser un problema para objetos grandes.

Expresion of Intent usando scoped_ptr indica más explícitamente lo que quiere hacer. (En caso de que te lo preguntes, eso es algo bueno :)). Si hace esto correctamente, shared_ptr también indicará que "este objeto está destinado a vivir más allá de este alcance"

+3

+1 para expresión de intención. En ese sentido, 'scoped_ptr' es muy claro como lo es' shared_ptr'. Del mismo modo, el uso de 'std :: auto_ptr' debería indicar que estás dispuesto a transferir la propiedad del objeto en algún momento. –

1

Scoped_ptr tiene poco en común con shared_ptr, weak_ptr, o unique_ptr porque solo está haciendo un caso muy especial de "recuento de referencias" . No es algo que necesitarás muy a menudo en un código bien diseñado, pero es una buena herramienta para tener disponible.

Básicamente, un scoped_ptr no es una cosa contada en absoluto. Más bien, es un objeto se crea en la pila (en el ámbito local) para que pueda hacer algo como esto:

//Some enclosing scope- anything set off by "{}" or even a function: 
    { 
     scoped_ptr<MyObject> ptr = new MyObject(parameters...); 
    } // When we hit this closing brace, "ptr" will delete the "MyObject" inside. 

Se tiende a ver este patrón más con mutex y otro de sincronización primatives- puedo declarar un "AutoLock" que bloqueará el mutex pasado en él, y luego lo desbloqueará cuando lo elimine para convertir todo el alcance "{}" en una sección crítica.

Observe también que un 'scoped_ptr' solo tiene sentido cuando no se puede simplemente hacer una asignación de stack simple como "MyObject obj (params ..)" por alguna razón. Después de todo, lo que hace es permitirte usar un objeto alojado en el montón como si fuera uno en la pila.Eso tiende a ser un caso de uso mucho más raro que el recuento de referencias de shared_ptr & sus primos.

Cuestiones relacionadas