Partilhar via


Como: criar e usar instâncias de unique_ptr

A unique_ptr não compartilha seu ponteiro.Não pode ser copiado para outro unique_ptr, passados por valor para uma função (a menos que ele é um rvalue pode ser modificado), ou usados em qualquer algoritmo de biblioteca STL (Standard Template) requer cópias sejam feitas.A unique_ptr só pode ser movida.Isso significa que a propriedade do recurso de memória é transferida para um novo unique_ptr e original unique_ptr não possui.Recomendamos que você restrinja um objeto para um proprietário, porque vários propriedade adiciona complexidade lógica do programa.Portanto, quando você precisa de um ponteiro inteligente para um objeto C++ simples, use unique_ptr.

O diagrama a seguir ilustra a transferência de propriedade entre duas unique_ptr instâncias.

Mudança de propriedade de um unique_ptr

unique_ptré definido de <memory> cabeçalho da STL.É exatamente é eficiente como um ponteiro bruto e pode ser usado em contêineres STL.A adição de unique_ptr instâncias para contêineres STL é eficiente porque o construtor de movimentação do unique_ptr elimina a necessidade de uma operação de cópia.

Exemplo

O exemplo a seguir mostra como criar unique_ptr instâncias e passá-los entre as funções.

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

Esses exemplos demonstram essa característica básica do unique_ptr: ele pode ser movido, mas não copiado. "Mover"transfere a propriedade para um novo unique_ptr e redefine o antigo unique_ptr.

O exemplo a seguir mostra como criar unique_ptr instâncias e usá-los em um vetor.

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

No for_each loop, observe que o unique_ptr é passado por referência na expressão lambda.Se você tentar passar por valor aqui, o compilador emitirá um erro porque o unique_ptr construtor de cópia está desabilitada.

O exemplo a seguir mostra como inicializar um unique_ptr ou seja um membro da 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();
    }
};

Consulte também

Conceitos

Ponteiros inteligentes (guia de programação do C++ moderno)