Condividi tramite


Procedura: Creare e utilizzare le istanze di unique_ptr

A unique_ptr non condivide il puntatore.Non possono essere copiata in un altro unique_ptr, passato per valore a una funzione (a meno che non si tratta di un rvalue modificabili), oppure utilizzato in qualsiasi algoritmo libreria STL (Standard Template) che richiede la copia deve essere effettuato.A unique_ptr può solo essere spostata.Ciò significa che è trasferita la proprietà della risorsa di memoria per un nuovo unique_ptr e l'originale unique_ptr non è più proprietario.Si consiglia di limitare un oggetto a un proprietario, in quanto più proprietà aumenta la complessità della logica di programma.Di conseguenza, quando è necessario un puntatore intelligente per un normale oggetto C++, utilizzare unique_ptr.

Nel diagramma riportato di seguito viene illustrato il trasferimento della proprietà tra due unique_ptr le istanze.

Trasferimento della proprietà di unique_ptr

unique_ptrè definito nel <memory> intestazione STL.È esattamente è efficiente come un puntatore raw e può essere utilizzata in contenitori STL.L'aggiunta di unique_ptr istanze per contenitori STL è efficiente poiché il costruttore di spostamento del unique_ptr Elimina la necessità di un'operazione di copia.

Esempio

Nell'esempio riportato di seguito viene illustrato come creare unique_ptr le istanze e passarle tra le funzioni.

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");
}

Questi esempi dimostrano questa caratteristica di base di unique_ptr: possono essere spostato ma non copiato. Spostamento di"trasferisce il proprietario di un nuovo unique_ptr e reimposta il vecchio unique_ptr.

Nell'esempio riportato di seguito viene illustrato come creare unique_ptr le istanze e utilizzarli in un vettore.

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; 
    });        
}

Nel for_each loop, si noti che il unique_ptr viene passato per riferimento nell'espressione lambda.Se si tenta di passare in base al valore in questo campo, il compilatore genererà un errore perché il unique_ptr costruttore di copia è disattivato.

Nell'esempio riportato di seguito viene illustrato come inizializzare un unique_ptr è un membro di 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();
    }
};

Vedere anche

Concetti

Puntatori intelligenti (C++ moderno)