建議使用 Visual Studio 2017

如何:建立和使用 unique_ptr 執行個體

 

如需 Visual Studio 2017 的最新文件請參閱 Visual Studio 2017 文件

unique_ptr 不共用其指標。 這無法複製到另一個 unique_ptr、不能以傳值方式傳遞給函式,也無法用於任何需要製作複本的標準範本庫 (STL) 演算法。 只能移動 unique_ptr。 這表示記憶體資源的擁有權轉移到另一個 unique_ptr,原始 unique_ptr 不再擁有它。 因為多重擁有權會增加程序邏輯的複雜度,建議您將物件限制為一個擁有者。 因此,當您需要一般 C++ 物件的智慧型指標時,請使用 unique_ptr,並在建構 unique_ptr 時,使用 make_unique 協助程式函式。

下圖說明兩個 unique_ptr 執行個體之間的擁有權轉移。

移動 unique_ptr 的擁有權

unique_ptr 是定義在 STL 的 <memory> 標頭中。 這完全像原始指標一樣有效率,而且可以用於 STL 容器。 將 unique_ptr 執行個體加入至 STL 容器是有效率的作法,因為 unique_ptr 的移動建構函式不需要複製作業。

下列範例示範如何建立 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");
}

這些範例示範 unique_ptr 的這種基本特性:可加以移動,但無法複製。「移動」會將擁有權轉移到新的 unique_ptr 並重設舊的 unique_ptr

下列範例示範如何建立 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; 
    }    
}

在範圍 for 迴圈中,請注意 unique_ptr 是以傳址方式傳遞。 如果您嘗試在這裡以傳值方式傳遞,編譯器就會擲回錯誤,因為 unique_ptr 複製建構函式已刪除。

下列範例示範如何初始化本身為類別成員的 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();
    }
};

您可以使用 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;
	}

如需更多範例,請參閱 make_unique

智慧型指標
make_unique

顯示: