make_shared (<memory>)

Crée et retourne un pointeur shared_ptr qui pointe vers les objets alloués qui sont construits de zéro ou de plusieurs arguments à l'aide de l'allocateur par défaut. Alloue et construit un objet du type spécifié et un pointeur shared_ptr pour gérer une propriété partagée de l'objet et retourne le pointeur shared_ptr.

template<class Type, class... Types>     shared_ptr<Type> make_shared(         Types&&... _Args     );

Paramètres

Paramètre

Description

_Args

Zéro ou plusieurs arguments de constructeur. Selon les arguments fournis, la fonction déduit la surcharge de constructeur à appeler.

Valeur de propriété/valeur de retour

Retourne un pointeur shared_ptr qui pointe sur l'objet alloué et construit.

Notes

Utilisez make_shared comme un moyen simple et plus efficace pour créer un objet et un pointeur shared_ptr pour gérer l'accès partagé à l'objet en même temps. Sémantiquement, les deux instructions suivantes sont équivalentes :

   auto sp = std::shared_ptr<Example>(new Example(argument));
   auto msp = std::make_shared<Example>(argument);

Toutefois, la première instruction crée deux allocations, et si l'allocation du pointeur shared_ptr échoue alors que l'allocation de l'objet Example a réussi, l'objet sans nom Example est victime d'une fuite. L'instruction qui utilise make_shared est plus simple car un seul appel de fonction est impliqué. Elle est plus efficace car la bibliothèque peut effectuer une allocation unique pour l'objet et le pointeur intelligent. Elle est plus rapide, elle entraîne moins de fragmentation de mémoire et aucune exception ne peut avoir lieu sur une allocation sans se produire également sur l'autre. Les performances sont améliorées grâce à une meilleure localité du code qui fait référence à l'objet et qui met à jour les décomptes de références dans le pointeur intelligent.

Envisagez d'utiliser make_unique si vous n'avez pas besoin d'un accès partagé à l'objet. Utilisez allocate_shared si vous devez spécifier un allocateur personnalisé pour l'objet. Vous ne pouvez pas utiliser make_shared si votre objet nécessite une suppression personnalisée, car il n'existe aucun moyen de transmettre la suppression en tant qu'argument.

L'exemple suivant illustre la création de pointeurs partagés vers un type en appelant des surcharges de constructeur spécifiques.

Exemple

// stl_make_shared.cpp
// Compile by using: cl /W4 /EHsc stl_make_shared.cpp
#include <iostream>
#include <string>
#include <memory>
#include <vector>

class Song {
public:
   std::wstring title_;
   std::wstring artist_;

   Song(std::wstring title, std::wstring artist) : title_(title), artist_(artist) {}
   Song(std::wstring title) : title_(title), artist_(L"Unknown") {}
};

void CreateSharedPointers() {
   // Okay, but less efficient to have separate allocations for
   // Song object and shared_ptr control block.  
   auto song = new Song(L"Ode to Joy", L"Beethoven");
   std::shared_ptr<Song> sp0(song);

   // Use make_shared function when possible. Memory for control block
   // and Song object are allocated in the same call:  
   auto sp1 = std::make_shared<Song>(L"Yesterday", L"The Beatles");
   auto sp2 = std::make_shared<Song>(L"Blackbird", L"The Beatles");
   
   // make_shared infers which constructor to use based on the arguments.
   auto sp3 = std::make_shared<Song>(L"Greensleeves");
   
   // The playlist vector makes copies of the shared_ptr pointers.
   std::vector<std::shared_ptr<Song>> playlist;
   playlist.push_back(sp0);
   playlist.push_back(sp1);
   playlist.push_back(sp2);
   playlist.push_back(sp3);
   playlist.push_back(sp1);
   playlist.push_back(sp2);
   for (auto&& sp : playlist) {
      std::wcout << L"Playing " << sp->title_ << 
         L" by " << sp->artist_ << L", use count: " << 
         sp.use_count() << std::endl;
   }
}

int main() {
   CreateSharedPointers();
}

L'exemple génère cette sortie :

  

Configuration requise

En-tête : <memory>

Espace de noms : std

Voir aussi

Référence

<memory>

shared_ptr, classe