El mundo en el que vive Bjarne es muy ... académico, a falta de un término mejor. Si su código puede diseñarse y estructurarse de modo que los objetos tengan jerarquías relacionales muy deliberadas, de modo que las relaciones de propiedad sean rígidas e inflexibles, el código fluye en una dirección (de alto nivel a bajo nivel), y los objetos solo hablan con aquellos de nivel inferior. la jerarquía, entonces no encontrarás mucha necesidad shared_ptr
. Es algo que usas en esas raras ocasiones en las que alguien tiene que romper las reglas. Pero, de lo contrario, puede pegar todo en vector
s u otras estructuras de datos que usen semántica de valores, y unique_ptr
s para cosas que tiene que asignar individualmente.
Si bien es un gran mundo para vivir, no es lo que puedes hacer todo el tiempo. Si no puede organizar su código de esa manera, porque el diseño del sistema que está tratando de hacer significa que es imposible (o simplemente profundamente desagradable), entonces encontrará que necesita cada vez más la propiedad compartida de los objetos. .
En dicho sistema, mantener punteros desnudos no es ... exactamente peligroso, pero plantea preguntas. Lo bueno de esto shared_ptr
es que proporciona garantías sintácticas razonables sobre la vida útil del objeto. ¿Se puede romper? Por supuesto. Pero la gente también puede const_cast
cosas; El cuidado básico y la alimentación shared_ptr
deben proporcionar una calidad de vida razonable para los objetos asignados cuya propiedad debe ser compartida.
Luego, hay weak_ptr
s, que no se pueden usar en ausencia de a shared_ptr
. Si su sistema está rígidamente estructurado, puede almacenar un puntero desnudo a algún objeto, seguro sabiendo que la estructura de la aplicación asegura que el objeto señalado lo sobrevivirá. Puede llamar a una función que devuelve un puntero a algún valor interno o externo (busque un objeto llamado X, por ejemplo). En un código estructurado adecuadamente, esa función solo estaría disponible si la vida útil del objeto fuera superior a la suya; por lo tanto, almacenar ese puntero desnudo en su objeto está bien.
Dado que esa rigidez no siempre es posible de lograr en sistemas reales, necesita alguna forma de garantizar razonablemente la vida útil. A veces, no necesitas la propiedad total; a veces, solo necesita saber cuándo el puntero es malo o bueno. Ahí es donde weak_ptr
entra. Ha habido casos en los que podría haber usado un unique_ptr
o boost::scoped_ptr
, pero tuve que usar un shared_ptr
porque específicamente necesitaba darle a alguien un puntero "volátil". Un puntero cuya vida fue indeterminada, y podrían preguntar cuándo se destruyó ese puntero.
Una forma segura de sobrevivir cuando el estado del mundo es indeterminado.
¿Podría haber sido hecho por alguna llamada de función para obtener el puntero, en lugar de vía weak_ptr
? Sí, pero eso podría romperse más fácilmente. Una función que devuelve un puntero desnudo no tiene forma de sugerir sintácticamente que el usuario no haga algo como almacenar ese puntero a largo plazo. Devolver un shared_ptr
también hace que sea demasiado fácil para alguien simplemente almacenarlo y potencialmente prolongar la vida útil de un objeto. La devolución de un weak_ptr
embargo fuertemente sugiere que el almacenamiento de la shared_ptr
que se obtiene de lock
una ... idea dudosa. No le impedirá hacerlo, pero nada en C ++ le impide romper el código. weak_ptr
proporciona una resistencia mínima al hacer lo natural.
Ahora, eso no quiere decir que shared_ptr
no se pueda usar en exceso ; Ciertamente puede. Especialmente antes unique_ptr
, hubo muchos casos en los que simplemente utilicé un boost::shared_ptr
porque necesitaba pasar un puntero RAII o ponerlo en una lista. Sin movimiento semántico y unique_ptr
, boost::shared_ptr
fue la única solución real.
Y puede usarlo en lugares donde es bastante innecesario. Como se indicó anteriormente, la estructura de código adecuada puede eliminar la necesidad de algunos usos de shared_ptr
. Pero si su sistema no puede estructurarse como tal y sigue haciendo lo que necesita, shared_ptr
será de gran utilidad.