Udostępnij za pośrednictwem


Porady: tworzenie wystąpień unique_ptr i korzystanie z nich

Obiekt unique_ptr nie udostępnia swojego wskaźnika.Nie można go skopiować do innego obiektu unique_ptr, przekazać przez wartość do funkcji ani wykorzystywać w ramach dowolnego algorytmu biblioteki standardowych szablonów (STL), który wymaga wykonania kopii.Obiekty unique_ptr mogą być tylko przenoszone.Oznacza to, że własność zasobu pamięci jest przenoszona na inny unique_ptr, a oryginalny wskaźnik unique_ptr nie jest już jego właścicielem.Zalecamy, aby ograniczyć obiekt do jednego właściciela, ponieważ wiele własności zwiększa złożoność logiki programu.W związku z tym, jeśli potrzebujesz inteligentnego wskaźnika dla zwykłego obiektu języka C++, użyj unique_ptr, a podczas konstruowania wskaźnika unique_ptr użyj funkcji pomocnika make_unique.

Poniższy diagram ilustruje przeniesienie prawa własności między dwoma wystąpieniami unique_ptr.

Przeniesienie własności unique_ptr

unique_ptr jest zdefiniowany w nagłówku <memory> w STL.Jest tak samo skuteczny jak wskaźnik surowy i można go używać w kontenerach biblioteki STL.Dodanie wystąpień unique_ptr do kontenerów STL jest efektywne, ponieważ konstruktor przenoszący unique_ptr eliminuje potrzebę operacji kopiowania.

Przykład

Poniższy przykład ukazuje, jak tworzyć wystąpienia unique_ptr i przekazywać je między funkcjami.

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

Przykłady te pokazują podstawową cechę unique_ptr: można je przenosić, ale nie kopiować. „Przejście” powoduje przeniesienie własności na nowe unique_ptr i usuwa stare unique_ptr.

Poniższy przykład ukazuje, jak tworzyć wystąpienia unique_ptr i korzystać z nich w wektorze.

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

W zakresie dla pętli, zwróć uwagę, że unique_ptr jest przekazywany przez odwołanie.Jeśli próbujesz przekazać wartość do tego pola, kompilator będzie sygnalizować błąd, ponieważ konstruktor kopiujący unique_ptr jest usunięty.

Poniższy przykład ukazuje, jak inicjować unique_ptr, który jest elementem członkowskim klasy.

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

Można użyć funkcji make_unique, aby utworzyć wskaźnik unique_ptr do tablicy, ale nie można użyć funkcji make_unique do zainicjowania elementów tablicy.

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

Aby uzyskać więcej przykładów, zobacz make_unique.

Zobacz też

Informacje

make_unique

Koncepcje

Wskaźniki inteligentne (Modern C++)