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) | (自 C++23 起为 constexpr) |
|
unique_ptr
(
pointer p,
/* see below */
d1
)
noexcept
;
|
(3) | (自 C++23 起为 constexpr) |
|
unique_ptr
(
pointer p,
/* see below */
d2
)
noexcept
;
|
(4) | (自 C++23 起为 constexpr) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (自 C++23 起为 constexpr) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (自 C++23 起为 constexpr) |
|
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) | (自 C++23 起为 constexpr) |
|
template
<
class
U
>
unique_ptr ( U p, /* see below */ d1 ) noexcept ; |
(3) | (自 C++23 起为 constexpr) |
|
template
<
class
U
>
unique_ptr ( U p, /* see below */ d2 ) noexcept ; |
(4) | (自 C++23 起为 constexpr) |
|
unique_ptr
(
unique_ptr
&&
u
)
noexcept
;
|
(5) | (自 C++23 起为 constexpr) |
|
template
<
class
U,
class
E
>
unique_ptr ( unique_ptr < U, E > && u ) noexcept ; |
(6) | (自 C++23 起为 constexpr) |
|
unique_ptr
(
const
unique_ptr
&
)
=
delete
;
|
(7) | |
std::unique_ptr
。对存储的指针和存储的删除器进行值初始化。要求
Deleter
满足
可默认构造
要求,且构造过程不会抛出异常。这些重载仅当
std::
is_default_constructible
<
Deleter
>
::
value
为
true
且
Deleter
不是指针类型时才参与重载决议。
std::unique_ptr
,使用
p
初始化存储的指针并对存储的删除器进行值初始化。要求
Deleter
满足
可默认构造
且构造过程不会抛出异常。此重载仅当
std::
is_default_constructible
<
Deleter
>
::
value
为
true
且
Deleter
不是指针类型时参与重载决议。
|
此构造函数不会被 类模板实参推导 选中。 |
(C++17 起) |
std::unique_ptr
对象,使用
p
初始化存储的指针,并按以下方式初始化删除器
D
(具体取决于
D
是否为引用类型)。
D
为非引用类型
A
,则函数签名为:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) |
(要求
Deleter
满足不抛出异常的
可复制构造
)
|
|
unique_ptr
(
pointer p, A
&&
d
)
noexcept
;
|
(2) |
(要求
Deleter
满足不抛出异常的
可移动构造
)
|
D
为左值引用类型
A
&
,则函数签名为:
|
unique_ptr
(
pointer p, A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p, A
&&
d
)
=
delete
;
|
(2) | |
D
为左值引用类型
const
A
&
,则函数签名为:
|
unique_ptr
(
pointer p,
const
A
&
d
)
noexcept
;
|
(1) | |
|
unique_ptr
(
pointer p,
const
A
&&
d
)
=
delete
;
|
(2) | |
|
这两个构造函数不会被 类模板实参推导 选中。 |
(C++17 起) |
-
U与pointer类型相同,或 -
U是 std::nullptr_t ,或 -
pointer与element_type*类型相同,且U是某种指针类型V*,使得V(*)[]可隐式转换为element_type(*)[]。
unique_ptr
,并将空指针存入
u
。该构造函数仅当
std::
is_move_constructible
<
Deleter
>
::
value
为
true
时参与重载决议。如果
Deleter
不是引用类型,要求其满足不抛出移动构造(若
Deleter
为引用类型,则移动构造后的
get_deleter()
与
u.get_deleter()
将引用同一值)。
unique_ptr
,其中
u
使用指定的删除器(
E
)构造。具体行为取决于
E
是否为引用类型,如下所示:
E
为引用类型,则此删除器从
u
的删除器复制构造(要求该构造过程不抛出异常),
E
是非引用类型,则此删除器从
u
的删除器移动构造(要求该构造操作不抛出异常)。
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 | - | 用于获取所有权的另一智能指针 |
注释
|
相较于结合使用 new 和重载版本 (2) ,通常更推荐使用 std::make_unique<T> 。 |
(since C++14) |
std:: unique_ptr < Derived > 可通过重载 (6) 隐式转换为 std:: unique_ptr < Base > (因为被管理的指针和 std::default_delete 均可隐式转换)。
由于默认构造函数是 constexpr ,静态 unique_ptr 会在 静态非局部初始化 阶段完成初始化,早于任何动态非局部初始化的开始。这使得在任何静态对象的构造函数中使用 unique_ptr 都是安全的。
|
不存在从指针类型进行的 类模板实参推导 ,因为无法区分通过数组形式和非数组形式的 new 获得的指针。 |
(since C++17) |
示例
#include <iostream> #include <memory> struct Foo // 要管理的对象 { 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 // 删除器 { D() {}; D(const D&) { std::cout << "D copy ctor\n"; } D(D&) { std::cout << "D non-const copy ctor\n"; } D(D&&) { std::cout << "D move ctor \n"; } void operator()(Foo* p) const { std::cout << "D is deleting a Foo\n"; delete p; }; }; int main() { std::cout << "Example constructor(1)...\n"; std::unique_ptr<Foo> up1; // up1 为空 std::unique_ptr<Foo> up1b(nullptr); // up1b 为空 std::cout << "Example constructor(2)...\n"; { std::unique_ptr<Foo> up2(new Foo); // up2 现在拥有一个 Foo } // Foo 被删除 std::cout << "Example constructor(3)...\n"; D d; { // 删除器类型不是引用 std::unique_ptr<Foo, D> up3(new Foo, d); // 删除器被复制 } { // 删除器类型是引用 std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b 持有对 d 的引用 } std::cout << "Example constructor(4)...\n"; { // 删除器不是引用 std::unique_ptr<Foo, D> up4(new Foo, D()); // 删除器被移动 } std::cout << "Example constructor(5)...\n"; { std::unique_ptr<Foo> up5a(new Foo); std::unique_ptr<Foo> up5b(std::move(up5a)); // 所有权转移 } std::cout << "Example constructor(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 << "Example constructor(7)...\n"; { std::auto_ptr<Foo> up7a(new Foo); std::unique_ptr<Foo> up7b(std::move(up7a)); // 所有权转移 } #endif std::cout << "Example array constructor...\n"; { std::unique_ptr<Foo[]> up<span
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| 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意外删除了某些前置条件 | 恢复前置条件 |