std::unique_ptr es un puntero inteligente introducido en C++11. Gestiona automáticamente los recursos asignados dinámicamente en el montón. Los punteros inteligentes son solo envoltorios de punteros antiguos y habituales que le ayudan a prevenir errores generalizados. Es decir, olvidarse de eliminar un puntero y provocar una pérdida de memoria o eliminar accidentalmente un puntero dos veces o de forma incorrecta. Se pueden utilizar de forma similar a los punteros estándar. Automatizan algunos de los procesos manuales que causan errores comunes.
Requisitos previos: Puntero en C++ , Punteros inteligentes en C++.
Sintaxis
unique_ptr< A>ptr1 (nueva A)>
Aquí,
- único_ptr : Especifica el tipo de std::unique_ptr. En este caso, un objeto de tipo A.
- nueva A : Un objeto de tipo A se asigna dinámicamente en el montón utilizando el nuevo operador.
- ptr1 : Este es el nombre de la variable std::unique_ptr.
¿Qué sucede cuando se usa Unique_ptr?
Cuando escribimos Unique_ptr ptr1 (nuevo A), se asigna memoria en el montón para una instancia del tipo de datos A. ptr1 se inicializa y apunta al objeto A recién creado. Aquí, ptr1 es el único propietario del objeto A recién creado y gestiona la vida útil de este objeto. Esto significa que cuando ptr1 se reinicia o sale del alcance, la memoria se desasigna automáticamente y el objeto de A se destruye.
¿Cuándo utilizar Unique_ptr?
Cuando se requiere la propiedad del recurso. Cuando queremos la propiedad única o exclusiva de un recurso, debemos buscar sugerencias únicas. Sólo un puntero único puede apuntar a un recurso. Por tanto, un puntero único no se puede copiar a otro. Además, facilita la limpieza automática cuando los objetos asignados dinámicamente quedan fuera de alcance y ayuda a prevenir pérdidas de memoria.
Nota: Necesitamos usar el archivo de encabezado para usar estos punteros inteligentes.
Ejemplos de Unique_ptr
Ejemplo 1:
Creemos una estructura A y tendrá un método llamado printA para mostrar algo de texto. Luego, en la sección principal, creemos un puntero único que apuntará a la estructura A. Entonces, en este punto, tenemos una instancia de la estructura A y p1 contiene el puntero a esa.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> > int> main()> {> >unique_ptr p1(> new> A);> >p1->imprimirA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> >return> 0;> }> |
que significa esto xd
>
>Producción
A struct.... 0x18dac20>
Ejemplo 2
Ahora creemos otro puntero p2 e intentaremos copiar el puntero p1 usando el operador de asignación (=).
C++
lista de programas de Python
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->imprimirA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// will give compile time error> >unique_ptr> p2 = p1;> >p2->imprimirA();> >return> 0;> }> |
>
>
Producción
main.cpp: In function ‘int main()’: main.cpp:18:24: error: use of deleted function ‘std::unique_ptr::unique_ptr(const std::unique_ptr&) [with _Tp = A; _Dp = std::default_delete]’ 18 | unique_ptr p2 = p1; | ^~ In file included from /usr/include/c++/11/memory:76, from main.cpp:3: /usr/include/c++/11/bits/unique_ptr.h:468:7: note: declared here 468 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~>
El código anterior dará un error en tiempo de compilación ya que no podemos asignar el puntero p2 a p1 en el caso de punteros únicos. Tenemos que utilizar la semántica de movimiento para tal fin, como se muestra a continuación.
25 de 100
Ejemplo 3
Gestionar objetos de tipo A mediante semántica de movimiento.
C++
// C++ Program to implement unique_ptr> #include> #include> using> namespace> std;> > struct> A {> >void> printA() { cout <<>'A struct....'> << endl; }> };> int> main()> {> >unique_ptr p1(> new> A);> >p1->imprimirA();> > >// displays address of the containing pointer> >cout << p1.get() << endl;> > >// now address stored in p1 shpould get copied to p2> >unique_ptr> p2 = move(p1);> > >p2->imprimirA();> >cout << p1.get() << endl;> >cout << p2.get() << endl;> >return> 0;> }> |
>
>Producción
A struct.... 0x2018c20 A struct.... 0 0x2018c20>
Tenga en cuenta que una vez que la dirección en el puntero p1 se copia al puntero p2, la dirección del puntero p1 se vuelve NULL (0) y la dirección almacenada por p2 ahora es la misma que la dirección almacenada por p1, lo que muestra que la dirección en p1 se ha transferido al puntero. p2 usando la semántica de movimiento.