2010-05-25 2 views
7

boost::intrusive_ptr nécessite intrusive_ptr_add_ref et intrusive_ptr_release à définir. Pourquoi une classe de base n'est-elle pas fournie qui le fera? Il y a un exemple ici: http://lists.boost.org/Archives/boost/2004/06/66957.php, mais l'affiche dit «Je ne pense pas nécessairement que ce soit une bonne idée». Pourquoi pas? Mise à jour: Je ne pense pas que le fait que cette classe puisse être utilisée abusivement avec Multiple Héritage est une raison suffisante. Toute classe dérivée de plusieurs classes de base avec leur propre nombre de références aurait le même problème. Que ces refcounts soient implémentés via une classe de base ou non ne fait aucune différence.intrusive_ptr: Pourquoi une classe de base commune n'est-elle pas fournie?

Je ne pense pas qu'il y ait un problème avec le multithreading; boost::shared_ptr offre le comptage atomique des références et cette classe pourrait aussi.

+3

Sur une note connexe, 'osg :: ref_ptr' de la bibliothèque OpenSceneGraph utilise une classe de base commune de haut niveau ('osg :: Referenced') pour son implémentation de pointeur intelligent intrusif. –

+3

Et osg :: Referenced est compatible avec boost :: intrusive_ptr car il fournit des fonctions intrusive_ptr_add_ref() et intrusive_ptr_release(). Fonctionne parfaitement. –

Répondre

2

Boost fournit une facilité pour cela. Il peut être configuré soit pour refcounting thread-safe ou fil dangereux:

#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 d'autres termes, la réponse à ma question est, "il devrait y avoir, et maintenant il y a" :) – Jon

+0

On dirait que ça fait un bout de temps, mais ça bouge un peu. Voici la première référence de document que j'ai trouvée: http://www.boost.org/doc/libs/1_54_0/libs/log/doc/html/utilities.html#header.boost.log.utility.intrusive_ref_counter_hpp –

3

Le problème serait avec l'héritage multiple. Si vous héritez de 2 objets implémentant cette base, alors vous avez 2 compteurs pour votre seul objet ... et cela pourrait causer des dégâts.

Ainsi, vous devrez faire les ptr_add et ptr_release méthodes virtuelles, de sorte que la classe dérivée peut mettre en œuvre une dérogation pour synchroniser correctement les compteurs multiples à la fois ... Certaines pénalité de performance ici, d'autant plus que la plupart du temps il serait être complètement inutile (il n'y aurait pas d'override) car ce n'est utile qu'après tout pour Multiple Inheritance. Et bien sûr, dans les environnements multithread vous pourriez avoir (pour de courtes périodes) des compteurs désynchronisés (le premier a été incrémenté mais le thread a été interrompu avant le second) Je ne peux pas encore penser à un problème cause, mais ce n'est pas une situation saine. Vous ajoutez également de l'encombrement à la classe, certains clients peuvent ne pas avoir besoin de compter les références après tout (si elles créent l'objet sur la pile).

Je pense que ce n'est pas une bonne idée;)

+2

Héritage multiple: Ce problème se produit également lorsque vous avez deux classes de base qui implémentent leur propre nombre de références. Si ce refcount est implémenté via une classe de base ou pas, cela ne fait aucune différence. Multi-Thread: shared_ptr a un incrément/décrément atomique, donc cette classe pourrait aussi. "certains clients n'ont pas besoin de compter les références": c'est la raison pour laquelle vous n'utilisez pas intrusive_ptr, pas pourquoi il n'y a pas de classe de base. – Jon

+1

@Jon: Je suis d'accord sur l'héritage multiple, en effet vous pouvez implémenter le comptage de référence intrusif sans classe de base. Cependant, je ne suis pas d'accord sur les 2 autres remarques: MT "shared_ptr" fournit facilement la sémantique atomique car il n'a qu'un seul compteur, si vous avez plusieurs compteurs à maintenir dans un état cohérent, alors vous avez besoin d'un verrouillage explicite (plus d'opérations atomiques disponibles) cela signifie des frais généraux conséquents ... suivez le lapin blanc ... –

+1

Pour la partie 'intrusive_ptr': je suis partial ici, mais j'ai toujours pensé que l'approche intrusive était« fausse »dans le sens où elle regroupait à la fois une classe« fonctionnelle »et un comportement de« gestion ». Donc, c'est effectivement une critique sur le mécanisme de comptage des références intrusives. Je trouve l'approche 'shared_ptr' plus solide ici, et le fait que vous ne pouvez pas avoir accidentellement deux compteurs pour un seul ensemble de' shared_ptr' est un bon bonus. –

4

Il est donc vous pouvez utiliser intrusive_ptr avec des classes qui mettent en œuvre déjà ajouter et relâchez.

+0

Il ya d'autres raisons d'utiliser intrusive_ptr (empreinte mémoire, performance, construction à partir de pointeur arbitraire brut) – Jon

+0

C'est la meilleure raison si à mon humble avis –

Questions connexes