¿impulso, RPP compartido Vs rpp débil? ¿Cuál usar cuándo?


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

Recientemente mis compañeros de equipo también han comenzado a usar weak_ptr. No se cual usar y cuando.

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

Author: fduff, 2010-01-10

4 answers

En general y resumen,

Los punteros fuertes garantizan su propia validez. Úsalos, por ejemplo, cuando:

  • Eres el dueño del objeto que se apunta; lo creas y lo destruyes
  • No tiene un comportamiento definido si el objeto no existe
  • Necesita hacer cumplir que el objeto existe.

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

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

Lock() en un puntero débil devuelve un puntero fuerte; así es como se accede 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. Usted tendrá que comprobar esto.

Está configurado de esta manera para que no pueda eliminar accidentalmente el objeto mientras lo está usando, porque ha hecho un temporal (local) puntero fuerte, y así garunteó la existencia del objeto mientras ese puntero fuerte permanece. Cuando haya terminado de usar el objeto, generalmente deja que el puntero fuerte caiga fuera del alcance (o lo reasigne), lo que permite que el objeto se elimine. Para multithreading, tratarlos con el mismo cuidado que tratar otras cosas que no tienen seguridad de hilo incorporado, teniendo en cuenta que la garantía que he mencionado anteriormente se mantendrá cuando multithreading. AFAIK no hacen nada especial pasado que.

Los punteros compartidos boost también tienen características similares a recolectores 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án las dependencias de rendimiento y circulares mencionadas en las otras respuestas.

Fundamentalmente, yo diría que la biblioteca boost shared pointer le permite no estropear la creación de un programa, pero no es un sustituto de tomarse el tiempo para diseñar correctamente su punteros, propietarios de objetos y vidas. Si tiene un diseño de este tipo, puede usar la biblioteca para aplicarlo. Si no tiene un diseño de este tipo, es probable que se encuentre con problemas diferentes que antes.

 69
Author: Narfanator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-03 21:44:31

Use weak_ptr cuando los objetos que cree contengan referencias cíclicas, es decir, shared_ptr a un objeto con un shared_ptr de vuelta a sí mismo. Esto se debe a que shared_ptr no puede manejar referencias cíclicas: cuando ambos objetos salen de su alcance, la referencia mutua significa que no están "recolectados de basura", por lo que la memoria se pierde y tiene una fuga de memoria. Dado que 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 se cuenta con referencia y no desea aumentar su recuento de referencia, luego use weak_ptr.

De lo contrario, puede usar shared_ptr.

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

 21
Author: blwy10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-19 00:01:42

Los punteros compartidos implementan el conteo de referencias, los punteros débiles no afectan el conteo de referencias y si no tiene punteros compartidos a un objeto, solo los punteros débiles, el objeto se elimina y los punteros débiles ahora le dicen que el objeto se ha perdido.

Hay dos razones para usar un puntero débil:

  1. Para eliminar el costo del aumento / disminución del recuento de referencias; sin embargo, no debe hacer esto porque es propenso a errores y realmente 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 terminado. Este es el caso de uso realista básico para punteros débiles. Por supuesto, también existen otros.

Entonces, en general, mi recomendación sería usar punteros débiles solo cuando sepa que desea permitir que los objetos referenciados se eliminen y desee detectarlo. En los demás casos utilice punteros compartidos (conteo de referencias), o punteros directos, esp. en el método variables locales cuando sabe que los objetos no se van a eliminar. También errorprone, aunque, pero más rápido que los punteros compartidos.

N.B. Los objetos cíclicos no necesitan punteros débiles, puede usar punteros regulares no cocinados en su lugar en la mayoría de los programas construidos correctamente. Sin embargo, los punteros débiles son menos riesgosos.

 6
Author: Antti Huima,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-10 05:59:28

Probablemente no debería estar tratando de usar punteros débiles a menos que esté tratando de implementar un recolector de basura, que no es una idea caliente en C++ porque es demasiado difícil hacer un seguimiento de todo lo que podría salir mal lo suficientemente cerca.

 -10
Author: Charles Eli Cheese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-10 12:09:48