Cara: Membuat dan menggunakan instans unique_ptr

unique_ptr tidak berbagi penunjuknya. Ini tidak dapat disalin ke yang lain unique_ptr, diteruskan oleh nilai ke fungsi, atau digunakan dalam algoritma Pustaka Standar C++ yang memerlukan salinan untuk dibuat. A unique_ptr hanya dapat dipindahkan. Ini berarti bahwa kepemilikan sumber daya memori ditransfer ke sumber daya lain unique_ptr dan aslinya unique_ptr tidak lagi memilikinya. Kami menyarankan agar Anda membatasi objek ke satu pemilik, karena beberapa kepemilikan menambahkan kompleksitas ke logika program. Oleh karena itu, ketika Anda memerlukan penunjuk cerdas untuk objek C++ biasa, gunakan unique_ptr, dan saat Anda membuat unique_ptr, gunakan fungsi pembantu make_unique .

Diagram berikut mengilustrasikan transfer kepemilikan antara dua unique_ptr instans.

Diagram that shows moving the ownership of a unique pointer.

unique_ptr didefinisikan di <memory> header di Pustaka Standar C++. Ini sama efisiennya dengan pointer mentah dan dapat digunakan dalam kontainer Pustaka Standar C++. Penambahan unique_ptr instans ke kontainer Pustaka Standar C++ efisien karena konstruktor pemindahan unique_ptr menghilangkan kebutuhan akan operasi penyalinan.

Contoh 1

Contoh berikut menunjukkan cara membuat unique_ptr instans dan meneruskannya di antara fungsi.

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

Contoh-contoh ini menunjukkan karakteristik dasar ini dari unique_ptr: dapat dipindahkan, tetapi tidak disalin. "Memindahkan" mentransfer kepemilikan ke yang baru unique_ptr dan mengatur ulang yang lama unique_ptr.

Contoh 2

Contoh berikut menunjukkan cara membuat unique_ptr instans dan menggunakannya di vektor.

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

Dalam rentang untuk perulangan, perhatikan bahwa unique_ptr diteruskan oleh referensi. Jika Anda mencoba melewati nilai di sini, pengkompilasi akan melemparkan kesalahan karena unique_ptr konstruktor salin dihapus.

Contoh 3

Contoh berikut menunjukkan cara menginisialisasi unique_ptr yang merupakan anggota kelas.


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

Contoh 4

Anda dapat menggunakan make_unique untuk membuat unique_ptr ke array, tetapi Anda tidak dapat menggunakan make_unique untuk menginisialisasi elemen array.

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

Untuk contoh selengkapnya, lihat make_unique.

Baca juga

Penunjuk Cerdas (Modern C++)
make_unique