Les pointeurs vs auto_ptr vs shared_ptr
J'ai été récemment introduit à l'existence de auto_ptr
et shared_ptr
et j'ai un assez simple/naïve question.
J'essaie de mettre en œuvre une structure de données et j'ai besoin de point pour les enfants d'un Node
qui (sont plus que de 1 et de ses) numéro peut changer. Qui est la meilleure solution et pourquoi:
class Node
{
public:
//...
Node *children;
private:
//...
}
class Node
{
public:
//...
share_ptr<Node> children;
private:
//...
}
Je ne suis pas sûr, mais je pense que auto_ptr
ne fonctionne pas pour les tableaux. Je ne suis pas, aussi, assurez-vous pour savoir si je dois utiliser des doubles pointeurs. Merci pour toute aide.
auto_ptr est déconseillée en C++11 et doit être évitée si possible dans le code dans les anciennes version C++.
aussi jeter un oeil à stackoverflow.com/questions/3987521/...
auto_ptr
est déconseillée car elle est inutilement difficile à utiliser correctement. Utilisation unique_ptr
à la place qui est essentiellement la même que auto_ptr
, juste qu'il fonctionne correctement et prend également en charge les tableaux. Il est disponible depuis le C++11.aussi jeter un oeil à stackoverflow.com/questions/3987521/...
OriginalL'auteur Dimitris Leventeas | 2010-09-25
Vous devez vous connecter pour publier un commentaire.
Vous avez raison, auto_ptr ne fonctionne pas pour les tableaux. Lorsqu'il détruit l'objet qu'il possède, il utilise
delete object;
, si vous avez utilisénew objects[whatever];
, vous aurez un comportement indéfini. Peut-être un peu plus subtilement,auto_ptr
qui ne répond pas aux exigences de la "Copiable" (comme la norme définit le terme), de sorte que vous ne pouvez pas créer un conteneur (vector, deque, liste, etc.) deauto_ptr
.Un
shared_ptr
est pour un seul objet. C'est une situation où vous avez partagé la propriété et de la nécessité de supprimer l'objet uniquement lorsque tous les propriétaires hors de portée. Sauf s'il ya quelque chose que vous n'avez pas dit de nous sur, les chances sont très bonnes que cela ne correspond pas à vos exigences très bien.Vous pouvez chercher encore une autre classe qui peut être nouveau pour vous: Boost ptr_vector. Au moins d'après ce que vous avez dit, il semble adapté à vos besoins mieux que ce soit
auto_ptr
oushared_ptr
serait.ptr_vector
ouNode * children
. Ne pourrais-je utiliserauto_ptr
unestd::vector
deNode
s? En outre, c'est laNode * children
droite ou, devrais-je préfèreNode ** children
? Je suis un peu confus. Désolé pour l'emballage de trop nombreuses questions ici.Sans en savoir plus sur ce que vous faites, c'est difficile à dire pour sûr. Fondamentalement, un
Node *
vous donnera un point à un nombre quelconque de Nœuds, les nœuds sera essentiellement une partie de leur parent, et pas seulement liés à l'informatique. UnNode **
vous permettra d'avoir un tableau dynamique de pointeurs vers les nœuds, mais vous aurez à gérer la dynamique de la matrice de vous-même.OriginalL'auteur Jerry Coffin
J'ai utilisé
std::vector<std::shared_ptr<Node> > children
avec succès dans une situation similaire.Le principal avantage de l'utilisation d'un vecteur de shared_ptrs plutôt qu'un tableau, c'est que l'ensemble de la gestion des ressources est pris en charge pour vous. Ceci est particulièrement utile dans deux situations:
1) Lorsque le vecteur est plus étendue, il appelle automatiquement supprimer sur l'ensemble de son contenu. Dans ce cas, le nombre de références du Nœud enfant aura une baisse de 1, et si rien d'autre n'est le référencement, la supprimer sera appelée sur l'objet.
2) Si vous référencez le Nœud d'ailleurs, il n'y a pas de risque de se retrouver avec un bancales pointeur vers un objet supprimé. L'objet sera supprimé seulement lorsqu'il n'y a plus de références.
Sauf si vous voulez un comportement qui est plus compliqué (peut-être il ya une raison pourquoi un tableau est nécessaire), je suggère ce qui pourrait être une bonne approche pour vous.
Une simple mise en œuvre de l'idée:
Le plus simple (mais un peu moche) de façon à ajouter un deleter pour les tableaux est d'utiliser une fonction lambda, qui est passé dans le constructeur comme un argument supplémentaire. Ex.:
std::shared_ptr<T> sp(new T[n], [](T *p){ delete[] p; })
. Pour unique_ptrs il existe une version spéciale prévue à ceci: "std::unique_ptr<T[]> (T[n])' qui appelle delete[] au lieu de la supprimer.OriginalL'auteur QuesterZen
auto_ptr
est dépréciée en faveur destd::unique_ptr
et btw.std::unique_ptr
ne travail que pour les tableaux. Vous avez juste besoin de c++11. Et il y a déjà beaucoup de ressources sur les pointeurs intelligents et sémantique de déplacement. La principale différence entreauto_ptr
etunique_ptr
est queauto_ptr
un déplacer lorsque vous appelez le constructeur de copie etunique_ptr
interdit le constructeur de copie, mais permet unemove
lors de l'appel du constructeur de déplacement. Par conséquent, vous avez besoin de c++11 avec la sémantique de déplacement.OriginalL'auteur Arne
Stroustrup aborde la question de "qu'est Ce qu'un auto_ptr et pourquoi n'est-il pas un auto_array" et conclut qu'il n'est pas nécessaire pour ce dernier puisque la fonctionnalité désirée peut être accompli avec des un vecteur.
http://www.stroustrup.com/bs_faq2.html#auto_ptr
OriginalL'auteur Dave S