712 lines
66 KiB
HTML
712 lines
66 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>operator delete, operator delete[]</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_new_operator_delete 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%">operator</span> delete<span style="font-size:0.7em; line-height:130%">, operator</span> delete[]</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-new.html">new</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-dsc-header">
|
|
<td>
|
|
<div>定义于头文件 <code><a href="cpp-header-new.html"><new></a></code></div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>可替换通常解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(1)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody></tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(2)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(3)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(4)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx14">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(5)</td>
|
|
<td><span class="t-mark-rev t-since-cxx14">(C++14 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx14">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(6)</td>
|
|
<td><span class="t-mark-rev t-since-cxx14">(C++14 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz,<br />
|
|
<a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <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-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz,<br />
|
|
<a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(8)</td>
|
|
<td><span class="t-mark-rev t-since-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>可替换布置解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(9)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody></tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(10)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al,<br />
|
|
<span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(11)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al,<br />
|
|
<span class="kw4">const</span> <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="sy3">&</span> tag <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(12)</td>
|
|
<td><span class="t-mark-rev t-since-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>不分配布置解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(13)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">void</span><span class="sy2">*</span> place <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">void</span><span class="sy2">*</span> place <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody></tbody>
|
|
<tbody class="t-dcl-rev t-dcl-rev-num">
|
|
<tr class="t-dcl-rev-aux">
|
|
<td></td>
|
|
<td rowspan="142">(14)</td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-until-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">void</span><span class="sy2">*</span> place <span class="br0">)</span> <span class="kw1">throw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx11">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">void</span><span class="sy2">*</span> place <span class="br0">)</span> <span class="kw1">noexcept</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>用户定义的布置解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, args... <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(15)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, args... <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(16)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>类特定通常解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(17)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(18)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(19)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(20)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(21)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(22)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(23)</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx17">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(24)</td>
|
|
<td><span class="t-mark-rev t-since-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>类特定布置解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete <span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, args... <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(25)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span> <span class="kw4">void</span><span class="sy2">*</span> ptr, args... <span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(26)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl-h">
|
|
<td>
|
|
<div>类特定销毁解分配函数</div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx20">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>T<span class="sy2">*</span> ptr, std<span class="sy4">::</span><span class="me2">destroying_delete_t</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(27)</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx20">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>T<span class="sy2">*</span> ptr, std<span class="sy4">::</span><span class="me2">destroying_delete_t</span>,<br />
|
|
<a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al<span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(28)</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx20">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>T<span class="sy2">*</span> ptr, std<span class="sy4">::</span><span class="me2">destroying_delete_t</span>, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz<span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(29)</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl t-since-cxx20">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span> T<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>T<span class="sy2">*</span> ptr, std<span class="sy4">::</span><span class="me2">destroying_delete_t</span>,<br />
|
|
<a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz, <a href="cpp-memory-new-align_val_t.html"><span class="kw695">std::<span class="me2">align_val_t</span></span></a> al<span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(30)</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>解分配先前由匹配的 <span class="t-lc"><a href="cpp-memory-new-operator_new.html">operator new</a></span> 所分配的存储。这些解分配函数为 <a href="cpp-language-delete.html">delete 表达式</a>与 <a href="cpp-language-new.html">new 表达式</a>所调用,以在析构(或构造失败)拥有动态存储期的对象后解分配内存。它们亦可用常规函数调用语法调用。</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 为 <a href="cpp-language-delete.html">delete 表达式</a>所调用,以解分配先前为单对象分配的存储。此函数的标准库实现的行为未定义,除非 <code>ptr</code> 是空指针或是先前从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">(</span>size_t<span class="br0">)</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">(</span>size_t, <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="br0">)</span></span></span> 的标准库实现获得的指针。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 为 <a href="cpp-language-delete.html">delete[] 表达式</a>所调用,以解分配先前为对象数组分配的存储。此函数的标准库实现的行为未定义,除非 <code>ptr</code> 是空指针或是先前从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>size_t<span class="br0">)</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>size_t, <a href="cpp-memory-new-nothrow_t.html"><span class="kw694">std::<span class="me2">nothrow_t</span></span></a><span class="br0">)</span></span></span> 的标准库实现获得的指针。</div>
|
|
<div class="t-li1"><span class="t-li">3,4)</span> 同 <span class="t-v">(1,2)</span> ,除了若对齐要求超出 <code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code> 才被调用</div>
|
|
<div class="t-li1"><span class="t-li">5,6)</span> 若提供用户定义重载,则取代 <span class="t-v">(1-2)</span> 得到调用,除了在删除不完整类型的对象、非类类型的数组和可平凡析构类类型的数组时,调用 <span class="t-v">(1-2)</span> 还是 <span class="t-v">(5-6)</span> 是未指定的。内存分配器可用给定的大小变得更高效。标准库实现等同于 <span class="t-v">(1-2)</span> 。</div>
|
|
<div class="t-li1"><span class="t-li">7,8)</span> 同 <span class="t-v">(5-6)</span> ,除了若对齐要求超出 <code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code> 才被调用</div>
|
|
<div class="t-li1"><span class="t-li">9)</span> 若对象的构造函数抛出异常,则为不抛出的单对象 <a href="cpp-language-new.html">new 表达式</a>所调用。标准库实现表现同 <span class="t-v">(1)</span></div>
|
|
<div class="t-li1"><span class="t-li">10)</span> 若任何对象的构造函数抛出异常,则(在执行数组中已成功构造的所有对象的析构函数后)为不抛出的数组 <a href="cpp-language-new.html">new[] 表达式</a>所调用。标准库实现表现同 <span class="t-v">(2)</span></div>
|
|
<div class="t-li1"><span class="t-li">11,12)</span> 同 <span class="t-v">(9,10)</span> ,除了若对齐要求超出 <code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code> 才被调用</div>
|
|
<div class="t-li1"><span class="t-li">13)</span> 若对象的构造函数抛出异常,则为标准单对象<a href="cpp-language-new.html">布置 new</a> 表达式所调用。此函数的标准库实现不做任何事。</div>
|
|
<div class="t-li1"><span class="t-li">14)</span> 若任何对象的构造函数抛出异常,则为<a href="cpp-language-new.html">布置 new[]</a> 表达式的数组形式(在执行数组中已成功构造的所有对象的析构函数后)所调用。此函数的标准库实现不做任何事。</div>
|
|
<div class="t-li1"><span class="t-li">15)</span> 若定义,则为拥有匹配签名的自定义单对象<a href="cpp-language-new.html">布置 new</a> 表达式调用,若对象构造函数抛出异常。若定义类特定版本 <span class="t-v">(25)</span> ,则类特定版本优先于 <span class="t-v">(9)</span> 调用。若用户既不提供 <span class="t-v">(25)</span> 又不提供 <span class="t-v">(15)</span> ,则不调用解分配函数。</div>
|
|
<div class="t-li1"><span class="t-li">16)</span> 若定义,则为拥有匹配签名的<a href="cpp-language-new.html">布置 new[]</a> 表达式自定义数组形式(在执行数组中已成功构造的所有对象的析构函数后)调用,若任何对象的构造函数抛出异常。若定义类特定版本 <span class="t-v">(16)</span> ,则类特定版本优先于 <span class="t-v">(10)</span> 调用。若用户既不提供 <span class="t-v">(26)</span> 又不提供 <span class="t-v">(16)</span> ,则不调用解分配函数。</div>
|
|
<div class="t-li1"><span class="t-li">17)</span> 若定义,则为通常单对象 <a href="cpp-language-delete.html">delete 表达式</a>调用,若在解分配一个 T 类型对象。</div>
|
|
<div class="t-li1"><span class="t-li">18)</span> 若定义,则为通常数组 <a href="cpp-language-delete.html">delete[] 表达式</a>调用,若在解分配 T 类型对象的数组。</div>
|
|
<div class="t-li1"><span class="t-li">19,20)</span> 若定义,则优先于 <span class="t-v">(17,18)</span> 调用,若对齐要求超出 <code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code> 。</div>
|
|
<div class="t-li1"><span class="t-li">21)</span> 若定义,且若未定义 <span class="t-v">(17)</span> ,则为通常单对象 <a href="cpp-language-delete.html">delete 表达式</a>调用,若在解分配一个 T 类型对象。</div>
|
|
<div class="t-li1"><span class="t-li">22)</span> 若定义,且若未定义 <span class="t-v">(18)</span> ,则为通常数组 <a href="cpp-language-delete.html">delete[] 表达式</a>调用,若在解分配 T 类型对象的数组。</div>
|
|
<div class="t-li1"><span class="t-li">23,24)</span> 若定义,且若未定义 <span class="t-v">(19,20)</span> ,则优先于无对齐成员调用,若对齐要求超出 <code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code>.</div>
|
|
<div class="t-li1"><span class="t-li">25)</span> 若定义,则为拥有匹配签名的自定义单对象<a href="cpp-language-new.html">布置 new</a> 表达式调用,若对象构造函数抛出异常。若不提供此函数,亦不提供匹配的 <span class="t-v">(15)</span> ,则不调用解分配函数。</div>
|
|
<div class="t-li1"><span class="t-li">26)</span> 若定义,则为拥有匹配签名的自定义<a href="cpp-language-new.html">布置 new[]</a> 表达式的数组形式(在执行数组中已成功构造的所有对象的析构函数后)调用,若任何对象的构造函数抛出异常。若不提供此函数,亦不提供匹配的 <span class="t-v">(16)</span> ,则不调用析构函数。</div>
|
|
<div class="t-li1"><span class="t-li">27-30)</span> 若定义,则 <a href="cpp-language-delete.html">delete 表达式</a>在调用 <code>operator delete</code> 前不对 *p 执行析构函数。取而代之地,变为由此用户定义的 operator delete 负责直接调用析构函数,例如用 <span class="t-c"><span class="mw-geshi cpp source-cpp">p<span class="sy2">-</span><span class="sy1">></span>~T<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></span> 。</div>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>通常(非布置)解分配函数的具对齐和不具对齐重载之间的重载决议准确细节见 <a href="cpp-language-delete.html">delete 表达式</a>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>所有情况下,若 <code>ptr</code> 是空指针,则标准库解分配函数不做任何事。若传递给标准库解分配函数的指针不是从对应的标准库分配函数取得者,则行为未定义。</p>
|
|
<p>在标准库解分配函数返回后,所有引用到被解分配存储的任何部分的指针都变为非法。</p>
|
|
<p>通过已因此方式变为非法的指针解引用,以及将它传递给解分配函数(双重 delete )是未定义行为。任何其他使用是实现定义的。</p>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E6.95.B0">参数</span></h3>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td>ptr</td>
|
|
<td>-</td>
|
|
<td>指向要解分配的内存块的指针或空指针</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>sz</td>
|
|
<td>-</td>
|
|
<td>传递给匹配的分配函数的 size</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>place</td>
|
|
<td>-</td>
|
|
<td>用作匹配的布置 new 中布置参数的指针</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>tag</td>
|
|
<td>-</td>
|
|
<td>匹配不抛出 operator new 所用标签的重载消歧义标签</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>al</td>
|
|
<td>-</td>
|
|
<td>被分配的对象或数组元素的对齐</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>args</td>
|
|
<td>-</td>
|
|
<td>匹配布置分配函数的任意参数(可包含 <span class="t-lc"><a href="cpp-types-size_t.html">std::size_t</a></span> 与 <span class="t-lc"><a href="cpp-memory-new-align_val_t.html">std::align_val_t</a></span> )</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.BF.94.E5.9B.9E.E5.80.BC">返回值</span></h3>
|
|
<p>(无)</p>
|
|
<h3><span class="mw-headline" id=".E5.BC.82.E5.B8.B8">异常</span></h3>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx11">
|
|
<td>
|
|
<div class="t-li1"><span class="t-li">15-30)</span> 容许用户定义的解分配函数抛异常。</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<div class="t-li1"><span class="t-li">15-30)</span> 所有解分配函数均为 <code>noexcept(true)</code> ,除非在声明中另外说明。若解分配函数以抛异常终止,则行为未定义,即使以 <code>noexcept(false)</code> 声明它。</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.85.A8.E5.B1.80.E6.9B.BF.E6.8D.A2">全局替换</span></h3>
|
|
<p>可替换解分配函数 <span class="t-v">(1-12)</span> 在每个翻译单元隐式声明,即使不包含 <code><new></code> 头文件。这些函数是<i>可替换</i>的:定义于程序任何位置、任何头文件的用户提供的拥有相同签名的非成员函数,会为整个程序替换对应的隐式版本。其声明不必可见。</p>
|
|
<p>若程序中提供多于一个替换,或若替换声明有 <code>inline</code> 说明符,则程序非良构,不要求诊断。若替换声明于异于全局命名空间的命名空间,或若它定义为在全局作用域的 static 非成员函数,则程序为非良构。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>nothrow 版本 <span class="t-v">(9,10)</span> 的标准库实现直接调用抛出版本 <span class="t-v">(1,2)</span> 。具大小解分配函数 <span class="t-v">(5-8)</span> 的标准库实现直接调用对应的不具大小解分配函数 <span class="t-v">(1-4)</span> 。不具大小的抛出数组形式 <span class="t-v">(2,4)</span> 的标准库实现直接调用对应的单对象形式 <span class="t-v">(1,3)</span> 。</p>
|
|
<p>故而,替换抛出的单对象解分配函数 <span class="t-v">(1,3)</span> 足以处理所有解分配。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<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 <cstdio></span>
|
|
<span class="co2">#include <cstdlib></span>
|
|
<span class="co2">#include <new></span>
|
|
<span class="co1">// 最小函数集的替换:</span>
|
|
<span class="kw4">void</span><span class="sy2">*</span> <a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz<span class="br0">)</span> <span class="co1">// 无 inline ,由 [replacement.functions]/3 要求</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-c-fprintf.html"><span class="kw1843">std::<span class="me2">printf</span></span></a><span class="br0">(</span><span class="st0">"global op new called, size = %zu<span class="es1">\n</span>"</span>, sz<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>sz <span class="sy1">==</span> <span class="nu0">0</span><span class="br0">)</span>
|
|
<span class="sy2">++</span>sz<span class="sy4">;</span> <span class="co1">// 避免可能在成功时返回 nullptr 的 std::malloc(0)</span>
|
|
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">void</span> <span class="sy2">*</span>ptr <span class="sy1">=</span> <a href="cpp-memory-c-malloc.html"><span class="kw757">std::<span class="me2">malloc</span></span></a><span class="br0">(</span>sz<span class="br0">)</span><span class="br0">)</span>
|
|
<span class="kw1">return</span> ptr<span class="sy4">;</span>
|
|
|
|
<span class="kw1">throw</span> <a href="cpp-memory-new-bad_alloc.html"><span class="kw691">std::<span class="me2">bad_alloc</span></span></a><span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 由 [new.delete.single]/3 要求</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw4">void</span> operator delete<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> ptr<span class="br0">)</span> <span class="kw1">noexcept</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-c-puts.html"><span class="kw1828">std::<span class="me2">puts</span></span></a><span class="br0">(</span><span class="st0">"global op delete called"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-memory-c-free.html"><span class="kw761">std::<span class="me2">free</span></span></a><span class="br0">(</span>ptr<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> p1 <span class="sy1">=</span> new <span class="kw4">int</span><span class="sy4">;</span>
|
|
delete p1<span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span><span class="sy2">*</span> p2 <span class="sy1">=</span> new <span class="kw4">int</span><span class="br0">[</span><span class="nu0">10</span><span class="br0">]</span><span class="sy4">;</span> <span class="co1">// C++11 中保证调用替换</span>
|
|
delete<span class="br0">[</span><span class="br0">]</span> p2<span class="sy4">;</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">global op new called, size = 4
|
|
global op delete called
|
|
global op new called, size = 40
|
|
global op delete called</pre></div>
|
|
</div>
|
|
</div>
|
|
<p><code>operator delete</code> 与 <code>operator delete[]</code> 带额外用户定义参数的重载(“布置形式”, <span class="t-v">(15,16)</span> )可照常声明于全局作用域,而且为匹配的布置形式 <i>new 表达式</i> 所调用,若正在分配的对象的构造函数抛出异常。</p>
|
|
<p>operator delete 的标准库布置形式 <span class="t-v">(13,14)</span> 不能替换,而且仅若布置 new 表达式不使用 <code>::new</code> 语法才能被自定义,通过提供拥有匹配签名的类特定布置 delete <span class="t-v">(25,26)</span> : <code>void T::operator delete(void*, void*)</code> 或 <code>void T::operator delete[](void*, void*)</code> 。</p>
|
|
<h3><span class="mw-headline" id=".E7.B1.BB.E7.89.B9.E5.AE.9A.E9.87.8D.E8.BD.BD">类特定重载</span></h3>
|
|
<p>解分配函数 <span class="t-v">(17-24)</span> 可定义为类的静态成员函数。若提供这些解分配函数,则它们为 <a href="cpp-language-delete.html">delete 表达式</a>在删除此类的对象 <span class="t-v">(17,19,21)</span> 和数组 <span class="t-v">(18,20,22)</span> 时调用,除非 delete 表达式使用跳过类作用域查找的形式 <code>::delete</code> 。关键词 <code>static</code> 对这些函数声明是可选的:不管是否使用该关键词,解分配函数都始终是静态成员函数。</p>
|
|
<p>delete 表达式从类作用域开始查找适当的解分配函数名(数组形式在数组元素类的作用域查找),然后若找不到成员再继而照常寻找全局作用域。注意,同每个<a href="cpp-language-lookup.html">名称查找规则</a>,任何声明于类作用域的解分配函数隐藏所有全局解分配函数。</p>
|
|
<p>若正在删除的对象的静态类型异于其动态类型(例如通过指向基类的指针删除一个<a href="cpp-language-object.html">多态</a>对象),且若静态类型中的析构函数是虚的,则 delete 的单对象形式从其虚析构函数的最终覆盖者的定义点开始查找解分配函数的名称。无关乎运行时会执行哪个析构函数,为了能够编译, operator delete 的静态可见版本必须可访问。其他情况下,当通过指向基类的指针删除数组,或通过带非虚析构函数的指针删除时,行为未定义。</p>
|
|
<p>若未提供单参数重载 <span class="t-v">(17,18)</span> ,但提供接收 <code>std::size_t</code> 为第二参数的具大小重载 <span class="t-v">(21,22)</span> ,则正常解分配调用具大小形式,且 C++ 运行时传递要被解分配的对象大小为第二参数。若定义两种形式,则调用不具大小的版本。</p>
|
|
<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="co1">// 具大小的类特定解分配函数</span>
|
|
<span class="kw1">struct</span> X <span class="br0">{</span>
|
|
<span class="kw4">static</span> <span class="kw4">void</span> operator delete<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1756">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"custom delete for size "</span> <span class="sy1"><<</span> sz <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>ptr<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw4">static</span> <span class="kw4">void</span> operator delete<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> ptr, <a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1756">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"custom delete for size "</span> <span class="sy1"><<</span> sz <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>ptr<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</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>
|
|
X<span class="sy2">*</span> p1 <span class="sy1">=</span> new X<span class="sy4">;</span>
|
|
delete p1<span class="sy4">;</span>
|
|
X<span class="sy2">*</span> p2 <span class="sy1">=</span> new X<span class="br0">[</span><span class="nu0">10</span><span class="br0">]</span><span class="sy4">;</span>
|
|
delete<span class="br0">[</span><span class="br0">]</span> p2<span class="sy4">;</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">custom delete for size 1
|
|
custom delete for size 18</pre></div>
|
|
</div>
|
|
</div>
|
|
<p>带额外用户定义参数的 <code>operator delete</code> 与 <code>operator delete[]</code> (“布置形式”, <span class="t-v">(25,26)</span> )亦可定义为类成员。在失败的布置 new 表达式查找将调用的对应布置 delete 函数时,它首次从类作用域开始,在全局作用域之前查找,并且查找匹配布置 new 签名的函数:</p>
|
|
<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 <stdexcept></span>
|
|
<span class="co2">#include <iostream></span>
|
|
<span class="kw1">struct</span> X <span class="br0">{</span>
|
|
X<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">throw</span> <a href="cpp-error-runtime_error.html"><span class="kw768">std::<span class="me2">runtime_error</span></span></a><span class="br0">(</span><span class="st0">""</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="co1">// 自定义布置 new</span>
|
|
<span class="kw4">static</span> <span class="kw4">void</span><span class="sy2">*</span> <a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">(</span><a href="cpp-types-size_t.html"><span class="kw100">std::<span class="me2">size_t</span></span></a> sz, <span class="kw4">bool</span> b<span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1756">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"custom placement new called, b = "</span> <span class="sy1"><<</span> b <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="kw1">return</span> <span class="sy4">::</span><a href="cpp-memory-new-operator_new.html"><span class="kw687">operator new</span></a><span class="br0">(</span>sz<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="co1">// 自定义布置 delete</span>
|
|
<span class="kw4">static</span> <span class="kw4">void</span> operator delete<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> ptr, <span class="kw4">bool</span> b<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1756">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"custom placement delete called, b = "</span> <span class="sy1"><<</span> b <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="sy4">::</span><span class="me2">operator</span> delete<span class="br0">(</span>ptr<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</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>
|
|
<span class="kw1">try</span> <span class="br0">{</span>
|
|
X<span class="sy2">*</span> p1 <span class="sy1">=</span> new <span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span> X<span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">catch</span><span class="br0">(</span><span class="kw4">const</span> <a href="cpp-error-exception.html"><span class="kw762">std::<span class="me2">exception</span></span></a><span class="sy3">&</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</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">custom placement new called, b = 1
|
|
custom placement delete called, b = 1</pre></div>
|
|
</div>
|
|
</div>
|
|
<p>若类级别的 <code>operator delete</code> 是模板函数,则它必须拥有 <code>void</code> 返回类型,首参数 <code>void*</code> ,而且必须拥有二个或更多参数。换言之,只有布置形式能是模板。模板 operator delete 的特化为<a href="cpp-language-template_argument_deduction.html">模板参数推导</a>所选择。</p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>在多态类上调用类特定的 <code>T::operator delete</code> 是仅有的通过动态派发调用静态成员函数的情况。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>要求下列函数是线程安全的:</p>
|
|
<ul>
|
|
<li><a href="cpp-memory-new-operator_new.html"><tt>operator new</tt></a> 及 <strong class="selflink"><tt>operator delete</tt></strong> 的库版本</li>
|
|
<li>全局 <a href="cpp-memory-new-operator_new.html"><tt>operator new</tt></a> 与 <strong class="selflink"><tt>operator delete</tt></strong> 的用户替换版本</li>
|
|
<li><span class="t-lc"><a href="cpp-memory-c-calloc.html">std::calloc</a></span> 、 <span class="t-lc"><a href="cpp-memory-c-malloc.html">std::malloc</a></span> 、 <span class="t-lc"><a href="cpp-memory-c-realloc.html">std::realloc</a></span> <span class="t-rev-inl t-since-cxx17"><span>、 <span class="t-lc"><a href="cpp-memory-c-aligned_alloc.html">std::aligned_alloc</a></span></span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span> 、 <span class="t-lc"><a href="cpp-memory-c-free.html">std::free</a></span></li>
|
|
</ul>
|
|
<p>对这些分配或解分配特定存储单元的函数调用以单独全序出现,并且在此顺序中,每个解分配调用<a href="cpp-atomic-memory_order.html">先发生于</a>下个分配(若存在)。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<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://wg21.cmeerw.net/cwg/issue1438">CWG 1438</a></td>
|
|
<td>C++98</td>
|
|
<td>任何非法指针值的使用均为未定义行为</td>
|
|
<td>只有间接和解分配是</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://cplusplus.github.io/LWG/issue2458">LWG 2458</a></td>
|
|
<td>C++14</td>
|
|
<td>曾指定了接受 (void*,size_t,const nothrow_t&) 的重载,但它无法被调用</td>
|
|
<td>移除虚假重载</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-new-operator_new.html"><span class="t-lines"><span>operator new</span><span>operator new[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>分配函数<br />
|
|
<span class="t-mark">(函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-return_temporary_buffer.html"><span class="t-lines"><span>return_temporary_buffer</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-deprecated-cxx17">(C++17 中弃用)</span></span><span><span class="t-mark-rev t-until-cxx20">(C++20 中移除)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>释放未初始化存储<br />
|
|
<span class="t-mark">(函数模板)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-c-free.html"><span class="t-lines"><span>free</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>解分配之前分配的内存<br />
|
|
<span class="t-mark">(函数)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|