Partager via


Comment : créer et utiliser des instances unique_ptr

Un unique_ptr ne partage pas son pointeur. Il ne peut pas être copié vers un autre unique_ptr, passé par valeur à une fonction, ni utilisé dans un algorithme STL (Standard Template Library) qui nécessite d'effectuer des copies. Un unique_ptr peut uniquement être déplacé. Cela signifie que la propriété de la ressource mémoire est transférée à un autre unique_ptr et que le unique_ptr d'origine ne le possède plus. Il est recommandé de restreindre un objet à un seul propriétaire, car la multiplicité des propriétaires ajoute de la complexité à la logique du programme. Par conséquent, lorsque vous avez besoin d'un pointeur intelligent pour un objet ordinaire C++, utilisez unique_ptret, lorsque vous construisez un unique_ptr, utilisez la fonction d'assistance make_unique.

Le diagramme suivant illustre le transfert de propriété entre deux instances unique_ptr.

Déplacement de la propriété d'un unique_ptr

unique_ptr est défini dans l'en-tête <memory> dans la bibliothèque STL. Il est efficace comme pointeur brut et peut être utilisé dans des conteneurs STL. L'ajout d'instances unique_ptr à des conteneurs STL est efficace, car le constructeur de déplacement de unique_ptr ne nécessite pas d'opération de copie.

Exemple

L'exemple suivant montre comment créer des instances unique_ptr et les passer entre des fonctions.

unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
    // Implicit move operation into the variable that stores the result. 
    return make_unique<Song>(artist, title);
}

void MakeSongs()
{
    // Create a new unique_ptr with a new object.
    auto song = make_unique<Song>(L"Mr. Children", L"Namonaki Uta");

    // Use the unique_ptr.
    vector<wstring> titles = { song->title };

    // Move raw pointer from one unique_ptr to another.
    unique_ptr<Song> song2 = std::move(song);

    // Obtain unique_ptr from function that returns by value.
    auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}

Ces exemples illustrent cette caractéristique de base de unique_ptr : il peut être déplacé, mais pas copié. Le « déplacement » transfère la propriété à un nouvel unique_ptr et réinitialise l'ancien unique_ptr.

L'exemple suivant montre comment créer des instances unique_ptr et les utiliser dans un vecteur.

void SongVector()
{
    vector<unique_ptr<Song>> songs;

    // Create a few new unique_ptr<Song> instances 
    // and add them to vector using implicit move semantics.
    songs.push_back(make_unique<Song>(L"B'z", L"Juice"));
    songs.push_back(make_unique<Song>(L"Namie Amuro", L"Funky Town"));
    songs.push_back(make_unique<Song>(L"Kome Kome Club", L"Kimi ga Iru Dake de"));
    songs.push_back(make_unique<Song>(L"Ayumi Hamasaki", L"Poker Face"));

    // Pass by const reference when possible to avoid copying. 
    for (const auto& song : songs)
    {
        wcout << L"Artist: " << song->artist << L"   Title: " << song->title << endl; 
    }    
}

Dans la boucle for de plage, remarquez que unique_ptr est passé par référence. Si vous essayez d'effectuer un passage par valeur ici, le compilateur génère une erreur, car le constructeur de copie unique_ptr est supprimé.

L'exemple suivant montre comment initialiser un unique_ptr qui est un membre de classe.

class MyClass
{
private:
    // MyClass owns the unique_ptr.
    unique_ptr<ClassFactory> factory;
public:

    // Initialize by using make_unique with ClassFactory default constructor.
    MyClass() : factory ( make_unique<ClassFactory>())
    {
    }

    void MakeClass()
    {
        factory->DoSomething();
    }
};

Vous pouvez utiliser make_unique pour créer un unique_ptr dans un tableau, mais vous ne pouvez pas utiliser make_unique pour initialiser les éléments du tableau.

  // Create a unique_ptr to an array of 5 integers.
    auto p = make_unique<int[]>(5);

    // Initialize the array. 
    for (int i = 0; i < 5; ++i)
    {
        p[i] = i;
        wcout << p[i] << endl;
    }

Pour plus d'exemples, consultez make_unique.

Voir aussi

Référence

make_unique

Concepts

Pointeurs intelligents (Modern C++)