9
votes

Devrais-je convertir partagé_ptr en faim_ptr lorsqu'il est passé à une méthode?

Il y a déjà quelques questions concernant ce sujet, mais je ne suis toujours pas sûr de quoi faire: Notre codeBase utilise partagé_ptr à de nombreux endroits. Je dois admettre que nous n'avons pas défini la propriété clairement lors de l'écrivant.

Nous avons des méthodes telles que xxx

après avoir découvert les premières dépendances circulaires (indirectes), je voudrais corriger les erreurs dans notre conception. Mais je ne suis pas vraiment sûr comment. Y a-t-il des avantages dans la modification de la méthode de ci-dessus en xxx

Je suis également confus car certaines personnes disent (y compris le guide de style Google) que En premier lieu, il est important de faire appel à la propriété (ce qui signifie probablement introduction de nombreux faibles_ptrs , par exemple dans l'exemple avec les méthodes ci-dessus, mais aussi pour de nombreuses variables membres que nous avons). D'autres disent (voir les liens ci-dessous) que vous devriez utiliser faibles_ptr pour casser des dépendances cycliques. Cependant, les détecter n'est pas toujours facile, alors je me demande si je devrais utiliser partagée_ptr jusqu'à ce que je rencontre des problèmes (et que je les réalise), puis les réparer ??

Merci pour vos pensées!

Voir aussi


4 commentaires

Shared_ptr & PTR serait-il meilleur?


"Les détecter n'est pas toujours facile" - alors vous devez vraiment ajouter plus d'étapes à votre processus de conception. Lignes lumineuses et sombres sur vos diagrammes de relation de classe, ou quoi que ce soit. Vous pouvez également envisager des cycles de rupture avec des pointeurs cru plutôt que des pointeurs faibles, pour la plupart des relations asymétriques où le "propriétaire" ne sera jamais détruit avant tous les "non-propriétaires".


@Dandan: Je ne pense pas, voir Stackoverflow.com/Questtions/327573/...


Certains des commentaires de ce fil n'étaient pas particulièrement valables. Si vous devez transmettre un partage_ptr par référence ou ne pas obéir plus ou moins les mêmes règles que tout ce qui est en référence; À cet égard, il n'y a rien de spécial sur Shared_Ptr.


4 Réponses :


6
votes

Nous n'avons pas défini de définir de la propriété.

Vous devez définir clairement qui possède quoi. Il n'y a pas d'autre moyen de résoudre ce problème. Arbitrairement échangeant certaines utilisations de partagée_ptr avec faibles_ptr ne fera pas mieux les choses.


2 commentaires

Ok, je pense que cela ne devrait pas être trop difficile car le design est (pas encore :-)) Dommage, je suppose. Cependant, la question reste: devrais-je introduire des faibles_ptrs uniquement lorsque je détecte des cercles (s'il y en a plus) ou partout où l'objet / la méthode n'a pas de propriété?


@Phillip - Si vous regardez l'exemple que vous avez donné, il n'y a aucune différence de comportement entre passer un faible_ptr et un partage_ptr. Pour utiliser le faibles_ptr, vous devez d'abord créer un Shared_ptr à partir de celui-ci, ce qui est effectivement identique à celui d'avoir passé un partage_ptr en premier lieu.



2
votes

Certaines personnes ont raison: vous devriez d'abord avoir une image très claire sur la propriété des objets dans votre projet.

Shared_Ptrs sont partagés , c'est-à-dire "appartenant à la communauté". Cela pourrait ou pourrait ne pas être souhaitable. Donc, je conseillerais de définir le modèle de propriété, puis de ne pas abuser de la sémantique partagée_ptr et d'utiliser des pointeurs ordinaires chaque fois que la propriété ne doit pas être "partagée" plus.

Utiliser des faibles_ptrs masquer le problème plus loin plutôt que de le réparer.


0 commentaires

4
votes

Il n'y a pas d'avantage dans la modification de votre conception ci-dessus de Shared_Ptr vers Faible_PTR. Se rendre à la propriété de la propriété ne consiste pas à utiliser des faibles_ptrs, il s'agit de gérer qui stocke le Shared_Ptr pour une durée importante. Si je passe un partage_ptr sur une méthode, en supposant que je ne stocke pas ce partage_ptr dans un champ de mon objet dans le cadre de mon objet dans le cadre de cette méthode, je n'ai pas changé à qui possède ces données.

Dans mon expérience, la seule raison d'utiliser faibles_ptr est lorsque vous devez absolument avoir un cycle de pointeurs et vous devez casser ce cycle. Mais vous devriez d'abord considérer si vous pouvez modifier votre conception pour éliminer le cycle.

Je décourage habituellement mélanger les pointeurs partagés_ptr et bris. Il arrive inévitablement (même s'il ne devrait probablement pas) qu'un pointeur brut doit être transmis à une fonction qui prend un partage_ptr de ce type. Une faiblesse_ptr peut être convertie en toute sécurité en un partage_ptr, avec un pointeur brut que vous n'avez pas de chance. Pire encore, un développeur inexpérimenté avec Shared_Ptr peut créer un nouveau Shared_Ptr à partir de ce pointeur brut et la transmettre à la fonction, ce qui provoque la suppression de ce pointeur lorsque la fonction renvoie. (En fait, je devais réparer ce bogue dans le code de production, donc oui cela se produit :))


1 commentaires

" Il arrive inévitablement (...)" Cette explication est l'une des rares rares justification de faibles_ptr j'ai vu sur tellement (ou ailleurs). Merci.



3
votes

On dirait que vous avez un problème de conception. partagé_ptr fournit une implémentation simple à utiliser pour des solutions de conception spécifiques, Mais cela (ni autre chose) ne peut remplacer la conception. Jusqu'à toi ont déterminé quelle est la durée de vie réelle de chaque type d'objet Devrait être, vous ne devriez pas utiliser Shared_PTR. Une fois que vous avez fait que, la plupart des problèmes partagés_ptr / faibles_ptr devraient disparaître.

Si, après cela, et déterminé que la durée de vie de certains les objets dépendent de celle des autres objets, et il y a cycles dans cette dépendance, vous devez déterminer (à la conception niveau, encore) Comment gérer ces cycles --- C'est tout à fait possible, Par exemple, dans ces cas, Shared_Ptr n'est pas le bon solution, ou que beaucoup de pointeurs impliqués sont juste pour la navigation et doivent être des pointeurs bruts.

En tout cas, la réponse à votre question réside à la conception niveau. Si vous devez le demander lors de la codage, il est temps d'y aller Retour à la conception.


0 commentaires