boost, partagé ptr Vs faible ptr? Pour l'utiliser quand?

dans mon projet actuel j'utilise boost::shared_ptr assez largement.

récemment, mes coéquipiers ont aussi commencé à utiliser weak_ptr. Je ne sais pas lequel utiliser et quand.

en dehors de cela, que dois-je faire si je veux convertir weak_ptrshared_ptr. Ne mettre un verrou sur weak_ptr pour créer un shared_ptr affecter mon code dans un autre thread?

41
demandé sur fduff 2010-01-10 08:13:57
la source

4 ответов

En général et sommaire,

pointeurs forts garantir leur propre validité. Utiliser, par exemple, lorsque:

  • vous possédez l'objet pointé vers vous; vous le Créez et le détruisez
  • Vous n'avez pas défini de comportement si l'objet n'existe pas
  • vous devez Vous assurer que l'objet existe.

points faibles garantie savoir leur propre validité. Utiliser, pour exemple:

  • vous y accédez, mais ce n'est pas le vôtre.
  • Vous avez défini le comportement si l'objet n'existe pas

Lock () sur un pointeur faible renvoie un pointeur fort; c'est ainsi que vous accédez au pointeur faible. Si l'objet n'est plus valide (il a été supprimé, etc), alors le pointeur fort sera nul, sinon, il pointera vers l'objet. Vous aurez besoin de vérifier cela.

il est mis en place de cette façon de sorte que vous ne pouvez pas supprimez accidentellement l'objet pendant que vous l'utilisez, parce que vous avez créé un pointeur fort (local) temporaire, et ainsi garunteed l'existence de l'objet alors que ce pointeur fort reste. Lorsque vous avez terminé l'utilisation de l'objet, vous laissez généralement le pointeur fort tomber hors de portée (ou en le réassignant), ce qui permet ensuite à l'objet d'être supprimé. Pour multithreading, traitez-les avec le même soin que vous traitez d'autres choses qui n'ont pas intégré la sécurité du fil, en notant que la garantie que j'ai mentionné ci-dessus tenez bon lorsque vous faites de la lecture multiple. Autant que je sache, ils ne font rien de spécial.

les pointeurs partagés boost ont aussi des fonctionnalités de type collecteur d'ordures, puisque lorsque le dernier pointeur fort vers un objet disparaît ou pointe ailleurs, l'objet est supprimé.

Il y a aussi les performances et les dépendances circulaires mentionnées dans les autres réponses.

fondamentalement, je dirais que la bibliothèque de pointeur partagée boost vous permet de ne pas faites des erreurs dans la mise en place d'un programme, mais ce n'est pas un substitut pour prendre le temps de bien concevoir vos pointeurs, vos possessions d'objets et vos vies. Si vous avez une telle conception, vous pouvez utiliser la bibliothèque de la faire respecter. Si vous n'avez pas une telle conception, vous êtes susceptible de rencontrer des problèmes différents qu'avant.

69
répondu Narfanator 2011-07-04 01:44:31
la source

Utiliser weak_ptr lorsque les objets que vous créez contiennent des références cycliques, i.e. shared_ptr pour un objet avec un shared_ptr retour à vous-même. C'est parce que shared_ptr ne peut pas gérer les références cycliques-lorsque les deux objets sortent de leur portée, le référencement mutuel signifie qu'ils ne sont pas "ramassés", donc la mémoire est perdue et vous avez une fuite de mémoire. Depuis weak_ptr n'augmente pas le nombre de référence, le problème de référence cyclique ne se produit pas. Cela signifie aussi en général que si vous vous voulez prendre un pointeur vers quelque chose qui est compté de référence et ne voulez pas augmenter son compte de référence, puis utilisez weak_ptr.

Sinon, vous pouvez utiliser shared_ptr.

pour plus d'information, consultez le Boost documentation.

21
répondu blwy10 2017-07-19 03:01:42
la source

pointeurs partagés implémenter le comptage de référence, les pointeurs faibles n'affectent pas le comptage de référence et si vous n'avez pas de pointeurs partagés vers un objet, seulement des pointeurs faibles, l'objet est supprimé et les pointeurs faibles vous disent maintenant que l'objet a été perdu.

il y a deux raisons d'utiliser un pointeur faible:

  1. pour éliminer le coût de l'augmentation / diminution du nombre de référence; cependant, vous ne devriez pas faire cela parce qu'il est sujet aux erreurs et ne permet pas vraiment d'économiser beaucoup temps
  2. dans les structures de données comptables, par exemple, vous avez un index de tous les objets Foo qui sont "vivants", c'est-à-dire utilisés ailleurs, et vous ne voulez pas garder un Foo vivant dans l'index si toutes les utilisations "réelles" ont pris fin. C'est le cas d'utilisation réaliste de base pour les pointeurs faibles. Bien sûr, les autres existent aussi.

Donc, en général, ma recommandation serait d'utiliser des pointeurs faibles seulement quand vous savez que vous voulez laisser les objets référencés être supprimé et voulez détecter. Dans d'autres cas, utilisez des pointeurs partagés (comptage de référence), ou des pointeurs directs, en particulier. dans les variables locales de méthode quand vous savez que les objets ne vont pas être supprimés. Aussi errorprone, cependant, mais plus rapide que les pointeurs partagés.

N.B. les objets cycliques n'ont pas besoin de pointeurs faibles, vous pouvez utiliser des pointeurs réguliers et non cuits à la place dans la plupart des programmes correctement construits. Points faibles moins risqués, cependant.

6
répondu Antti Huima 2010-01-10 08:59:28
la source

vous ne devriez probablement pas essayer d'utiliser des pointeurs faibles du tout sauf si vous essayez d'implémenter un collecteur d'ordures, ce qui n'est pas une bonne idée en C++ parce qu'il est trop difficile de garder une trace de tout ce qui pourrait mal tourner.

-10
répondu Charles Eli Cheese 2010-01-10 15:09:48
la source