1. 程式人生 > 其它 >如何建立並使用unique_ptr 例項(譯文)

如何建立並使用unique_ptr 例項(譯文)

技術標籤:Visual C++c++

譯自https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-unique-ptr-instances?view=msvc-160

目錄

總述

示例1

示例2

示例3

示例4


總述

Aunique_ptrdoes not share its pointer. It cannot be copied to anotherunique_ptr, passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. Aunique_ptr

can only be moved. This means that the ownership of the memory resource is transferred to anotherunique_ptrand the originalunique_ptrno longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic. Therefore, when you need a smart pointer for a plain C++ object, useunique_ptr
, and when you construct aunique_ptr, use themake_uniquehelper function.

The following diagram illustrates the transfer of ownership between twounique_ptrinstances.

unique_ptris defined in the<memory>header in the C++ Standard Library. It is exactly as efficient as a raw pointer and can be used in C++ Standard Library containers. The addition ofunique_ptr

instances to C++ Standard Library containers is efficient because the move constructor of theunique_ptreliminates the need for a copy operation.

一個unique_ptr例項不與其他例項共享指標。不能把一個unique_ptr拷貝到另一個unique_ptr例項上,也不能將其值傳遞給函式,也不能在任何產生其拷貝的c++標準庫演算法中使用unique_ptr。一個unique_ptr只能被移動。這意味著其指向的(或者說是擁有的)記憶體資源可以從一個unique_ptr轉到另一個unique_ptr名下。我們建議一個物件只有一個擁有者,因為多個擁有者將增加程式邏輯的複雜性。所以,當你需要給一個指向純c++物件的智慧指標時,請使用unique_ptr,並且當你構建一個unique_ptr的例項時,使用make_unique函式。

下面的圖展示了(記憶體資源的)擁有權是如何在兩個unique_ptr例項之間傳遞的。

unique_ptr定義在<memory>標頭檔案中。其效率跟原始的指標一樣高,並且可以用在標準庫的容器中。在標準庫容器中新增unique_ptr的操作是高效的,因為move建構函式並不引起拷貝操作(只是指標的轉移)。

示例1

The following example shows how to createunique_ptrinstances and pass them between functions.

下面的例子展示瞭如何建立unique_ptr例項,並且在函式之間傳遞它們。

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

示例2

下面的示例展示如何建立並在vector中使用unique_ptr

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

In the range for loop, notice that theunique_ptris passed by reference. If you try to pass by value here, the compiler will throw an error because theunique_ptrcopy constructor is deleted.

在for迴圈中,注意unique_ptr通過引用傳遞。如果你沒有采用引用傳遞,而是值傳遞,則編譯器將報錯,原因是unique_ptr不能拷貝。

示例3

The following example shows how to initialize aunique_ptrthat is a class member.

下面的示例介紹的是當unique_ptr是一個成員變數的時候,如何將其初始化。

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

示例4

You can usemake_uniqueto create aunique_ptrto an array, but you cannot usemake_uniqueto initialize the array elements.

你可以利用make_unique在陣列中建立unique_ptr,但是你不能使用make_unique來對陣列元素初始化。

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