Quel type de pointeur dois-je?
Ok, donc la dernière fois que j'ai écrit en C++ pour un vivant, std::auto_ptr
a toutes les mst lib disponibles, et boost::shared_ptr
était à la mode. Je n'ai jamais vraiment regardé dans l'autre pointeur intelligent types d'achats. Je comprends que C++11 fournit maintenant quelques-uns des types de boost est venu avec, mais pas tous d'entre eux.
Ainsi, quelqu'un avoir un algorithme simple pour déterminer quand utiliser de pointeur intelligent? De préférence, y compris des conseils sur muet pointeurs (raw pointeurs comme T*
) et le reste de la poussée des pointeurs intelligents. (Quelque chose comme cette serait génial).
Voir aussi std::auto_ptr à std::unique_ptr
Je suis vraiment en espérant que quelqu'un arrive avec une belle pratique de l'organigramme comme cette STL diagramme de flux de sélection.
Oh, c'est en effet une belle! Je FAQized il.
Ce n'est même pas proche d'être un doublon. Liés à la question dit: "Quand dois-je utiliser un pointeur intelligent", et cette question est "Quand dois-je utiliser ces pointeurs intelligents?", ce qui est de la catégorisation des différentes utilisations de la norme des pointeurs intelligents. Liés question de ne pas faire cela. La différence est petite en apparence, mais c'est un des grands.
Je suis vraiment en espérant que quelqu'un arrive avec une belle pratique de l'organigramme comme cette STL diagramme de flux de sélection.
Oh, c'est en effet une belle! Je FAQized il.
Ce n'est même pas proche d'être un doublon. Liés à la question dit: "Quand dois-je utiliser un pointeur intelligent", et cette question est "Quand dois-je utiliser ces pointeurs intelligents?", ce qui est de la catégorisation des différentes utilisations de la norme des pointeurs intelligents. Liés question de ne pas faire cela. La différence est petite en apparence, mais c'est un des grands.
OriginalL'auteur sbi | 2012-01-02
Vous devez vous connecter pour publier un commentaire.
Propriété partagée:
Le
shared_ptr
etweak_ptr
la norme adoptée sont à peu près les mêmes que leurs Boost homologues. Utilisez-la lorsque vous avez besoin de partager une ressource et ne sait pas ce qui sera le dernier à être encore en vie. Utilisationweak_ptr
d'observer la ressource partagée, sans influence sur sa durée de vie, de ne pas briser les cycles. Avec des Cycles deshared_ptr
ne devrait normalement pas se produire - deux ressources ne pouvez pas posséder les uns des autres.Noter que Boost offre en plus
shared_array
, ce qui pourrait être une alternative convenable àshared_ptr<std::vector<T> const>
.Prochain, de Stimuler l'offre
intrusive_ptr
, qui sont une solution légère et si votre ressource offre de référence compte de gestion déjà et que vous souhaitez l'adopter pour le RAII principe. Cette une n'a pas été adopté par la norme.Unique propriété:
Boost a aussi un
scoped_ptr
, ce qui n'est pas copiable et pour laquelle vous ne pouvez pas spécifier un deleter.std::unique_ptr
estboost::scoped_ptr
sur les stéroïdes et devrait être votre choix par défaut lorsque vous avez besoin d'un pointeur intelligent. Il vous permet de spécifier un deleter dans ses arguments de modèle et est mobiliers, contrairement àboost::scoped_ptr
. Il est également utilisable dans des conteneurs STL tant que vous n'utilisez pas les opérations qui doivent copiable types (évidemment).Noter encore, que Boost est un tableau version:
scoped_array
, dont la norme unifiée en exigeantstd::unique_ptr<T[]>
partielle de spécialisation quidelete[]
le pointeur au lieu dedelete
ing (avec ladefault_delete
r).std::unique_ptr<T[]>
propose égalementoperator[]
au lieu deoperator*
etoperator->
.Noter que
std::auto_ptr
est encore dans la norme, mais il est obsolète.§D.10 [depr.auto.ptr]
Aucun droit de propriété:
Utilisation muet pointeurs (raw pointeurs) ou des références pour non propriétaire références de ressources et quand on sait que les ressource va survivre à l'objet de référence /domaine d'application. Préférez les références et utiliser des pointeurs lorsque vous avez besoin de la possibilité de valeur null ou resettability.
Si vous voulez un non propriétaire de référence à une ressource, mais vous ne savez pas si la ressource va survivre à l'objet de référence, pack de ressources dans un
shared_ptr
et l'utilisation d'unweak_ptr
- vous pouvez tester si le parentshared_ptr
est vivant aveclock
, qui sera de retour uneshared_ptr
qui est non-nulle si la ressource existe toujours. Si vous voulez tester si la ressource est morte, l'utilisationexpired
. Les deux se ressemblent, mais sont très différents dans le visage de l'exécution en simultané, commeexpired
ne garantit que sa valeur de retour pour cette seule déclaration. Une apparence innocente, comme le test d'est un potentiel à condition de course.
shared_ptr
et la non possession d'pointeur vers unweak_ptr
...Je ne voulais pas de référence de pointeur, mais plutôt référence au lieu de pointeur. Si il n'y a pas de droit de propriété, sauf si vous avez besoin resettability (ou la possibilité de valeur null, mais la possibilité de valeur null sans être en mesure de réinitialiser serait assez limité), vous pouvez utiliser un brut de référence plutôt qu'un pointeur en premier lieu.
Ah, je vois. 🙂 Oui, les références ne sont pas mauvais pour que, personnellement, je les préfère trop dans de tels cas. Je vais les ajouter.
est une alternative à
shared_ptr<T[]>
de ne passhared_ptr<vector<T>>
: il ne peut pas croître.C'est... exactement ce que j'ai écrit? Je l'ai dit c'est un exemple d'une éventuelle condition de course.
OriginalL'auteur Xeo
Décider de ce pointeur intelligent à utiliser est une question de propriété. Quand il s'agit de la gestion des ressources, l'objet d'Une possède l'objet B si elle est dans le contrôle de la durée de vie de l'objet B. Par exemple, les variables de membre sont la propriété de leurs objets respectifs, car la durée de vie des variables de membre est liée à la durée de vie de l'objet. Vous choisissez des pointeurs intelligents basés sur la façon dont l'objet est la propriété.
Noter que la propriété dans un système de logiciel est séparée de la propriété que nous pensons de lui en dehors du logiciel. Par exemple, une personne pourrait "propre" de leur maison, mais cela ne veut pas nécessairement dire qu'un
Person
objet a le contrôle sur la durée de vie d'unHouse
objet. L'amalgame entre ces monde réel concepts avec le logiciel de concepts est un moyen infaillible pour programmer vous-même dans un trou.Si vous avez l'entière propriété de l'objet, utilisez
std::unique_ptr<T>
.Si vous avez partagé la propriété de l'objet...
- Si il n'y a pas de cycles dans la propriété, l'utilisation
std::shared_ptr<T>
.- Si il y a des cycles, de définir une "direction" et de l'utilisation
std::shared_ptr<T>
dans une direction etstd::weak_ptr<T>
dans l'autre.Si l'objet est propriétaire de vous, mais il est possible de ne pas avoir de propriétaire, de l'utilisation normale des pointeurs
T*
(p. ex. parent pointeurs).Si l'objet possède vous (ou sinon a garanti l'existence), utiliser des références
T&
.Mise en garde: prendre en compte le coût des pointeurs intelligents. Dans la mémoire ou les performances limitées des environnements, il pourrait être bénéfique à juste normal d'utilisation de pointeurs avec un manuel du système de gestion de la mémoire.
Les coûts:
std::shared_ptr
a l'aide d'un compteur de référence de l'incrément sur la copie, en plus d'une diminution de la destruction suivi d'un 0-comte vérifier avec la suppression de l'objet. En fonction de la mise en œuvre, ce qui peut gonfler votre code et provoquer des problèmes de performances.Exemples:
Un arbre binaire n'est pas propriétaire de son parent, mais l'existence d'un arbre implique l'existence de ses parents (ou
nullptr
pour la racine), de sorte qu'utilise un pointeur normal. Un arbre binaire (avec la valeur sémantique) est la propriété exclusive de ses enfants, de sorte que ceux-ci sontstd::unique_ptr
.Ici, la liste nœud possède son prochain et listes précédentes, nous avons donc définir une orientation et de l'utilisation
shared_ptr
pour la prochaine etweak_ptr
pour prev pour briser le cycle.shared_ptr<BinaryTree>
pour les enfants etweak_ptr<BinaryTree>
pour la relation parent.Cela dépend si l'Arbre a une valeur sémantique ou pas. Si les gens vont être le référencement de votre arbre à l'extérieur, même une fois la source de l'arbre est détruit alors oui, partagé/faible pointeur combo serait le mieux.
Si un des objets est propriétaire de vous et est garanti, alors pourquoi pas une référence.
Si vous utilisez de référence, on ne peut pas changer le parent, qui peut ou peut ne pas gêner la conception. Pour l'équilibrage des arbres, ce qui pourrait entraver.
+1, mais vous devriez ajouter une définition de la "propriété" sur la première ligne. Je me retrouve souvent avoir à indiquer clairement qu'il s'agit de la vie & la mort de l'objet, mais pas la propriété dans un domaine plus spécifique de sens.
OriginalL'auteur Peter Alexander
Utilisation
unique_ptr<T>
tout le temps, sauf quand vous avez besoin de comptage de référence, auquel cas l'utilisationshared_ptr<T>
(et pour de très rares cas,weak_ptr<T>
pour éviter des cycles de référence). Dans presque tous les cas, transférable unique propriété est tout simplement parfait.Raw pointeurs: Bon si vous avez besoin d'covariante renvoie, non propriétaire de pointage qui peut arriver. Ils ne sont pas terriblement utile autrement.
Tableau de pointeurs:
unique_ptr
a une spécialisation pourT[]
qui appelle automatiquementdelete[]
sur le résultat, de sorte que vous pouvez faire en toute sécuritéunique_ptr<int[]> p(new int[42]);
par exemple.shared_ptr
vous auriez encore besoin d'un custom deleter, mais vous n'avez pas besoin d'une institution spécialisée ou partagée unique pointeur sur le tableau. Bien sûr, ces choses qui sont généralement la meilleure remplacé parstd::vector
de toute façon. Malheureusementshared_ptr
ne fournit pas un tableau de fonction, alors vous pourriez avoir encore manuellement appelget()
, maisunique_ptr<T[]>
fournitoperator[]
au lieu deoperator*
etoperator->
. Dans tous les cas, vous devez les limites de vérifier vous-même. Cela rendshared_ptr
un peu moins convivial, bien que sans doute le générique avantage et pas de Stimuler la dépendanceunique_ptr
etshared_ptr
les gagnants de nouveau.L'étendue des pointeurs: Fait hors de propos par
unique_ptr
, tout commeauto_ptr
.Il n'y a vraiment rien de plus. En C++03, sans déplacer la sémantique de cette situation a été très compliqué, mais en C++11 le conseil est très simple.
Il y a encore utilise pour les autres pointeurs intelligents, comme
intrusive_ptr
ouinterprocess_ptr
. Cependant, ils sont très niche et totalement inutile dans le cas général.J'ai déjà modifié pour inclure de telles.
Hmm, la façon dont j'ai lu ça, c'est des situations qui sont à la fois covariant de retour et non propriétaire. Une réécriture pourrait être bon si vous parliez de l'union plutôt que d'intersection. Je voudrais aussi dire que itération mérite une mention particulière également.
std::unique_ptr<T[]>
fournitoperator[]
au lieu deoperator*
etoperator->
. Il est vrai que vous avez encore besoin de faire lié à vérifier tout de même.OriginalL'auteur Puppy
Cas d'utilisation de
unique_ptr
:Cas d'utilisation de
shared_ptr
:Cas d'utilisation de
weak_ptr
:N'hésitez pas à modifier et ajouter plus de
OriginalL'auteur Lalaland