std::unique_ptr<T,Deleter>:: unique_ptr
|
члены основного шаблона, unique_ptr<T>
|
||
|
constexpr
unique_ptr
(
)
noexcept
;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ; |
(1) | |
|
explicit
unique_ptr
(
pointer p
)
noexcept
;
|
(2) | (constexpr начиная с C++23) |
|
unique_ptr
(
pointer p,
/* см. ниже */
d1
)
noexcept
;
|
(3) | (constexpr начиная с C++23) |
|
unique_ptr
(
pointer p,
/* см. ниже */
d2
)
noexcept
;
|
(4) | (constexpr начиная с C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr начиная с C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr начиная с C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
|
template
<
class
U
>
unique_ptr ( std:: auto_ptr < U > && u ) noexcept ; |
(8) | (удалено в C++17) |
|
члены специализации для массивов, 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 начиная с C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* см. ниже */ d1 ) noexcept ; |
(3) | (constexpr начиная с C++23) |
|
template
<
class
U
>
unique_ptr ( U p, /* см. ниже */ d2 ) noexcept ; |
(4) | (constexpr начиная с C++23) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (constexpr начиная с C++23) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (constexpr начиная с C++23) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
std::unique_ptr
, который ничего не содержит. Инициализирует хранимый указатель и хранимый deleter значениями по умолчанию. Требует, чтобы
Deleter
был
DefaultConstructible
и чтобы конструкция не выбрасывала исключение. Эти перегрузки участвуют в разрешении перегрузки только если
std::
is_default_constructible
<
Deleter
>
::
value
равно
true
и
Deleter
не является типом указателя.
std::unique_ptr
, который владеет
p
, инициализируя сохраненный указатель значением
p
и инициализируя сохраненный удалитель значением по умолчанию. Требует, чтобы
Deleter
был
DefaultConstructible
и чтобы конструкция не выбрасывала исключение. Эта перегрузка участвует в разрешении перегрузки только если
std::
is_default_constructible
<
Deleter
>
::
value
равно
true
и
Deleter
не является типом указателя.
|
Этот конструктор не выбирается при выводе аргументов шаблона класса . |
(начиная с C++17) |
std::unique_ptr
, который владеет
p
, инициализируя сохраненный указатель значением
p
и инициализируя удалитель
D
следующим образом (зависит от того, является ли
D
ссылочным типом).
D
является типом без ссылки
A
, тогда сигнатуры:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) |
(требует, чтобы
Deleter
был nothrow-
CopyConstructible
)
|
|
unique_ptr
(
pointer p, A
&&
d
)
noexcept
;
|
(2) |
(требует, чтобы
Deleter
был nothrow-
MoveConstructible
)
|
D
является типом lvalue-ссылки
A
&
, тогда сигнатуры имеют вид:
|
unique_ptr
(
pointer p, A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p, A
&&
d
)
=
delete
;
|
(2) | |
D
является типом lvalue-ссылки
const
A
&
, тогда сигнатуры имеют вид:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p,
const
A
&&
d
)
=
delete
;
|
(2) | |
|
Эти два конструктора не выбираются выводом аргументов шаблона класса . |
(since C++17) |
-
Uимеет тот же тип, что иpointer, или -
Uявляется std::nullptr_t , или -
pointerимеет тот же тип, что иelement_type*, иUявляется некоторым типом указателяV*, таким чтоV(*)[]неявно преобразуется вelement_type(*)[].
unique_ptr
путем передачи владения из
u
в
*
this
и сохраняет нулевой указатель в
u
. Этот конструктор участвует в разрешении перегрузки только если
std::
is_move_constructible
<
Deleter
>
::
value
равно
true
. Если
Deleter
не является ссылочным типом, требует, чтобы он был безысключительным
MoveConstructible
(если
Deleter
является ссылкой,
get_deleter()
и
u.get_deleter()
после перемещающего конструирования ссылаются на одно и то же значение).
unique_ptr
путем передачи владения от
u
к
*
this
, где
u
создан с указанным удалителем (
E
). Зависит от того, является ли
E
ссылочным типом, следующим образом:
E
является ссылочным типом, этот удалитель копируется из
u
's deleter (требуется, чтобы эта конструкция не выбрасывала исключений),
E
является типом без ссылки, этот удалитель перемещается из
u
's deleter (требуется, чтобы эта конструкция не выбрасывала исключений).
pointer
,
Deleter
является ссылочным типом и
E
имеет тот же тип, что и
Deleter
, либо
Deleter
не является ссылочным типом и
E
неявно преобразуется в
Deleter
.
-
Uявляется типом массива, -
pointerимеет тот же тип, что иelement_type*, - unique_ptr < U,E > :: pointer имеет тот же тип, что и unique_ptr < U,E > :: element_type * ,
-
unique_ptr
<
U,E
>
::
element_type
(
*
)
[
]
преобразуется в
element_type(*)[], -
либо
Deleterявляется ссылочным типом иEимеет тот же тип, что иDeleter, либоDeleterне является ссылочным типом иEнеявно преобразуется вDeleter.
unique_ptr
, в котором сохраненный указатель инициализируется с помощью
u.release()
, а сохраненный удалитель инициализируется значением по умолчанию. Этот конструктор участвует в разрешении перегрузки только если
U*
неявно преобразуется в
T*
и
Deleter
имеет тот же тип, что и
std::
default_delete
<
T
>
.
Содержание |
Параметры
| p | - | указатель на управляемый объект |
| d1, d2 | - | удалитель для уничтожения объекта |
| u | - | другой умный указатель для получения владения |
Примечания
|
Вместо использования перегрузки (2) вместе с new, часто лучше использовать std::make_unique<T> . |
(since C++14) |
std:: unique_ptr < Derived > неявно преобразуется в std:: unique_ptr < Base > через перегрузку (6) (поскольку и управляемый указатель, и std::default_delete неявно преобразуемы).
Поскольку конструктор по умолчанию является constexpr , статические unique_ptr инициализируются как часть статической нелокальной инициализации , до начала любой динамической нелокальной инициализации. Это делает безопасным использование unique_ptr в конструкторе любого статического объекта.
|
Нет вывода аргументов шаблона класса из указателя, поскольку невозможно различить указатель, полученный из массивной и не-массивной форм new . |
(since C++17) |
Пример
#include <iostream> #include <memory> struct Foo // объект для управления { Foo() { std::cout << "Foo конструктор\n"; } Foo(const Foo&) { std::cout << "Foo конструктор копирования\n"; } Foo(Foo&&) { std::cout << "Foo move ctor\n"; } ~Foo() { std::cout << "~Foo деструктор\n"; } }; struct D // deleter { D() {}; D(const D&) { std::cout << "D конструктор копирования\n"; } D(D&) { std::cout << "D неконстантный конструктор копирования\n"; } D(D&&) { std::cout << "D конструктор перемещения \n"; } void operator()(Foo* p) const { std::cout << "D удаляет Foo\n"; delete p; }; }; int main() { std::cout << "Пример конструктора(1)...\n"; std::unique_ptr<Foo> up1; // up1 пуст std::unique_ptr<Foo> up1b(nullptr); // up1b пуст std::cout << "Пример конструктора(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); //up2 теперь владеет Foo } // Foo удален std::cout << "Пример конструктора(3)...\n"; D d; { // тип deleter не является ссылкой std::unique_ptr<Foo, D> up3(new Foo, d); // удалитель скопирован } { // тип deleter является ссылкой std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b содержит ссылку на d } std::cout << "Пример конструктора(4)...\n"; { // deleter не является ссылкой std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved } std::cout << "Пример конструктора(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::move(up5a)); // передача владения } std::cout << "Пример конструктора(6)...\n"; { std::unique_ptr<Foo, D> up6a(new Foo, d); // D копируется std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D перемещён std::unique_ptr<Foo, D&> up6c(new Foo, d); // D является ссылкой std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D копируется } #if (__cplusplus < 201703L) std::cout << "Пример конструктора(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // передача владения } #endif std::cout << "Пример конструктора массива...\n"; { std::unique_ptr<Foo[]> up(new Foo[3]); } // три объекта Foo удалены }
Вывод:
Пример конструктора(1)... Пример конструктора(2)... Foo ctor ~Foo dtor Пример конструктора(3)... Foo ctor D copy ctor D is deleting a Foo ~Foo dtor Foo ctor D is deleting a Foo ~Foo dtor Пример конструктора(4)... Foo ctor D move ctor D is deleting a Foo ~Foo dtor Пример конструктора(5)... Foo ctor ~Foo dtor Пример конструктора(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 Пример конструктора(7)... Foo ctor ~Foo dtor Пример конструктора массива... Foo ctor Foo ctor Foo ctor ~Foo dtor ~Foo dtor ~Foo dtor
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| LWG 2118 | C++11 |
Конструкторы
unique_ptr<T[]>
отвергали квалификационные преобразования.
|
Принимать. |
| LWG 2520 | C++11 |
unique_ptr<T[]>
случайно стал неконструируемым из
nullptr_t
.
|
Сделать конструируемым. |
| LWG 2801 | C++11 | Конструктор по умолчанию не был ограничен. | Ограничен. |
| LWG 2899 | C++11 | Перемещающий конструктор не был ограничен. | Ограничен. |
| LWG 2905 | C++11 | Ограничение на конструктор из указателя и удалителя было неверным. | Исправлено. |
| LWG 2944 | C++11 | Некоторые предусловия были случайно удалены LWG 2905 | Восстановлены. |