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