std::unique_ptr<T,Deleter>:: unique_ptr
|
miembros de la plantilla principal, unique_ptr<T>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
explicit
unique_ptr
(
pointer p
)
noexcept
;
|
(2) | (constexpr desde C++23) |
|
unique_ptr
(
pointer p,
/* ver más abajo */
d1
)
noexcept
;
|
(3) | (constexpr desde C++23) |
|
unique_ptr
(
pointer p,
/* ver más abajo */
d2
)
noexcept
;
|
(4) | (constexpr desde C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr desde C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr desde C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
|
template
<
class
U
>
unique_ptr ( std:: auto_ptr < U > && u ) noexcept ; |
(8) | (eliminado en C++17) |
|
miembros de la especialización para arrays, unique_ptr<T[]>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
template
<
class
U
>
explicit unique_ptr ( U p ) noexcept ; |
(2) | (constexpr desde C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* ver más abajo */ d1 ) noexcept ; |
(3) | (constexpr desde C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* ver más abajo */ d2 ) noexcept ; |
(4) | (constexpr desde C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr desde C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr desde C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
std::unique_ptr
que no posee nada. Inicializa por valor el puntero almacenado y el eliminador almacenado. Requiere que
Deleter
sea
DefaultConstructible
y que la construcción no lance una excepción. Estas sobrecargas participan en la resolución de sobrecarga solo si
std::
is_default_constructible
<
Deleter
>
::
value
es
true
y
Deleter
no es un tipo puntero.
std::unique_ptr
que posee
p
, inicializando el puntero almacenado con
p
e inicializando por valor el eliminador almacenado. Requiere que
Deleter
sea
DefaultConstructible
y que la construcción no lance una excepción. Esta sobrecarga participa en la resolución de sobrecarga solo si
std::
is_default_constructible
<
Deleter
>
::
value
es
true
y
Deleter
no es un tipo puntero.
|
Este constructor no es seleccionado por deducción de argumentos de plantilla de clase . |
(desde C++17) |
std::unique_ptr
que posee
p
, inicializando el puntero almacenado con
p
e inicializando un deleter
D
como se indica a continuación (depende de si
D
es un tipo de referencia).
D
es un tipo no-referencia
A
, entonces las firmas son:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) |
(requiere que
Deleter
sea nothrow-
CopyConstructible
)
|
|
unique_ptr
(
pointer p, A
&&
d
)
noexcept
;
|
(2) |
(requiere que
Deleter
sea nothrow-
MoveConstructible
)
|
D
es un tipo de referencia lvalue
A
&
, entonces las firmas son:
|
unique_ptr
(
pointer p, A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p, A
&&
d
)
=
delete
;
|
(2) | |
D
es un tipo de referencia lvalue
const
A
&
, entonces las firmas son:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p,
const
A
&&
d
)
=
delete
;
|
(2) | |
|
Estos dos constructores no son seleccionados por class template argument deduction . |
(since C++17) |
-
Ues el mismo tipo quepointer, o -
Ues std::nullptr_t , o -
pointeres el mismo tipo queelement_type*yUes algún tipo de punteroV*tal queV(*)[]es implícitamente convertible aelement_type(*)[].
unique_ptr
transfiriendo la propiedad desde
u
a
*
this
y almacena el puntero nulo en
u
. Este constructor solo participa en la resolución de sobrecarga si
std::
is_move_constructible
<
Deleter
>
::
value
es
true
. Si
Deleter
no es un tipo referencia, requiere que sea nothrow-
MoveConstructible
(si
Deleter
es una referencia,
get_deleter()
y
u.get_deleter()
después de la construcción por movimiento referencian el mismo valor).
unique_ptr
transfiriendo la propiedad desde
u
hacia
*
this
, donde
u
está construido con un eliminador especificado (
E
). Depende de si
E
es un tipo de referencia, como sigue:
E
es un tipo de referencia, este deleter se construye por copia desde
u
's deleter (requiere que esta construcción no lance excepciones),
E
es un tipo no-referencia, este deleter se construye por movimiento desde
u
's deleter (requiere que esta construcción no lance excepciones).
pointer
,
Deleter
sea un tipo de referencia y
E
sea del mismo tipo que
Deleter
, o que
Deleter
no sea un tipo de referencia y
E
sea convertible implícitamente a
Deleter
.
-
Ues un tipo de arreglo, -
pointeres del mismo tipo queelement_type*, - unique_ptr < U,E > :: pointer es del mismo tipo que unique_ptr < U,E > :: element_type * ,
-
unique_ptr
<
U,E
>
::
element_type
(
*
)
[
]
es convertible a
element_type(*)[], -
ya sea que
Deletersea un tipo de referencia yEsea del mismo tipo queDeleter, o queDeleterno sea un tipo de referencia yEsea implícitamente convertible aDeleter.
unique_ptr
donde el puntero almacenado se inicializa con
u.release()
y el deleter almacenado se inicializa por valor. Este constructor solo participa en la resolución de sobrecarga si
U*
es convertible implícitamente a
T*
y
Deleter
es del mismo tipo que
std::
default_delete
<
T
>
.
Contenidos |
Parámetros
| p | - | un puntero a un objeto para gestionar |
| d1, d2 | - | un deleter para usar para destruir el objeto |
| u | - | otro smart pointer del cual adquirir la propiedad |
Notas
|
En lugar de usar la sobrecarga (2) junto con new, a menudo es mejor idea usar std::make_unique<T> . |
(since C++14) |
std:: unique_ptr < Derived > es implícitamente convertible a std:: unique_ptr < Base > mediante la sobrecarga (6) (ya que tanto el puntero gestionado como std::default_delete son implícitamente convertibles).
Debido a que el constructor por defecto es constexpr , los unique_ptrs estáticos se inicializan como parte de la inicialización no-local estática , antes de que comience cualquier inicialización no-local dinámica. Esto hace seguro usar un unique_ptr en el constructor de cualquier objeto estático.
|
No existe deducción de argumentos de plantilla de clase a partir de tipos puntero porque es imposible distinguir entre un puntero obtenido de las formas con array y sin array de new . |
(desde C++17) |
Ejemplo
#include <iostream> #include <memory> struct Foo // objeto a gestionar { Foo() { std::cout << "Foo ctor\n"; } Foo(const Foo&) { std::cout << "Foo copy ctor\n"; } Foo(Foo&&) { std::cout << "Foo move ctor\n"; } ~Foo() { std::cout << "~Foo dtor\n"; } }; struct D // deleter { D() {}; D(const D&) { std::cout << "Constructor de copia D\n"; } D(D&) { std::cout << "D constructor de copia no constante\n"; } D(D&&) { std::cout << "D move ctor \n"; } void operator()(Foo* p) const { std::cout << "D está eliminando un Foo\n"; delete p; }; }; int main() { std::cout << "Ejemplo de constructor(1)...\n"; std::unique_ptr<Foo> up1; // up1 está vacío std::unique_ptr<Foo> up1b(nullptr); // up1b está vacío std::cout << "Ejemplo constructor(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2 ahora posee un Foo } // Foo eliminado std::cout << "Ejemplo constructor(3)...\n"; D d; { // el tipo deleter no es una referencia std::unique_ptr<Foo, D> up3(new Foo, d); // deleter copiado } { // el tipo deleter es una referencia std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b contiene una referencia a d } std::cout << "Ejemplo constructor(4)...\n"; { // deleter no es una referencia std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } std::cout << "Ejemplo constructor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::mover(up5a)); // transferencia de propiedad } std::cout << "Ejemplo constructor(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D se copia std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D se ha movido std::unique_ptr<Foo, D&> up6c(new Foo, d); // D es una referencia std::unique_ptr<Foo, D> up6d(std::mover(up6c)); // D se copia } #if (__cplusplus < 201703L) std::cout << "Ejemplo constructor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::mover(up7a)); // transferencia de propiedad } #endif std::cout << "Constructor de array de ejemplo...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // tres objetos Foo eliminados }
Salida:
Ejemplo constructor(1)... Ejemplo constructor(2)... Foo ctor ~Foo dtor Ejemplo constructor(3)... Foo ctor D copy ctor D is deleting a Foo ~Foo dtor Foo ctor D is deleting a Foo ~Foo dtor Ejemplo constructor(4)... Foo ctor D move ctor D is deleting a Foo ~Foo dtor Ejemplo constructor(5)... Foo ctor ~Foo dtor Ejemplo constructor(6)... Foo ctor D copy ctor D move ctor Foo ctor D non-const copy ctor D is deleting a Foo ~Foo dtor D is deleting a Foo ~Foo dtor Ejemplo constructor(7)... Foo ctor ~Foo dtor Ejemplo array constructor... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2118 | C++11 |
Los constructores de
unique_ptr<T[]>
rechazaban conversiones de calificación.
|
Aceptar. |
| LWG 2520 | C++11 |
unique_ptr<T[]>
se hizo accidentalmente no construible desde
nullptr_t
.
|
Hacerlo construible. |
| LWG 2801 | C++11 | El constructor por defecto no estaba restringido. | Restringido. |
| LWG 2899 | C++11 | El constructor de movimiento no estaba restringido. | Restringido. |
| LWG 2905 | C++11 | La restricción en el constructor desde un puntero y un deleter era incorrecta. | Corregido. |
| LWG 2944 | C++11 | Algunas precondiciones fueron eliminadas accidentalmente por LWG 2905 | Restauradas. |