Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at How to: Create and Use unique_ptr Instances. 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.
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.
Example
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
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
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
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.