Doublons Possibles:
pimpl: shared_ptr ou unique_ptr
des pointeurs intelligents (boost) a expliquéQuelqu'un pourrait-il expliquer les différences entre les shared_ptr et unique_ptr?
Réponses
Trop de publicités?Ces deux classes sont des pointeurs intelligents, ce qui signifie qu'ils automatiquement (dans la plupart des cas) désalloue l'objet qu'elles point lorsque l'objet ne peut plus être référencée. La différence entre les deux est de savoir comment beaucoup de différents pointeurs de chaque type peut se référer à une ressource.
Lors de l'utilisation d' unique_ptr
, il peut y avoir au plus un unique_ptr
de pointage à la ressource. Lorsque qu' unique_ptr
est détruit, la ressource est automatiquement récupéré. Car il ne peut être une unique_ptr
pour toute ressource, toute tentative de faire une copie d'un unique_ptr
provoquera une erreur de compilation. Par exemple, ce code est illégal:
unique_ptr<T> myPtr(new T); // Okay
unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptr
Toutefois, unique_ptr
peut être déplacé à l'aide de la nouvelle sémantique de déplacement:
unique_ptr<T> myPtr(new T); // Okay
unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtr
De même, vous pouvez faire quelque chose comme ceci:
unique_ptr<T> MyFunction() {
unique_ptr<T> myPtr(/* ... */);
/* ... */
return myPtr;
}
Cette locution signifie: "je suis de retour d'une ressource gérée pour vous. Si vous n'avez pas explicitement de capture de la valeur de retour, alors que la ressource sera nettoyé. Si vous le faites, alors vous avez maintenant la propriété exclusive de la ressource." De cette façon, vous pouvez penser à de la unique_ptr
comme un endroit plus sûr, meilleur remplacement pour l' auto_ptr
.
shared_ptr
, d'autre part, permet plusieurs pointeurs à point à une ressource donnée. Lors de la dernière shared_ptr
d'une ressource est détruit, la ressource va être libéré. Par exemple, ce code est parfaitement légal:
shared_ptr<T> myPtr(new T); // Okay
shared_ptr<T> myOtherPtr = myPtr; // Sure! Now have two pointers to the resource.
En interne, shared_ptr
utilise le comptage de référence pour déterminer le nombre de pointeurs de se référer à une ressource, alors vous devez faire attention de ne pas introduire des cycles de référence.
En bref:
- Utiliser
unique_ptr
lorsque vous voulez qu'un seul pointeur vers un objet qui sera récupérée lors que seul pointeur est détruit. - Utiliser
shared_ptr
quand vous voulez plusieurs pointeurs à la même ressource.
Espérons que cette aide!
unique_ptr
est la lumière-poids de pointeur intelligent de choix si vous avez juste un objet dynamique, quelque part, pour laquelle un consommateur est seul (d'où le terme "unique") de la responsabilité, peut-être une classe wrapper qui doit conserver une certaine allouée dynamiquement objet. unique_ptr
a très peu de frais généraux. Il n'est pas copiable, mais mobiliers. Son type est - template <typename D, typename Deleter> class unique_ptr;
, il dépend donc de deux paramètres du modèle.
unique_ptr
est aussi ce que l' auto_ptr
voulais être dans le vieux C++, mais ne pouvait pas à cause de la langue de ses limites.
shared_ptr
d'autre part, c'est très différent de l'animal. La différence la plus évidente est que vous pouvez avoir de nombreux consommateurs partage de la responsabilité pour un objet dynamique (d'où "partagé"), et l'objet ne seront détruits lorsque tous partagé les pointeurs ont disparu. En outre, vous pouvez avoir l'observation des pointeurs faibles qui se fait de manière intelligente être informé si le pointeur partagé ils suivent a disparu.
En interne, shared_ptr
a beaucoup plus de choses: Il y a un compteur de référence, qui est mis à jour automatiquement afin de permettre l'utilisation en simultané de code. Aussi, il y a beaucoup de ressources en cours, l'un pour une comptabilité interne de référence pour le "bloc de contrôle", et un autre (souvent) pour le membre réel de l'objet.
Mais il y a une autre grande différence: Les pointeurs partagés type est toujours template <typename T> class shared_ptr;
, et ce, malgré le fait que vous pouvez l'initialiser avec la coutume deleters et personnalisée avec des allocateurs. La deleter et l'allocateur sont suivis à l'aide du type d'effacement et d'virtuel de la fonction de répartition, ce qui ajoute du poids interne de la classe, mais a l'énorme avantage que les différentes sortes de partagé des pointeurs de type T
compatible avec tous les modèles, peu importe la suppression et de l'allocation de détails. Ainsi, ils ont vraiment exprimer le concept de "responsabilité partagée pour l' T
" sans peser sur le consommateur avec les détails!
Les deux shared_ptr
et unique_ptr
sont conçus pour être passé par valeur (à l'exigence de mobilité pour le pointeur unique). Ni devrait vous inquiet à propos de la surcharge, car leur puissance est vraiment incroyable, mais si vous avez le choix, préférez unique_ptr
, et de n'utiliser shared_ptr
si vous avez vraiment besoin de responsabilité partagée.
unique_ptr
est un pointeur intelligent qui possède un objet exclusivement.
shared_ptr
est un pointeur intelligent pour le partage de la propriété. Il est à la fois copyable
et movable
. Plusieurs pointeur intelligent instances peuvent posséder la même ressource. Dès que le dernier pointeur intelligent propriétaire de la ressource est hors de portée, la ressource va être libéré.
Lorsque l'enveloppant d'un pointeur dans un unique_ptr
vous ne pouvez pas avoir plusieurs copies d' unique_ptr
. L' shared_ptr
détient un compteur de références qui permettent de compter le nombre de copies du pointeur stocké. Chaque fois qu'un shared_ptr
est copié, ce compteur est incrémenté. Chaque fois qu'un shared_ptr
est détruite, ce compteur est décrémenté. Lorsque ce compteur atteint 0, puis stockées objet est détruit.