Procedura: Creare e utilizzare le istanze di unique_ptr
A unique_ptr non condivide il puntatore.Non possono essere copiata in un altro unique_ptr, passato per valore a una funzione (a meno che non si tratta di un rvalue modificabili), oppure utilizzato in qualsiasi algoritmo libreria STL (Standard Template) che richiede la copia deve essere effettuato.A unique_ptr può solo essere spostata.Ciò significa che è trasferita la proprietà della risorsa di memoria per un nuovo unique_ptr e l'originale unique_ptr non è più proprietario.Si consiglia di limitare un oggetto a un proprietario, in quanto più proprietà aumenta la complessità della logica di programma.Di conseguenza, quando è necessario un puntatore intelligente per un normale oggetto C++, utilizzare unique_ptr.
Nel diagramma riportato di seguito viene illustrato il trasferimento della proprietà tra due unique_ptr le istanze.
unique_ptrè definito nel <memory> intestazione STL.È esattamente è efficiente come un puntatore raw e può essere utilizzata in contenitori STL.L'aggiunta di unique_ptr istanze per contenitori STL è efficiente poiché il costruttore di spostamento del unique_ptr Elimina la necessità di un'operazione di copia.
Esempio
Nell'esempio riportato di seguito viene illustrato come creare unique_ptr le istanze e passarle tra le funzioni.
unique_ptr<Song> SongFactory(std::wstring artist, std::wstring title)
{
// Implicit move operation into the variable that stores the result.
return unique_ptr<Song>(new Song(artist, title));
}
void MakeSongs()
{
// Create a new unique_ptr with a new object.
unique_ptr<Song> pSong = unique_ptr<Song>(new Song(L"Mr. Children", L"Namonaki Uta"));
// Use the unique_ptr
vector<wstring> titles;
titles.push_back(pSong->title);
// Move raw pointer from one unique_ptr to another.
unique_ptr<Song> pSong2 = std::move(pSong);
// Obtain unique_ptr from function that returns rvalue reference.
auto pSong3 = SongFactory(L"Michael Jackson", L"Beat It");
}
Questi esempi dimostrano questa caratteristica di base di unique_ptr: possono essere spostato ma non copiato. Spostamento di"trasferisce il proprietario di un nuovo unique_ptr e reimposta il vecchio unique_ptr.
Nell'esempio riportato di seguito viene illustrato come creare unique_ptr le istanze e utilizzarli in un vettore.
void SongVector()
{
vector<unique_ptr<Song>> v;
// Create a few new unique_ptr<Song> instances
// and add them to vector using implicit move semantics.
v.push_back(unique_ptr<Song>(new Song(L"B'z", L"Juice")));
v.push_back(unique_ptr<Song>(new Song(L"Namie Amuro", L"Funky Town")));
v.push_back(unique_ptr<Song>(new Song(L"Kome Kome Club", L"Kimi ga Iru Dake de")));
v.push_back(unique_ptr<Song>(new Song(L"Ayumi Hamasaki", L"Poker Face")));
// Pass by reference to lambda body.
for_each(v.begin(), v.end(), [] (const unique_ptr<Song>& p)
{
wcout << L"Artist: " << p->artist << L"Title: " << p->title << endl;
});
}
Nel for_each loop, si noti che il unique_ptr viene passato per riferimento nell'espressione lambda.Se si tenta di passare in base al valore in questo campo, il compilatore genererà un errore perché il unique_ptr costruttore di copia è disattivato.
Nell'esempio riportato di seguito viene illustrato come inizializzare un unique_ptr è un membro di classe.
class MyClass
{
private:
// MyClass owns the unique_ptr.
unique_ptr<ClassFactory> factory;
public:
// Initialize by invoking the unique_ptr move constructor.
MyClass() : factory ( unique_ptr<ClassFactory>(new ClassFactory()))
{
}
void MakeClass()
{
factory->DoSomething();
}
};