c++ memory-management boost shared-ptr weak-ptr

c++ - boost, ptr compartido Vs ptr débil? ¿Qué usar cuando?



memory-management shared-ptr (4)

En general y resumen,

Los indicadores fuertes garantizan su propia validez. Úselos, por ejemplo, cuando:

  • Usted es dueño del objeto al que apunta; lo creas y lo destruyes
  • No tiene un comportamiento definido si el objeto no existe
  • Debe hacer cumplir que el objeto existe.

Los indicadores débiles garantizan conocer su propia validez. Úselos, por ejemplo, cuando:

  • Usted accede a él, pero no es suyo.
  • Has definido el comportamiento si el objeto no existe

Lock () en un puntero débil devuelve un puntero fuerte; esta es la forma de acceder al puntero débil. Si el objeto ya no es válido (se ha eliminado, etc.), entonces el puntero fuerte será NULO; de lo contrario, apuntará al objeto. Deberás verificar esto.

Está configurado de esta manera para que no puedas eliminar accidentalmente el objeto mientras lo estás usando, porque has creado un puntero fuerte temporal (local) y, por lo tanto, has bloqueado la existencia del objeto mientras ese fuerte puntero permanece. Cuando termine de utilizar el objeto, generalmente deja que el puntero fuerte se salga del alcance (o lo reasigne), lo que permite que el objeto se elimine. Para el multihilo, trátelos con la misma precaución para tratar otras cosas que no tienen seguridad incorporada en el hilo, señalando que la garantía que mencioné anteriormente se mantendrá cuando se multiplique. AFAIK no hacen nada especial más allá de eso.

Los punteros compartidos de impulso también tienen características similares al recolector de basura, ya que cuando el último puntero fuerte a un objeto desaparece o apunta a otro lugar, el objeto se elimina.

También está el rendimiento y las dependencias circulares mencionadas en las otras respuestas.

Fundamentalmente, diría que la biblioteca de impulso compartido de impulso le permite no estropear la creación de un programa, pero no es un sustituto para tomarse el tiempo para diseñar correctamente sus punteros, propiedades de objeto y tiempos de vida. Si tiene dicho diseño, puede usar la biblioteca para aplicarlo. Si no tiene ese diseño, es probable que se encuentre con problemas diferentes a los anteriores.

En mi proyecto actual, estoy usando boost::shared_ptr bastante extensamente.

Recientemente, mis compañeros de equipo también comenzaron a usar weak_ptr . No sé cuál usar y cuándo.

Aparte de esto, ¿qué debo hacer si quiero convertir weak_ptr a shared_ptr ? ¿ weak_ptr un candado en weak_ptr para crear un shared_ptr afecta mi código en otro hilo?


Los punteros compartidos implementan el recuento de referencias, los punteros débiles no afectan el recuento de referencias y si no tiene punteros compartidos para un objeto, solo punteros débiles, el objeto se elimina y los punteros débiles le informan que el objeto se ha perdido.

Hay dos razones para usar un puntero débil:

  1. Para eliminar el costo de recuento de referencia aumentar / disminuir; sin embargo, no debes hacer esto porque es propenso a errores y no ahorra mucho tiempo
  2. En las estructuras de datos de contabilidad, por ejemplo, tiene un índice de todos los objetos Foo que están "vivos", es decir, utilizados en otro lugar, y no desea mantener un Foo vivo en el índice si todos los usos "reales" han finalizado. Este es el caso de uso realista básico para los indicadores débiles. Por supuesto, existen otros también.

Por lo tanto, en general, mi recomendación sería utilizar punteros débiles solo cuando sepa que desea dejar que los objetos a los que se hace referencia se eliminen y desee detectarlos. En otros casos, use punteros compartidos (recuento de referencias) o punteros directos, esp. en variables locales del método cuando sabes que los objetos no se van a eliminar. También errorprone, pero más rápido que los punteros compartidos.

Los objetos cíclicos de NB no necesitan punteros débiles; en cambio, puede utilizar punteros regulares no cocidos en la mayoría de los programas construidos correctamente. Los indicadores débiles son menos riesgosos, sin embargo.


Probablemente no deberías tratar de utilizar punteros débiles a menos que intentes implementar un recolector de basura, lo cual no es una buena idea en C ++ porque es muy difícil hacer un seguimiento de todo lo que podría ir mal lo suficientemente cerca.


Utilice weak_ptr cuando los objetos que cree contengan referencias cíclicas, es decir, shared_ptr a un objeto con un shared_ptr regreso a usted. Esto se debe a que shared_ptr no puede manejar referencias cíclicas: cuando ambos objetos quedan fuera del alcance, la referencia mutua significa que no son "basura recolectada", por lo que la memoria se pierde y tiene una pérdida de memoria. Como weak_ptr no aumenta el recuento de referencias, no se produce el problema de referencia cíclica. Esto también significa, en general, que si solo desea tomar un puntero a algo que es referencia contada y no desea aumentar su conteo de referencia, entonces use weak_ptr .

De lo contrario, puede usar shared_ptr .

Para obtener más información, consulte la documentation Boost.