This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft Edge More info about Internet Explorer and Microsoft Edge

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 C++ Standard Library 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.

unique_ptr is 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 of unique_ptr instances to C++ Standard Library containers is efficient because the move constructor of the unique_ptr eliminates the need for a copy operation.

Example 1

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.

Example 2

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.

Example 3

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

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

Example 4

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.

See also

Smart Pointers (Modern C++)
make_unique