Doublons possibles:
pimpl: shared_ptr ou unique_ptr
explication des pointeurs intelligents (boost)
Quelqu'un pourrait-il expliquer les différences entre shared_ptr et unique_ptr?
Ces deux classes sont des pointeurs intelligents, ce qui signifie qu'elles désallouent automatiquement (dans la plupart des cas) l'objet sur lequel elles pointent lorsque cet objet ne peut plus être référencé. La différence entre les deux est le nombre de pointeurs différents de chaque type pouvant faire référence à une ressource.
Lorsque vous utilisez _unique_ptr
_, il peut y avoir au plus un _unique_ptr
_ pointant sur une ressource quelconque. Lorsque ce _unique_ptr
_ est détruit, la ressource est automatiquement récupérée. Etant donné qu'il ne peut y avoir qu'un seul _unique_ptr
_ par ressource, toute tentative de copie d'un _unique_ptr
_ entraînera une erreur lors de la 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
_
Cependant, _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;
}
_
Cet idiome signifie "Je vous renvoie une ressource gérée. Si vous ne capturez pas explicitement la valeur de retour, la ressource sera nettoyée. Si vous le faites, vous êtes maintenant le propriétaire exclusif de cette ressource." De cette façon, vous pouvez considérer _unique_ptr
_ comme un remplacement plus sûr et meilleur pour _auto_ptr
_.
_shared_ptr
_ permet en revanche à plusieurs pointeurs de pointer sur une ressource donnée. Lorsque le dernier _shared_ptr
_ d'une ressource est détruit, la ressource est désallouée. 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 comptage de références pour suivre le nombre de pointeurs référant à une ressource. Vous devez donc veiller à ne pas introduire de cycles de référence.
En bref:
unique_ptr
_ lorsque vous souhaitez un seul pointeur sur un objet qui sera récupéré lorsque ce pointeur unique sera détruit.shared_ptr
_ lorsque vous souhaitez que plusieurs pointeurs pointent vers la même ressource.J'espère que cela t'aides!
unique_ptr
est le pointeur intelligent le plus léger de votre choix si vous avez juste un objet dynamique quelque part pour lequel un consommateur a le seul (donc "unique"). ") responsabilité - peut-être une classe wrapper qui doit maintenir un objet alloué dynamiquement. unique_ptr
a très peu de frais généraux. Ce n'est pas copiable, mais amovible. Son type est template <typename D, typename Deleter> class unique_ptr;
, il dépend donc de deux paramètres de modèle .
unique_ptr
est aussi ce que auto_ptr
voulait être dans l'ancien C++ mais ne le pouvait pas en raison des limitations de ce langage.
shared_ptr
est en revanche un animal très différent. La différence évidente est que de nombreux consommateurs peuvent partager la responsabilité d'un objet dynamique (donc "partagé"), et l'objet ne sera détruit que lorsque tous les pointeurs partagés auront disparu. De plus, vous pouvez avoir des pointeurs faibles qui seront informés de manière intelligente si le pointeur partagé qu'ils suivent a disparu.
En interne, shared_ptr
a encore beaucoup à faire: Il existe un compte de références mis à jour de manière atomique pour permettre son utilisation dans du code concurrent. En outre, de nombreuses affectations sont en cours, une pour un "bloc de contrôle de référence" de comptabilité interne et une autre (souvent) pour l'objet membre réel.
Mais il y a une autre grande différence: le type de pointeurs partagés est toujours template <typename T> class shared_ptr;
, et ceci malgré le fait que vous pouvez l'initialiser avec des deleters personnalisés et avec des allocateurs personnalisés. Le deleter et l'allocateur sont suivis à l'aide de l'effacement de type et de la répartition de la fonction virtuelle, ce qui ajoute au poids interne de la classe, mais présente l'énorme avantage que différentes sortes de pointeurs partagés de type T
sont tous compatibles, quelle que soit la suppression. et les détails de l'allocation. Ainsi, ils expriment réellement le concept de "responsabilité partagée pour T
" sans alourdir le consommateur avec les détails!
shared_ptr
et unique_ptr
sont tous deux conçus pour être passés par valeur (avec l'exigence évidente de mobilité pour le pointeur unique). Vous ne devriez pas non plus vous inquiéter pour les frais généraux, car leur puissance est vraiment stupéfiante, mais si vous avez le choix, préférez unique_ptr
et utilisez uniquement shared_ptr
si vous avez vraiment besoin de responsabilité partagée.
nique_ptr
est un pointeur intelligent qui possède un objet exclusivement.
shared_ptr
est un pointeur intelligent pour la propriété partagée. C'est à la fois copyable
et movable
. Plusieurs instances de pointeur intelligent peuvent posséder la même ressource. Dès que le dernier pointeur intelligent propriétaire de la ressource sera hors de portée, la ressource sera libérée.
Lorsque vous placez un pointeur dans un unique_ptr
, vous ne pouvez pas avoir plusieurs copies de unique_ptr
. Le shared_ptr
contient un compteur de référence qui compte 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étruit, ce compteur est décrémenté. Lorsque ce compteur atteint 0, l'objet stocké est détruit.