Quelles sont les meilleures pratiques pour le passage d’un shared_ptr ?
Actuellement je passe shared_ptr arguments de la fonction comme suit :
Quelles sont les meilleures pratiques pour le passage d’un shared_ptr ?
Actuellement je passe shared_ptr arguments de la fonction comme suit :
Dans des circonstances contrôlées, vous pouvez passer le pointeur partagé par référence constante. Assurez-vous que personne n'est en même temps la suppression de l'objet, si cela ne devrait pas être trop difficile si vous êtes prudents à qui vous donnez des références.
En général, vous devez passer le pointeur partagé comme un droit de copie. Ce qui lui donne sa sémantique: Chaque champ qui contient une copie du pointeur partagé maintient l'objet actif en vertu de son "action" dans la propriété.
La seule raison de ne pas toujours passer par valeur, c'est que la copie d'un pointeur partagé arrive à un certain prix, compte tenu de la atomique de comptage de référence de mise à jour; toutefois, cela pourrait ne pas être une préoccupation majeure.
En option digression:
Étant donné que la principale question a été posée, c'est peut-être intéressant d'examiner quelques façons dont vous devriez ne jamais utiliser un pointeur partagé. Voici une petite expérience de pensée. Laissez-nous définir un pointeur partagé de type SF = std::shared_ptr<Foo>
. Afin de tenir compte de références, plutôt que de passer des arguments de la fonction regardons le type RSF = std::reference_wrapper<T>
. C'est, si nous avons un pointeur partagé SF p(std::make_shared<Foo>());
, alors on peut faire un wrapper de référence avec la valeur sémantique via RSF w = std::ref(p);
. Voilà pour le programme d'installation.
Maintenant, tout le monde sait que les contenants de pointeurs sont des champs de mines. Donc, std::vector<Foo*>
va être un cauchemar à maintenir, et un certain nombre de bugs surviennent d'une mauvaise gestion de durée de vie. Ce qui est pire sur le plan conceptuel, c'est qu'il n'est jamais clairement qui détient les objets dont les pointeurs le conteneur des magasins. Les pointeurs pourrait même être un mélange de pointeurs vers des objets dynamiques, automatique d'objets et de déchets. Personne ne peut le dire. Donc la solution standard est d'utiliser std::vector<SF>
à la place. Ce est La bonne Façon d'utiliser le pointeur partagé. D'autre part, ce que vous ne devez jamais utiliser est - std::vector<RSF>
-- c'est un monstre ingérable qui est en fait très semblable à l'original de vecteur de pointeurs nus! Par exemple, il n'est pas clair si l'objet pour lequel vous détenez une référence est toujours en vie. En prenant une référence de pointeur partagé a vaincu l'ensemble de son but.
Pour un deuxième exemple, supposons que nous avons un pointeur partagé SF p
comme avant. Maintenant, nous avons une fonction d' int foo(SF)
que nous voulons exécuter simultanément. L'habituel std::thread(foo, p)
fonctionne très bien, depuis le thread constructeur fait une copie de ses arguments. Cependant, avions-nous dit - std::thread(foo, std::ref(p))
, nous serions dans toutes sortes de difficultés: Le pointeur partagé dans l'appel de la portée risque d'expirer et de détruire l'objet, et vous serez à gauche avec une balançant de référence et un pointeur non valide!
J'espère que ces deux certes assez artificiel exemples jeté un peu de lumière sur, lorsque vous voulez vraiment que votre partagée pointeurs être passés par copie. Dans un programme bien conçu, il doit toujours être clairement qui est responsable de ressources et, à droite, le pointeur partagé est un excellent outil pour le travail.
Cela dépend de ce que vous voulez. Si le destinataire de l'appel de partager la propriété de l'objet? Ensuite, il a besoin de sa propre copie de l' shared_ptr
. Donc passer par valeur.
Si une fonction a besoin tout simplement d'accéder à un objet possédé par l'appelant, aller de l'avant et de passer par (const) de référence, pour éviter la surcharge de la copie de l' shared_ptr
.
La meilleure pratique en C++ est toujours d'avoir clairement défini la propriété sémantique de vos objets. Il n'est pas universelle "toujours le faire" à la place du réel de la pensée.
Si vous avez toujours passer partagé pointeurs en valeur, il devient coûteux (car ils sont beaucoup plus cher à copier qu'un pointeur brut). Si vous ne jamais le faire, alors il n'y a pas de point à l'aide d'un pointeur partagé en premier lieu.
Copie le pointeur partagé lorsqu'une nouvelle fonction ou un objet a besoin de partager la propriété de la pointee.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.