2010-05-25 25 views
7

boost::intrusive_ptr requiere intrusive_ptr_add_ref y intrusive_ptr_release por definir. ¿Por qué no se proporciona una clase base que hará esto? Aquí hay un ejemplo: http://lists.boost.org/Archives/boost/2004/06/66957.php, pero el cartel dice "No creo necesariamente que sea una buena idea". Por qué no?intrusive_ptr: ¿Por qué no se proporciona una clase base común?

Actualización: No creo que el hecho de que esta clase pueda ser mal utilizada con Herencia múltiple sea motivo suficiente. Cualquier clase que derive de múltiples clases base con su propio recuento de referencia tendría el mismo problema. Si estas refotaciones se implementan a través de una clase base o no, no hace ninguna diferencia.

No creo que haya ningún problema con el multihilo; boost::shared_ptr ofrece conteo de referencias atómicas y esta clase también podría.

+3

En una nota relacionada, 'osg :: ref_ptr' de la biblioteca OpenSceneGraph utiliza una clase base común de nivel superior ('osg :: Referenced') para su implementación intrusiva de puntero inteligente. –

+3

Y osg :: Referenced es compatible con boost :: intrusive_ptr ya que proporciona intrusive_ptr_add_ref() y funciones intrusive_ptr_release(). Funciona perfectamente. –

Respuesta

2

Boost proporciona una instalación para eso. Se puede configurar para refcounting flujos seguros o inseguros hilo:

#include <boost/intrusive_ptr.hpp> 
#include <boost/smart_ptr/intrusive_ref_counter.hpp> 

class CMyClass 
    : public boost::intrusive_ref_counter< 
           CMyClass, 
           boost::thread_unsafe_counter> 
    ... 

boost::intrusive_ptr<CMyClass> myPtr; 

http://www.boost.org/doc/libs/1_62_0/libs/smart_ptr/intrusive_ref_counter.html

+0

En otras palabras, la respuesta a mi pregunta es "debería haber, y ahora está" :) – Jon

+0

Parece que ha estado allí por un tiempo, pero se movió un poco. Esta es la primera referencia de doc que encontré: http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/utilities.html#header.boost.log.utility.intrusive_ref_counter_hpp –

3

El problema sería con Herencias Múltiples. Si heredas de 2 objetos que implementan esta base, entonces tienes 2 contadores para tu único objeto ... y eso podría causar estragos.

Por lo tanto lo que se necesita para hacer que los métodos ptr_add y ptr_release virtual, por lo que la clase derivada puede aplicar una anulación de sincronizar adecuadamente los varios contadores a la vez ... Algunos penalización de rendimiento aquí, especialmente porque la mayoría de las veces que lo haría ser completamente innecesario (no habrá anulación) porque solo es útil para Herencia Múltiple después de todo.

Y, por supuesto, en entornos Multi-Threaded podrías tener (por cortos periodos de tiempo) contadores desincronizados (el primero se incrementó pero el hilo fue interrumpido antes que el segundo) No puedo pensar en ningún problema que pueda porque, pero no es una situación sensata

También agrega desorden a la clase, algunos clientes pueden no necesitar el recuento de referencias después de todo (si crean el objeto en la pila).

Creo que no es una buena idea;)

+2

Herencia múltiple: este problema también ocurre cuando tienes dos clases base que implementan su propio recuento de referencias. Si este refcount se implementa a través de una clase base o no, no hace ninguna diferencia. Multi-Threaded: shared_ptr tiene incrementos/decrementos atómicos, por lo que esta clase también podría. "algunos clientes pueden no necesitar el recuento de referencias": esa es una razón por la que no usaría intrusive_ptr, no por qué no hay una clase base. – Jon

+1

@Jon: estoy de acuerdo con la Herencia Múltiple, de hecho puede implementar el recuento de referencias intrusivas sin una clase base. Sin embargo, no estoy de acuerdo con los otros 2 comentarios: para MT 'shared_ptr' proporciona semántica atómica fácilmente porque solo tiene un contador, si tienes varios contadores para mantener en un estado coherente, entonces necesitas bloqueo explícito (no hay más operaciones atómicas disponibles) y esto significa gastos generales consecuentes ... sigue al conejo blanco ... –

+1

Para la parte 'intrusive_ptr': soy parcial aquí, pero siempre pensé que el enfoque intrusivo era" incorrecto "en el sentido de que agrupaba tanto una clase" funcional "como una conducta de" gestión ". Entonces, esto es efectivamente una crítica sobre el intrusivo mecanismo de conteo de referencias. Encuentro el enfoque 'shared_ptr' más sólido aquí, y el hecho de que no puedes tener accidentalmente dos contadores para un solo conjunto de' shared_ptr' es una buena bonificación. –

4

Es lo que puede utilizar intrusive_ptr con las clases que ya implementan añadir y liberación.

+0

Hay otras razones para usar intrusive_ptr (huella de memoria, rendimiento, construir desde un puntero sin procesar arbitrario) – Jon

+0

Es la mejor razón, aunque en mi humilde opinión –

Cuestiones relacionadas