Partager via


Comment : Créer et utiliser des instances d'unique_ptr

A unique_ptr ne partage pas son pointeur.Il ne peut pas être copié vers un autre unique_ptr, passé par valeur à une fonction (sauf s'il est une valeur rvalue modifiable), ou utilisé dans n'importe quel algorithme de la bibliothèque STL (Standard Template Library) qui nécessite des clichés.A unique_ptr ne peut être déplacé.Cela signifie que le propriétaire de la ressource mémoire est transféré vers une nouvelle unique_ptr et l'original unique_ptr n'est plus le possède.Nous vous recommandons de vous limitez un objet à un seul propriétaire, car plusieurs possession complique la logique du programme.Par conséquent, lorsque vous avez besoin d'un pointeur intelligent pour un simple objet C++, utilisez unique_ptr.

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

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

unique_ptrest défini dans le <memory> en-tête dans la STL.Il est exactement est efficace comme un pointeur brut et peuvent être utilisés dans les conteneurs STL.L'addition de unique_ptr instances aux conteneurs STL est efficace car le constructeur de déplacement de la unique_ptr élimine la nécessité d'une opération de copie.

Exemple

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

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

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

    // Use the unique_ptr
    vector<wstring> titles;
    titles.push_back(pSong->title);

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

    // Obtain unique_ptr from function that returns rvalue reference.
    auto pSong3 = SongFactory(L"Michael Jackson", L"Beat It");
}

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

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

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

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

    // Pass by reference to lambda body. 
    for_each(v.begin(), v.end(), [] (const unique_ptr<Song>& p)
    {
        wcout << L"Artist: " << p->artist << L"Title: " << p->title << endl; 
    });        
}

Dans la for_each en boucle, notez que le unique_ptr est passé par référence dans l'expression lambda.Si vous essayez de passer par valeur ici, le compilateur génère une erreur car le unique_ptr le constructeur de copie est désactivé.

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 invoking the unique_ptr move constructor.
    MyClass() : factory ( unique_ptr<ClassFactory>(new ClassFactory()))
    {              

    }

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

Voir aussi

Concepts

Pointeurs intelligents (C++ moderne)