51 votes

Y a-t-il des inconvénients à utiliser make_shared pour créer un TP partagé ?

Y a-t-il des inconvénients à utiliser make_shared<T>() au lieu d'utiliser shared_ptr<T>(new T) .

Améliorer la documentation États

Les utilisateurs ont demandé à plusieurs reprises utilisateurs pour une fonction usine qui crée un objet d'un type donné et renvoie un tronc partagé vers celui-ci. Outre pratique et de style, une telle fonction est également sans danger pour les exceptions et considérablement plus rapide car elle peut utiliser une allocation unique à la fois pour l'objet et son bloc de contrôle correspondant de contrôle correspondant, éliminant ainsi une partie importante de la construction de shared_ptr construction de shared_ptr. Ceci élimine l'une des principales plaintes concernant l'efficacité de shared_ptr.

38voto

sbk Points 4987

En plus des points présentés par @deft_code, un point encore plus faible :

  • Si vous utilisez weak_ptr qui vivent après tous les shared_ptr à un objet donné sont morts, alors la mémoire de cet objet vivra en mémoire avec le bloc de contrôle jusqu'à ce que le dernier weak_ptr meure. En d'autres termes, l'objet est détruit mais n'est pas désaffecté jusqu'à ce que le dernier weak_ptr est détruit.

26voto

deft_code Points 19418

J'en connais au moins deux.

  • Vous devez avoir le contrôle de l'allocation. Ce n'est pas vraiment une question importante, mais certaines api plus anciennes renvoient des pointeurs que vous devez supprimer.
  • Pas de suppresseur personnalisé. Je ne sais pas pourquoi ce n'est pas supporté, mais ça ne l'est pas. Cela signifie que vos pointeurs partagés doivent utiliser un suppresseur vanille.

Des points faibles assez importants. Essayez donc de toujours utiliser make_shared.

14voto

Viktor Sehr Points 5634

De http://www.codesynthesis.com/~boris/blog/2010/05/24/smart-pointers-in-boost-tr1-cxx-x0/

L'autre inconvénient de l'implémentation de make_shared() est l'augmentation de la taille du code objet. En raison de la manière dont cette optimisation est mise en œuvre, une table virtuelle supplémentaire ainsi qu'un ensemble de fonctions virtuelles seront instanciés pour chaque type d'objet que vous utilisez avec make_shared().

8voto

Darthenius Points 1828

En outre, make_shared n'est pas compatible avec le modèle d'usine . Cela est dû au fait que l'appel à make_shared dans votre fonction d'usine appelle le code de la bibliothèque, qui appelle à son tour new à laquelle elle n'a pas accès, puisqu'il ne peut pas appeler le(s) constructeur(s) privé(s) de la classe. (le(s) constructeur(s) devrait(ent) être privé(s), si vous suivez correctement le modèle de la fabrique).

7voto

Johan Lundberg Points 5835

Avec make shared, vous ne pouvez pas spécifier comment allocation et désaffectation de l'objet retenu sera effectué.

Lorsque cela est souhaité, utilisez std::allocate_shared<T> à la place :

std::vector<std::shared_ptr<std::string>> avec; 
std::allocator<std::string> aAllocator;
avec.push_back(std::allocate_shared<std::string>(aAllocator,"hi there!"));

Notez que le vecteur n'a pas besoin d'être informé sur l'allocateur !

Pour créer un allocateur personnalisé, regardez ici. http://stackoverflow.com/a/542339/1149664

Prograide.com

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.

Powered by:

X