Sdílet prostřednictvím


Postupy: Vytváření a používání instancí ukazatelů unique_ptr

unique_ptr nesdílí vlastní ukazatel.Nelze ho zkopírovat do jiného unique_ptr, předat podle hodnoty do funkce ani použít v libovolném algoritmu STL (Standard Template Library), který vyžaduje vytvoření kopií.unique_ptr lze pouze přesunout.To znamená, že vlastnictví prostředku paměti je převedeno do jiného unique_ptr a původní unique_ptr není nadále jeho vlastníkem.Doporučujeme omezit objekt na jednoho vlastníka, protože více vlastnictví zkomplikuje programovou logiku.Když budete potřebovat inteligentní ukazatel pro prostý objekt jazyka C++, použijte tedy unique_ptr a při sestavování unique_ptr použijte funkci pomocné rutiny make_unique.

Následující diagram znázorňuje převod vlastnictví mezi dvěma instancemi unique_ptr.

Přesunutí vlastnictví unique_ptr

unique_ptr je definován v záhlaví <memory> v STL.Je naprosto stejně efektivní jako nezpracovaný ukazatel a lze jej použít v kontejnerech STL.Přidání instancí unique_ptr do kontejnerů STL je účinné, protože konstruktor přesunu unique_ptr eliminuje potřebu operace kopírování.

Příklad

Následující příklad ukazuje, jak vytvořit instance unique_ptr a předat je mezi funkcemi.

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

Tyto příklady ukazují tuto základní charakteristiku unique_ptr: lze je přesunout, ale ne zkopírovat. „Přesun“ převede vlastnictví na novou unique_ptr a obnoví původní unique_ptr.

Následující příklad ukazuje, jak vytvořit instance unique_ptr a používat je ve vektoru.

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

V rozsahu smyčky si všimněte, že unique_ptr je předáno odkazem.Pokud se pokusíte předat hodnotu v tomto poli, vyvolá kompilátor chybu, protože kopie konstruktoru unique_ptr je odstraněna.

Následující příklad ukazuje způsob inicializace unique_ptr, který je členem třídy.

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

make_unique můžete použít k vytvoření unique_ptr pro pole, ale nemůžete použít make_unique k inicializaci prvků pole.

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

Další příklady naleznete v tématu make_unique.

Viz také

Referenční dokumentace

make_unique

Koncepty

Chytré ukazatele (moderní verze jazyka C++)