Procedimiento Creación y uso de instancias unique_ptr
Un unique_ptr no comparte el puntero. No se puede copiar en otro unique_ptr
, pasar por valor a una función ni utilizar en ningún algoritmo de la Biblioteca estándar de C++ que requiera hacer copias. Un unique_ptr
solo se puede mover. Esto significa que la propiedad del recurso de memoria se transfiere a otro unique_ptr
y el unique_ptr
original deja de poseerlo. Se recomienda limitar un objeto a un propietario, porque la propiedad múltiple agrega complejidad a la lógica del programa. Por consiguiente, si necesita un puntero inteligente para un objeto de C++ sin formato, utilice unique_ptr
, y cuando construya un unique_ptr
, utilice la función del asistente make_unique.
El diagrama siguiente muestra la transferencia de propiedad entre dos instancias de unique_ptr
.
unique_ptr
se define en el encabezado <memory>
de la Biblioteca estándar de C++. Es exactamente tan eficaz como un puntero sin procesar y se puede usar en contenedores de la Biblioteca estándar de C++. La adición de las instancias de unique_ptr
a los contenedores STL es eficaz porque el constructor de movimiento de unique_ptr
elimina la necesidad de una operación de copia.
Ejemplo 1
En el ejemplo siguiente se muestra cómo crear instancias de unique_ptr
y pasarlas entre funciones.
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");
}
Estos ejemplos muestran esta característica básica de unique_ptr
: se puede mover, pero no copiar. "Mover" transfiere la propiedad a un nuevo unique_ptr
y restablece el antiguo unique_ptr
.
Ejemplo 2
En el ejemplo siguiente se muestra cómo crear instancias del objeto unique_ptr
y usarlas en un 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;
}
}
En el intervalo del bucle, observe que unique_ptr
se pasa por referencia. Si intenta pasar el parámetro por valor aquí, el compilador producirá un error porque se elimina el constructor de copias unique_ptr
.
Ejemplo 3
En el siguiente ejemplo se muestra cómo se inicializa un unique_ptr
que es miembro de una clase.
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();
}
};
Ejemplo 4
Puede utilizar make_unique para crear unique_ptr
a una matriz, pero no puede utilizar make_unique
para inicializar los elementos de matriz.
// 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;
}
Para obtener más ejemplos, consulte make_unique.
Consulte también
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de