10
votes

Pointeurs vs auto_ptr vs partagé_ptr

J'ai récemment été introduit à l'existence de auto_ptr et partagé_ptr et j'ai une question assez simple / naïve.

J'essaie de mettre en œuvre une structure de données et je Besoin de pointer vers les enfants d'un noeud qui (plus de 1 et sa) numéro peut changer. Quelle est la meilleure alternative et pourquoi: xxx

Je ne suis pas sûr, mais je pense que auto_ptr ne fonctionne pas pour les tableaux. Je ne suis pas sûr de savoir si je devrais utiliser des doubles pointeurs. Merci pour toute aide.


3 commentaires

Auto_PTR est obsolète en C ++ 11 et doit être évité si possible dans le code dans la version plus ancienne C ++.


auto_ptr est obsolète car il est inutilement difficile à utiliser correctement. Utilisez unique_ptr à la place, qui est fondamentalement identique à auto_ptr , juste pour cela fonctionne correctement et prend également en charge les tableaux. Il est disponible depuis C ++ 11.


Regardez également Stackoverflow.com/Questtions/3987521/...


4 Réponses :


9
votes

Vous avez raison que Auto_PTR ne fonctionne pas pour les tableaux. Lorsqu'il détruit l'objet, il utilise un objet Supprimer; , donc si vous avez utilisé nouveaux objets [autre]; , vous obtiendrez un comportement non défini. Peut-être un peu plus subtilement, auto_ptr ne correspond pas aux exigences de "COYBLE" (comme la norme définit le terme) afin que vous ne puissiez pas créer de conteneur (vecteur, deque, liste, etc.) de auto_ptr non plus.

A partagé_ptr est également destiné à un seul objet. C'est pour une situation où vous avez partagé la propriété et avez besoin de supprimer l'objet uniquement lorsque tous les les propriétaires sont hors de portée. À moins que quelque chose ne se passe quelque chose que vous ne nous avez pas parlé, les chances sont plutôt bonnes que cela ne correspond pas très bien à vos besoins.

Vous voudrez peut-être examiner encore une autre classe qui peut être nouvelle pour vous: boost ptr_vector . Au moins sur la base de ce que vous avez dit, il semble mieux adapter vos besoins que votre auto_ptr ou partagé_ptr serait.


2 commentaires

Merci! Donc, je reçois que je devrais aller avec pTR_Vector ou nœud * enfants . Impossible d'utiliser auto_ptr pour pointer sur un std :: vecteur de nœud s? En outre, est le noeud * enfants droit ou je préférerais préférer nœud ** enfants ? Je suis un peu confus. Désolé d'avoir emballé trop de questions ici.


@MYLE: Sans en savoir plus sur ce que vous faites, il est difficile de dire à coup sûr. Fondamentalement, un nœud * vous donnera un point à un nombre arbitraire de nœuds, de sorte que ces nœuds feront fondamentalement partie de leur parent, non seulement liés à celui-ci. Un nœud ** vous permettra d'avoir une gamme dynamique de pointeurs sur des nœuds, mais vous devrez gérer vous-même la matrice dynamique.



4
votes

J'ai utilisé std :: vecteur > enfants avec succès dans une situation similaire.

Le principal avantage d'utiliser un vecteur de Shared_Ptrs plutôt que d'un tableau est que toute la gestion des ressources est manipulée pour vous. Ceci est particulièrement pratique dans deux situations:
1) Lorsque le vecteur n'est plus en portée, il appelle automatiquement la suppression de tout son contenu. Dans ce cas, le nombre de références du nœud enfant baissera par 1 et si rien d'autre ne le fait référence, supprimer sera appelé sur l'objet.
2) Si vous référencez le nœud ailleurs, il n'ya aucun risque d'être laissé avec un pointeur pendant un objet supprimé. L'objet ne sera supprimé que lorsqu'il n'y a plus de références à cela.

Sauf si vous voulez un comportement sensiblement plus compliqué (peut-être qu'il y a une raison pour laquelle un tableau est nécessaire), je suggérerais que cela pourrait être Une bonne approche pour vous.

Une simple mise en œuvre de l'idée: xxx


2 commentaires

Notez également que vous pouvez fournir votre propre destructeur à un Shared_PTR afin que vous puissiez utiliser un pour gérer un tableau en appelant Suppr [] au lieu de la suppression simple.


Le moyen le plus simple (mais légèrement laid) d'ajouter un Deleter personnalisé pour les tableaux est d'utiliser une fonction Lambda, qui est transmise dans le constructeur comme argument supplémentaire. EG.: STD :: Shared_PTR SP (nouveau t [n], [] (T * P) {Supprimer [] P;}) . Pour uniques_ptrs, une version spéciale est fournie pour cela: 'std :: unique_ptr up (nouveau t [n])' qui appelle supprimer [] plutôt que DELETE.



2
votes

auto_ptr est obsolète en faveur de std :: unique_ptr et BTW. std :: unique_ptr fonctionne pour les tableaux. Vous avez juste besoin de support C ++ 11. Et il y a déjà beaucoup de ressources sur les pointeurs intelligents et déplacez la sémantique là-bas. La principale différence entre auto_ptr et unique_ptr est que auto_ptr est un déplacer lorsque vous appelez le constructeur de copie et unique_ptr interdit le constructeur de copie, mais permet à un déplacer lorsque vous appelez le constructeur de déplacement. Par conséquent, vous avez besoin de support C ++ 11 avec une sémantique de déplacement.


0 commentaires

1
votes

STROSTRUP discute de la question de "Qu'est-ce qu'un auto_ptr et pourquoi n'existe-t-il pas d'auto_array" et conclut qu'il n'y a pas besoin de ce dernier puisque la fonctionnalité souhaitée peut être accomplie avec un vecteur.

http://www.stroustrup.com/bs_faq2.html#auto_ptr


0 commentaires