486 lines
41 KiB
HTML
486 lines
41 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>std::unique_ptr<T,Deleter>::unique_ptr</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_memory_unique_ptr_unique_ptr skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading"><span style="font-size:0.7em; line-height:130%">std::unique_ptr<T,Deleter>::</span>unique_ptr</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-memory.html">memory</a>‎ | <a href="cpp-memory-unique_ptr.html">unique ptr</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>主模板 unique_ptr<T> 的成员</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">constexpr</span> unique_ptr<span class="br0">(</span><span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span><br />
|
|
<span class="kw4">constexpr</span> unique_ptr<span class="br0">(</span> <a href="cpp-types-nullptr_t.html"><span class="kw102">std::<span class="me2">nullptr_t</span></span></a> <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">explicit</span> unique_ptr<span class="br0">(</span> pointer p <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span> pointer p, <span class="coMULTI">/* see below */</span> d1 <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(3)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span> pointer p, <span class="coMULTI">/* see below */</span> d2 <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(4)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span> unique_ptr<span class="sy3">&&</span> u <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(5)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span> <span class="kw1">class</span> U, <span class="kw1">class</span> E <span class="sy1">></span><br />
|
|
unique_ptr<span class="br0">(</span> unique_ptr<span class="sy1"><</span>U, E<span class="sy1">></span><span class="sy3">&&</span> u <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(6)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span> <span class="kw1">class</span> U <span class="sy1">></span><br />
|
|
unique_ptr<span class="br0">(</span> <a href="cpp-memory-auto_ptr.html"><span class="kw742">std::<span class="me2">auto_ptr</span></span></a><span class="sy1"><</span>U<span class="sy1">></span><span class="sy3">&&</span> u <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(7)</td>
|
|
<td><span class="t-mark-rev t-until-cxx17">(C++17 中移除)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>数组特化 unique_ptr<T[]> 的成员</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">constexpr</span> unique_ptr<span class="br0">(</span><span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span><br />
|
|
<span class="kw4">constexpr</span> unique_ptr<span class="br0">(</span> <a href="cpp-types-nullptr_t.html"><span class="kw102">std::<span class="me2">nullptr_t</span></span></a> <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> U<span class="sy1">></span> <span class="kw1">explicit</span> unique_ptr<span class="br0">(</span> U p <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> U<span class="sy1">></span> unique_ptr<span class="br0">(</span> U p, <span class="coMULTI">/* see below */</span> d1 <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(3)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> U<span class="sy1">></span> unique_ptr<span class="br0">(</span> U p, <span class="coMULTI">/* see below */</span> d2 <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(4)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span> unique_ptr<span class="sy3">&&</span> u <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(5)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span> <span class="kw1">class</span> U, <span class="kw1">class</span> E <span class="sy1">></span><br />
|
|
unique_ptr<span class="br0">(</span> unique_ptr<span class="sy1"><</span>U, E<span class="sy1">></span><span class="sy3">&&</span> u <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(6)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 构造不占有对象的 <code>std::unique_ptr</code> 。值初始化存储的指针和存储的删除器。要求 <code>Deleter</code> <a href="cpp-named_req-DefaultConstructible.html"><span style="font-style:italic">可默认构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(DefaultConstructible)</span></a> 且构造不抛异常。这些重载仅若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-types-is_default_constructible.html"><span class="kw526">std::<span class="me2">is_default_constructible</span></span></a><span class="sy1"><</span>Deleter<span class="sy1">></span><span class="sy4">::</span><span class="me2">value</span></span></span> 为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 且 <span class="t-c"><span class="mw-geshi cpp source-cpp">Deleter</span></span> 不是指针类型才参与重载决议。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 构造占有 p 的 <code>std::unique_ptr</code> ,以 p 初始化存储的指针,并值初始化存储的删除器。要求 <code>Deleter</code> <a href="cpp-named_req-DefaultConstructible.html"><span style="font-style:italic">可默认构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(DefaultConstructible)</span></a> 且构造不抛异常。这些重载仅若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-types-is_default_constructible.html"><span class="kw526">std::<span class="me2">is_default_constructible</span></span></a><span class="sy1"><</span>Deleter<span class="sy1">></span><span class="sy4">::</span><span class="me2">value</span></span></span> 为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 且 <span class="t-c"><span class="mw-geshi cpp source-cpp">Deleter</span></span> 不是指针类型才参与重载决议。
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>若<a href="cpp-language-class_template_argument_deduction.html">类模板实参推导</a>选择此构造函数,则程序为谬构。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">3-4)</span> 构造占有 <code>p</code> 的 <code>std::unique_ptr</code> 对象,以 <code>p</code> 初始化存储的指针,并按下列方式初始化删除器 <code>D</code> (依赖于 <code>D</code> 是否为引用类型)</div>
|
|
<div class="t-li2"><span class="t-li">a)</span> 若 <code>D</code> 是非引用类型 <span class="t-c"><span class="mw-geshi cpp source-cpp">A</span></span> ,则签名是:
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, <span class="kw4">const</span> A<span class="sy3">&</span> d<span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td>(要求 <code>Deleter</code> 为不抛出<a href="cpp-named_req-CopyConstructible.html"><span style="font-style:italic">可复制构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(CopyConstructible)</span></a> )</td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, A<span class="sy3">&&</span> d<span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td>(要求 <code>Deleter</code> 为不抛出<a href="cpp-named_req-MoveConstructible.html"><span style="font-style:italic">可移动构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(MoveConstructible)</span></a> )</td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="t-li2"><span class="t-li">b)</span> 若 <code>D</code> 是左值引用类型 <span class="t-c"><span class="mw-geshi cpp source-cpp">A<span class="sy3">&</span></span></span> ,则签名是:
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, A<span class="sy3">&</span> d<span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, A<span class="sy3">&&</span> d<span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="t-li2"><span class="t-li">c)</span> 若 <code>D</code> 是左值引用类型 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> A<span class="sy3">&</span></span></span> ,则签名是:
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, <span class="kw4">const</span> A<span class="sy3">&</span> d<span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp">unique_ptr<span class="br0">(</span>pointer p, <span class="kw4">const</span> A<span class="sy3">&&</span> d<span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li"></span> 所有情况下中删除器从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-utility-forward.html"><span class="kw1117">std::<span class="me2">forward</span></span></a><span class="sy1"><</span>decltype<span class="br0">(</span>d<span class="br0">)</span><span class="sy1">></span><span class="br0">(</span>d<span class="br0">)</span></span></span> 初始化。这些重载仅若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-types-is_constructible.html"><span class="kw520">std::<span class="me2">is_constructible</span></span></a><span class="sy1"><</span>D, decltype<span class="br0">(</span>d<span class="br0">)</span><span class="sy1">></span><span class="sy4">::</span><span class="me2">value</span></span></span> 为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 才参与重载决议。
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>若<a href="cpp-language-class_template_argument_deduction.html">类模板实参推导</a>选择二个构造函数之一,则程序为谬构。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">2-4)</span> 数组特化中表现同初等模板中接收一个指针参数的构造函数,除了它们不另外参与重载决议,除非下列之一为真:
|
|
<ul>
|
|
<li><code>U</code> 与 <code>pointer</code> 为同一类型,或</li>
|
|
<li><code>U</code> 为 <span class="t-lc"><a href="cpp-types-nullptr_t.html">std::nullptr_t</a></span> ,或</li>
|
|
<li><code>pointer</code> 与 <code>element_type*</code> 为同一类型且 <code>U</code> 为指针类型 <code>V*</code> ,满足 <code>V(*)[]</code> 可隐式转换为 <code>element_type(*)[]</code> 。</li>
|
|
</ul>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> 通过从 <code>u</code> 转移所有权给 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>this</span></span> 构造 <code>unique_ptr</code> 并存储空指针于 <code>u</code> 。此构造函数仅若 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-types-is_move_constructible.html"><span class="kw538">std::<span class="me2">is_move_constructible</span></span></a><span class="sy1"><</span>Deleter<span class="sy1">></span><span class="sy4">::</span><span class="me2">value</span></span></span> 为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 才参与重载决议。若 <code>Deleter</code> 不是引用类型,则要求它为不抛出<a href="cpp-named_req-MoveConstructible.html"><span style="font-style:italic">可移动构造</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(MoveConstructible)</span></a> (若 <code>Deleter</code> 是引用,则 <code>get_deleter()</code> 和 <code>u.get_deleter()</code> 在移动构造后引用相同值)。</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> 通过从 <code>u</code> 转移所有权给 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>this</span></span> 构造 <code>unique_ptr</code> ,其中 <code>u</code> 以指定的删除器( <code>E</code> )构造。它依赖于 <code>E</code> 是否引用类型,如下:
|
|
<dl>
|
|
<dd></dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-li2"><span class="t-li">a)</span> 若 <code>E</code> 是引用类型,则从 <code>u</code> 的删除器复制构造此删除器(要求此构造不抛出)</div>
|
|
<div class="t-li2"><span class="t-li">b)</span> 若 <code>E</code> 不是引用类型,则从 <code>u</code> 的删除器移动构造此删除器(要求此构造不抛出)</div>
|
|
<div class="t-li1"><span class="t-li"></span> 此构造函数仅若下列皆为真才参与重载决议:</div>
|
|
<div class="t-li2"><span class="t-li">a)</span> <span class="t-c"><span class="mw-geshi cpp source-cpp">unique_ptr<span class="sy1"><</span>U, E<span class="sy1">></span><span class="sy4">::</span><span class="me2">pointer</span></span></span> 可隐式转换为 <code>pointer</code></div>
|
|
<div class="t-li2"><span class="t-li">b)</span> U 不是数组类型</div>
|
|
<div class="t-li2"><span class="t-li">c)</span> <code>Deleter</code> 是引用类型且 <code>E</code> 与 <code>D</code> 为同一类型,或 <code>Deleter</code> 不是引用类型且 <code>E</code> 可隐式转换为 <code>D</code></div>
|
|
<div class="t-li1"><span class="t-li">6)</span> 数组特化中,表现同在初等模板中的版本,除了它仅若下列皆为真才会参与重载决议
|
|
<ul>
|
|
<li><code>U</code> 是数组类型</li>
|
|
<li><code>pointer</code> 与 <code>element_type*</code> 是同一类型</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">unique_ptr<span class="sy1"><</span>U,E<span class="sy1">></span><span class="sy4">::</span><span class="me2">pointer</span></span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp">unique_ptr<span class="sy1"><</span>U,E<span class="sy1">></span><span class="sy4">::</span><span class="me2">element_type</span><span class="sy2">*</span></span></span> 是同一类型</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">unique_ptr<span class="sy1"><</span>U,E<span class="sy1">></span><span class="sy4">::</span><span class="me2">element_type</span><span class="br0">(</span><span class="sy2">*</span><span class="br0">)</span><span class="br0">[</span><span class="br0">]</span></span></span> 可转换为 <code>element_type(*)[]</code></li>
|
|
<li><code>Deleter</code> 是引用类型且 <code>E</code> 与 <code>Deleter</code> 是同一类型,或 <code>Deleter</code> 非引用类型且 <code>E</code> 可隐式转换为 <code>Deleter</code> 。</li>
|
|
</ul>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">7)</span> 构造 <code>unique_ptr</code> ,其中以 <code>u.release()</code> 初始化存储的指针,并值初始化存储的删除器。此构造函数仅若 <code>U*</code> 可隐式转换为 <code>T*</code> 且 <code>Deleter</code> 与 <code>std::default_delete<T></code> 为同一类型才参与重载决议。</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E6.95.B0">参数</span></h3>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td>p</td>
|
|
<td>-</td>
|
|
<td>指向要管理的对象的指针</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>d1,d2</td>
|
|
<td>-</td>
|
|
<td>用于销毁对象的删除器</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>u</td>
|
|
<td>-</td>
|
|
<td>获取所有权来源的智能指针</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx14">
|
|
<td>
|
|
<p>使用 <span class="t-lc"><a href="cpp-memory-unique_ptr-make_unique.html">std::make_unique<T></a></span> 是更好的做法,可取代与 new 一起的重载 <span class="t-v">(2)</span> 。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx14">(C++14 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Derived<span class="sy1">></span></span></span> 通过重载 <span class="t-v">(6)</span> 可隐式转换为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Base<span class="sy1">></span></span></span> (因为被管理指针和 <span class="t-lc"><a href="cpp-memory-default_delete.html">std::default_delete</a></span> 都可隐式转换)。</p>
|
|
<p>因为默认构造函数是 <code>constexpr</code> ,故静态的 unique_ptr 作为<a href="cpp-language-initialization.html#.E9.9D.9E.E5.B1.80.E9.83.A8.E5.8F.98.E9.87.8F">静态非局部初始化</a>的一部分初始化,在任何动态初始化之前。这使得在任何静态对象的构造函数中使用 unique_ptr 是安全的。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>无源自指针类型的<a href="cpp-language-class_template_argument_deduction.html">类模板实参推导</a>,因为不可能辨别来自 <code>new</code> 的数组和非数组形式的指针。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <memory></span>
|
|
|
|
<span class="kw1">struct</span> Foo <span class="br0">{</span> <span class="co1">// 要管理的对象</span>
|
|
Foo<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Foo ctor<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
Foo<span class="br0">(</span><span class="kw4">const</span> Foo<span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Foo copy ctor<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
Foo<span class="br0">(</span>Foo<span class="sy3">&&</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Foo move ctor<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
~Foo<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"~Foo dtor<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> D <span class="br0">{</span> <span class="co1">// 删除器</span>
|
|
D<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
D<span class="br0">(</span><span class="kw4">const</span> D<span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"D copy ctor<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
D<span class="br0">(</span>D<span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"D non-const copy ctor<span class="es1">\n</span>"</span><span class="sy4">;</span><span class="br0">}</span>
|
|
D<span class="br0">(</span>D<span class="sy3">&&</span><span class="br0">)</span> <span class="br0">{</span> <a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"D move ctor <span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">void</span> operator<span class="br0">(</span><span class="br0">)</span><span class="br0">(</span>Foo<span class="sy2">*</span> p<span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"D is deleting a Foo<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
delete p<span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(1)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up1<span class="sy4">;</span> <span class="co1">// up1 为空</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up1b<span class="br0">(</span>nullptr<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// up1b 为空</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(2)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up2<span class="br0">(</span>new Foo<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// up2 现在占有 Foo</span>
|
|
<span class="br0">}</span> <span class="co1">// Foo 被删除</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(3)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
D d<span class="sy4">;</span>
|
|
<span class="br0">{</span> <span class="co1">// 删除器类型不是引用</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy1">></span> up3<span class="br0">(</span>new Foo, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 复制删除器</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">{</span> <span class="co1">// 删除器类型是引用 </span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy3">&</span><span class="sy1">></span> up3b<span class="br0">(</span>new Foo, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// up3b 保有到 d 的引用</span>
|
|
<span class="br0">}</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(4)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span> <span class="co1">// 删除器不是引用</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy1">></span> up4<span class="br0">(</span>new Foo, D<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 移动删除器</span>
|
|
<span class="br0">}</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(5)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up5a<span class="br0">(</span>new Foo<span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up5b<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>up5a<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 所有权转移</span>
|
|
<span class="br0">}</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(6)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy1">></span> up6a<span class="br0">(</span>new Foo, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 复制 D</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy1">></span> up6b<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>up6a<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 移动 D</span>
|
|
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy3">&</span><span class="sy1">></span> up6c<span class="br0">(</span>new Foo, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// D 是引用</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo, D<span class="sy1">></span> up6d<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>up6c<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 复制 D</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="co2">#if (__cplusplus < 201703L)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example constructor(7)...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-memory-auto_ptr.html"><span class="kw742">std::<span class="me2">auto_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up7a<span class="br0">(</span>new Foo<span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="sy1">></span> up7b<span class="br0">(</span>std<span class="sy4">::</span><span class="me2">move</span><span class="br0">(</span>up7a<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 所有权转移</span>
|
|
<span class="br0">}</span>
|
|
<span class="co2">#endif</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Example array constructor...<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1"><</span>Foo<span class="br0">[</span><span class="br0">]</span><span class="sy1">></span> up<span class="br0">(</span>new Foo<span class="br0">[</span><span class="nu0">3</span><span class="br0">]</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="co1">// 删除三个 Foo 对象</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">Example constructor(1)...
|
|
Example constructor(2)...
|
|
Foo ctor
|
|
~Foo dtor
|
|
Example constructor(3)...
|
|
Foo ctor
|
|
D copy ctor
|
|
D is deleting a Foo
|
|
~Foo dtor
|
|
Foo ctor
|
|
D is deleting a Foo
|
|
~Foo dtor
|
|
Example constructor(4)...
|
|
Foo ctor
|
|
D move ctor
|
|
D is deleting a Foo
|
|
~Foo dtor
|
|
Example constructor(5)...
|
|
Foo ctor
|
|
~Foo dtor
|
|
Example 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
|
|
Example constructor(7)...
|
|
Foo ctor
|
|
~Foo dtor
|
|
Example array constructor...
|
|
Foo ctor
|
|
Foo ctor
|
|
Foo ctor
|
|
~Foo dtor
|
|
~Foo dtor
|
|
~Foo dtor</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
|
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
|
<table class="dsctable" style="font-size:0.8em">
|
|
<tr>
|
|
<th>DR</th>
|
|
<th>应用于</th>
|
|
<th>出版时的行为</th>
|
|
<th>正确行为</th>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2118">LWG 2118</a></td>
|
|
<td>C++11</td>
|
|
<td><code>unique_ptr<T[]></code> 的构造函数拒绝限定转换</td>
|
|
<td>接受</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2520">LWG 2520</a></td>
|
|
<td>C++11</td>
|
|
<td><code>unique_ptr<T[]></code> 被意外地设为不可从 <code>nullptr_t</code> 构造</td>
|
|
<td>使之可构造</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2801">LWG 2801</a></td>
|
|
<td>C++11</td>
|
|
<td>默认构造函数未受约束</td>
|
|
<td>已约束</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2899">LWG 2899</a></td>
|
|
<td>C++11</td>
|
|
<td>移动构造函数未受约束</td>
|
|
<td>已约束</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2905">LWG 2905</a></td>
|
|
<td>C++11</td>
|
|
<td>来自指针和删除器的构造函数上的约束错误</td>
|
|
<td>更正</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2944">LWG 2944</a></td>
|
|
<td>C++11</td>
|
|
<td>某些前条件被 LWG 2905 意外丢弃</td>
|
|
<td>恢复</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|