Windows apps
Collapse the table of content
Expand the table of content
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

How to: Create and Use unique_ptr Instances


For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr, passed by value to a function, or used in any Standard Template Library (STL) algorithm that requires copies to be made. A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no 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, use unique_ptr, and when you construct a unique_ptr, use the make_unique helper function.

The following diagram illustrates the transfer of ownership between two unique_ptr instances.

Moving the ownership of a unique_ptr

unique_ptr is defined in the <memory> header in the STL. It is exactly is efficient as a raw pointer and can be used in STL containers. The addition of unique_ptr instances to STL containers is efficient because the move constructor of the unique_ptr eliminates the need for a copy operation.

The following example shows how to create unique_ptr instances and pass them between functions.

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

These examples demonstrate this basic characteristic of unique_ptr: it can be moved, but not copied. "Moving" transfers ownership to a new unique_ptr and resets the old unique_ptr.

The following example shows how to create unique_ptr instances and use them in a vector.

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 the unique_ptr is passed by reference. If you try to pass by value here, the compiler will throw an error because the unique_ptr copy constructor is deleted.

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

class MyClass
    // MyClass owns the unique_ptr.
    unique_ptr<ClassFactory> factory;

    // Initialize by using make_unique with ClassFactory default constructor.
    MyClass() : factory ( make_unique<ClassFactory>())

    void MakeClass()

You can use make_unique to create a unique_ptr to an array, but you cannot use make_unique to initialize the array elements.

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

For more examples, see make_unique.

Smart Pointers

© 2017 Microsoft