J'ai entendu auto_ptr
dire qu'il était obsolète dans C ++ 11. Quelle est la raison pour ça?
J'aimerais aussi connaître la différence entre auto_ptr
et shared_ptr
.
c++
c++11
smart-pointers
auto-ptr
Brett
la source
la source
Réponses:
Le remplacement direct pour
auto_ptr
(ou la chose la plus proche de l'une de toute façon) estunique_ptr
. En ce qui concerne le «problème», c'est assez simple:auto_ptr
transfère la propriété lorsqu'elle est attribuée.unique_ptr
transfère également la propriété, mais grâce à la codification de la sémantique de déplacement et à la magie des références rvalue, il peut le faire beaucoup plus naturellement. Il «s'adapte» également beaucoup mieux au reste de la bibliothèque standard (bien que, en toute honnêteté, cela soit dû en partie au changement du reste de la bibliothèque pour s'adapter à la sémantique de déplacement au lieu de toujours exiger la copie).Le changement de nom est également le bienvenu (IMO) -
auto_ptr
ne vous en dit pas vraiment beaucoup sur ce qu'il tente d'automatiser, alors qu'ilunique_ptr
s'agit d'une description assez raisonnable (si laconique) de ce qui est fourni.la source
auto_ptr
nom: auto suggère automatique comme dans la variable automatique, et il se réfère à une chose quiauto_ptr
fait: détruire la ressource gérée dans son destructeur (quand elle est hors de portée).auto_ptr
: open-std.org/jtc1/sc22/wg21/docs/papers/2005std::sort
n'a pas de spécialisation pourunique_ptr
. Au lieu de cela, il a été redéfini pour ne jamais copier. Donc , enauto_ptr
réalité fait le travail avec le modernesort
. Mais le C ++ 98/03sort
n'est qu'un exemple d'algorithme ici: tout algorithme générique (fourni par std ou écrit par l'utilisateur) qui suppose que la syntaxe de copie a une sémantique de copie aura probablement une erreur d'exécution s'il est utilisé avecauto_ptr
, car se déplaceauto_ptr
silencieusement avec la syntaxe de copie . Le problème est bien plus vaste que juste .sort
J'ai trouvé les réponses existantes excellentes, mais à partir du PoV des pointeurs. OMI, une réponse idéale devrait avoir la réponse du point de vue de l'utilisateur / programmeur.
Tout d'abord (comme l'a souligné Jerry Coffin dans sa réponse)
shared_ptr: Si vous êtes préoccupé par la libération de ressources / mémoire ET si vous avez plus d'une fonction qui pourrait utiliser l'objet AT-DIFFERENT fois, optez pour shared_ptr.
Par DIFFERENT-Times, pensez à une situation dans laquelle l'objet-ptr est stocké dans plusieurs structures de données et accédé plus tard. Plusieurs threads, bien sûr, est un autre exemple.
unique_ptr: Si tout ce qui vous préoccupe est de libérer de la mémoire et que l'accès à l'objet est SEQUENTIAL, alors optez pour unique_ptr.
Par SÉQUENTIEL, je veux dire, à tout moment, un objet sera accessible à partir d'un contexte. Par exemple, un objet qui a été créé et utilisé immédiatement après sa création par le créateur. Après la création, l'objet est stocké dans la structure de données FIRST . Ensuite, soit l'objet est détruit après la structure de données ONE, soit est déplacé vers la structure de données SECOND .
À partir de cette ligne, je ferai référence à _ptr partagé / unique en tant que pointeurs intelligents. (auto_ptr est également un pointeur intelligent MAIS en raison de défauts dans sa conception, pour lesquels ils sont obsolètes, et que je pense que je vais souligner dans les prochaines lignes, ils ne doivent pas être regroupés avec un pointeur intelligent.)
À partir du lien: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Type d'affectations prises en charge par unqiue_ptr
De: http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
Type d'affectations prises en charge par auto_ptr
Venant maintenant à la raison pour laquelle l'affectation de copie elle-même n'a pas été si appréciée, j'ai cette théorie:
Le comportement involontaire est vraiment détesté et donc l'aversion pour l'auto_ptr.
(Pour les 3,1415926536% de programmeurs qui souhaitent intentionnellement transférer la propriété, C ++ 11 leur a donné std :: move (), ce qui a clairement indiqué leur intention à tous les stagiaires qui vont lire et maintenir le code.)
la source
auto_ptr
valeurs pointent vers le même objet (puisqu'elles ne donnent pas la propriété partagée, le premier à mourir laissera l'autre avec un héritage mortel; cela est également vrai pour l'unique_ptr
usage), pouvez-vous suggérer ce qui était prévu dans ceux qui restent 96.8584073465% de toute l'utilisation?*a=*b;
ici, seule la valeur de b est copiée dans a. J'espère que la propriété de a et de b appartient toujours aux mêmes personnes. Vous avez mentionné que la propriété sera transférée. Comment ça va être?auto_ptr
objet lui-même. L'attribution de / à partir de sa valeur désignée n'a aucun effet sur la propriété ni aucune pertinence pour celle-ci. J'espère que vous ne l'utilisez pas encoreauto_ptr
?shared_ptr
peuvent être stockés dans des conteneurs.auto_ptr
ne peut pas.BTW
unique_ptr
est vraiment leauto_ptr
remplacement direct , il combine les meilleures fonctionnalités des deuxstd::auto_ptr
etboost::scoped_ptr
.la source
Encore une autre façon d'expliquer la différence ...
Fonctionnellement, C ++ 11
std::unique_ptr
est le "fixe"std::auto_ptr
: les deux conviennent quand - à tout moment pendant l'exécution - il devrait y avoir un seul propriétaire de pointeur intelligent pour un objet pointé vers.La différence cruciale réside dans la construction de la copie ou l'affectation à partir d'un autre pointeur intelligent non expirant, illustré sur les
=>
lignes ci-dessous:Ci-dessus,
ap3
discrètement "vole" la propriété de*ap
, en laissant leap
réglage à anullptr
, et le problème est que cela peut arriver trop facilement, sans que le programmeur ait pensé à sa sécurité.Par exemple, si un
class
/struct
a unstd::auto_ptr
membre, alors faire une copie d'une instance serarelease
le pointeur de l'instance en cours de copie: c'est une sémantique étrange et dangereusement déroutante car généralement copier quelque chose ne le modifie pas. Il est facile pour l'auteur de la classe / structure d'ignorer la publication du pointeur lors du raisonnement sur les invariants et l'état, et par conséquent de tenter accidentellement de déréférencer le pointeur intelligent alors qu'il est nul, ou tout simplement de ne pas avoir toujours l'accès / la propriété prévu des données pointées.la source
auto_ptr ne peut pas être utilisé dans les conteneurs STL car il possède un constructeur de copie qui ne répond pas aux exigences du conteneur CopyConstructible . unique_ptr n'implémente pas de constructeur de copie, les conteneurs utilisent donc d'autres méthodes. unique_ptr peut être utilisé dans des conteneurs et est plus rapide pour les algorithmes std que shared_ptr.
la source