Files
hustoj/web/cppreference-zh/chmhelp/cpp-language-pimpl.html
2025-08-01 12:57:54 +08:00

196 lines
31 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>PImpl</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_language_pimpl skin-cppreference2 action-view cpp-navbar">
<div id="cpp-content-base">
<div id="content"><a id="top"></a>
<h1 id="firstHeading" class="firstHeading">PImpl</h1>
<div id="bodyContent">
<div id="contentSub"><span class="subpages">&lt; <a href="cpp.html">cpp</a>&lrm; | <a href="cpp-language.html">language</a></span></div>
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
<p>&ldquo;&#25351;&#21521;&#23454;&#29616;&#30340;&#25351;&#38024;&rdquo;&#25110;&ldquo;pImpl&rdquo;&#26159;&#19968;&#31181; C++ &#32534;&#31243;&#25216;&#24039;<sup id="cite_ref-1" class="reference"><a href="cpp-language-pimpl.html#cite_note-1">[1]</a></sup>&#65292;&#23427;&#23558;&#31867;&#30340;&#23454;&#29616;&#32454;&#33410;&#20174;&#23545;&#35937;&#34920;&#31034;&#20013;&#31227;&#38500;&#65292;&#25918;&#21040;&#19968;&#20010;&#20998;&#31163;&#30340;&#31867;&#20013;&#65292;&#24182;&#20197;&#19968;&#20010;&#19981;&#36879;&#26126;&#30340;&#25351;&#38024;&#36827;&#34892;&#35775;&#38382;&#65306;</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;">
<div class="cpp source-cpp">
<pre class="de1"><span class="co1">// widget.h&#65288;&#25509;&#21475;&#65289;</span>
<span class="kw1">class</span> widget <span class="br0">{</span>
<span class="co1">// &#20844;&#24320;&#25104;&#21592;</span>
<span class="kw1">private</span><span class="sy4">:</span>
<span class="kw1">struct</span> impl<span class="sy4">;</span> <span class="co1">// &#23454;&#29616;&#31867;&#30340;&#21069;&#32622;&#22768;&#26126;</span>
<span class="co1">// &#19968;&#31181;&#23454;&#29616;&#31034;&#20363;&#65306;&#35265;&#19979;&#25991;&#20013;&#30340;&#20854;&#20182;&#35774;&#35745;&#36873;&#39033;&#21644;&#26435;&#34913;</span>
<a href="cpp-experimental-propagate_const.html"><span class="kw2423">std::<span class="me2">experimental</span><span class="sy4">::</span><span class="me2">propagate_const</span></span></a><span class="sy1">&lt;</span> <span class="co1">// &#36716;&#21457; const &#30340;&#25351;&#38024;&#21253;&#35013;&#22120;</span>
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span> <span class="co1">// &#21807;&#19968;&#25152;&#26377;&#26435;&#30340;&#19981;&#36879;&#26126;&#25351;&#38024;</span>
impl<span class="sy1">&gt;&gt;</span> pImpl<span class="sy4">;</span> <span class="co1">// &#25351;&#21521;&#21069;&#32622;&#22768;&#26126;&#30340;&#23454;&#29616;&#31867;</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="co1">// widget.cpp&#65288;&#23454;&#29616;&#65289;</span>
<span class="kw1">struct</span> widget<span class="sy4">::</span><span class="me2">impl</span> <span class="br0">{</span>
<span class="co1">// &#23454;&#29616;&#32454;&#33410;</span>
<span class="br0">}</span><span class="sy4">;</span></pre></div>
</div>
<p>&#27492;&#25216;&#24039;&#29992;&#20110;&#26500;&#36896;&#25317;&#26377;&#31283;&#23450; ABI &#30340; C++ &#24211;&#25509;&#21475;&#65292;&#21450;&#20943;&#23569;&#32534;&#35793;&#26102;&#20381;&#36182;&#12290;</p>
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">&#35299;&#37322;</span></h3>
<p>&#22240;&#20026;&#31867;&#30340;&#31169;&#26377;&#25968;&#25454;&#25104;&#21592;&#21442;&#19982;&#20854;&#23545;&#35937;&#34920;&#31034;&#65292;&#24433;&#21709;&#22823;&#23567;&#21644;&#24067;&#23616;&#65292;&#20063;&#22240;&#20026;&#31867;&#30340;&#31169;&#26377;&#25104;&#21592;&#20989;&#25968;&#21442;&#19982;<a href="cpp-language-overload_resolution.html">&#37325;&#36733;&#20915;&#35758;</a>&#65288;&#36825;&#21457;&#29983;&#20110;&#25104;&#21592;&#35775;&#38382;&#26816;&#26597;&#20043;&#21069;&#65289;&#65292;&#25925;&#23545;&#23454;&#29616;&#32454;&#33410;&#30340;&#20219;&#20309;&#26356;&#25913;&#37117;&#35201;&#27714;&#35813;&#31867;&#30340;&#25152;&#26377;&#29992;&#25143;&#37325;&#32534;&#35793;&#12290;</p>
<p>pImpl &#25171;&#30772;&#20102;&#36825;&#31181;&#32534;&#35793;&#20381;&#36182;&#65307;&#23454;&#29616;&#30340;&#25913;&#21160;&#19981;&#20250;&#23548;&#33268;&#37325;&#32534;&#35793;&#12290;&#32467;&#26524;&#26159;&#65292;&#33509;&#26576;&#20010;&#24211;&#22312;&#20854; ABI &#20013;&#20351;&#29992; pImpl&#65292;&#21017;&#36825;&#20010;&#24211;&#30340;&#26032;&#29256;&#26412;&#21487;&#20197;&#26356;&#25913;&#23454;&#29616;&#65292;&#24182;&#19988;&#19982;&#26087;&#29256;&#26412;&#20445;&#25345; ABI &#20860;&#23481;&#12290;</p>
<h3><span class="mw-headline" id=".E5.BE.97.E5.A4.B1.E6.9D.83.E8.A1.A1">&#24471;&#22833;&#26435;&#34913;</span></h3>
<p>pImpl &#25216;&#27861;&#30340;&#26367;&#20195;&#26041;&#26696;&#26159;</p>
<ul>
<li>&#20869;&#32852;&#23454;&#29616;&#65306;&#31169;&#26377;&#25104;&#21592;&#21644;&#20844;&#24320;&#25104;&#21592;&#26159;&#21516;&#19968;&#31867;&#30340;&#25104;&#21592;</li>
<li>&#32431;&#34394;&#31867;&#65288;OOP &#24037;&#21378;&#65289;&#65306;&#29992;&#25143;&#33719;&#24471;&#21040;&#26576;&#20010;&#36731;&#37327;&#32423;&#25110;&#32431;&#34394;&#30340;&#22522;&#31867;&#30340;&#21807;&#19968;&#25351;&#38024;&#65292;&#23454;&#29616;&#32454;&#33410;&#21017;&#22788;&#20110;&#35206;&#30422;&#20854;&#34394;&#25104;&#21592;&#20989;&#25968;&#30340;&#27966;&#29983;&#31867;&#20013;&#12290;</li>
</ul>
<h4><span class="mw-headline" id=".E7.BC.96.E8.AF.91.E9.98.B2.E7.81.AB.E5.A2.99">&#32534;&#35793;&#38450;&#28779;&#22681;</span></h4>
<p>&#31616;&#21333;&#24773;&#20917;&#19979;&#65292;pImpl &#21644;&#24037;&#21378;&#26041;&#27861;&#37117;&#20250;&#25171;&#30772;&#23454;&#29616;&#21644;&#31867;&#25509;&#21475;&#30340;&#29992;&#25143;&#20043;&#38388;&#30340;&#32534;&#35793;&#26102;&#20381;&#36182;&#12290;&#24037;&#21378;&#26041;&#27861;&#21019;&#24314;&#23545;&#34394;&#34920;&#30340;&#19968;&#27425;&#38544;&#34255;&#20381;&#36182;&#65292;&#25925;&#32780;&#23545;&#34394;&#20989;&#25968;&#36827;&#34892;&#37325;&#25490;&#24207;&#12289;&#28155;&#21152;&#25110;&#31227;&#38500;&#37117;&#20250;&#25171;&#30772; ABI&#12290;pImpl &#26041;&#27861;&#21017;&#27809;&#26377;&#38544;&#34255;&#30340;&#20381;&#36182;&#65292;&#28982;&#32780;&#33509;&#23454;&#29616;&#31867;&#26159;&#31867;&#27169;&#26495;&#29305;&#21270;&#65292;&#21017;&#20250;&#20007;&#22833;&#32534;&#35793;&#38450;&#28779;&#22681;&#30340;&#20248;&#21183;&#65306;&#25509;&#21475;&#30340;&#29992;&#25143;&#24517;&#39035;&#35266;&#27979;&#21040;&#25972;&#20010;&#27169;&#26495;&#23450;&#20041;&#65292;&#20197;&#23454;&#20363;&#21270;&#27491;&#30830;&#30340;&#29305;&#21270;&#12290;&#36825;&#31181;&#24773;&#20917;&#19979;&#30340;&#19968;&#31181;&#24120;&#35265;&#30340;&#35774;&#35745;&#26041;&#26696;&#26159;&#65292;&#20197;&#36991;&#20813;&#21442;&#25968;&#21270;&#30340;&#26041;&#24335;&#23545;&#23454;&#29616;&#36827;&#34892;&#37325;&#26500;&#65292;&#36825;&#26159;&#12298;C++ &#26680;&#24515;&#25351;&#21335;&#12299;&#30340; <a rel="nofollow" class="external text" href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rt-scary">T.61 &#21247;&#36807;&#20998;&#21442;&#25968;&#21270;&#25104;&#21592;</a> &#21644; <a rel="nofollow" class="external text" href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#t84-use-a-non-template-core-implementation-to-provide-an-abi-stable-interface">T.84 &#20351;&#29992;&#38750;&#27169;&#26495;&#26680;&#24515;&#23454;&#29616;&#20197;&#25552;&#20379; ABI &#31283;&#23450;&#30340;&#25509;&#21475;</a> &#30340;&#21478;&#19968;&#31181;&#20351;&#29992;&#24773;&#20917;&#12290;</p>
<p>&#20030;&#20363;&#26469;&#35828;&#65292;&#20197;&#19979;&#30340;&#31867;&#27169;&#26495;&#22312;&#20854;&#31169;&#26377;&#25104;&#21592;&#25110; push_back &#20989;&#25968;&#20307;&#20869;&#24182;&#26410;&#20351;&#29992;&#31867;&#22411; T</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;">
<div class="cpp source-cpp">
<pre class="de1"><span class="kw1">template</span><span class="sy1">&lt;</span><span class="kw1">class</span> T<span class="sy1">&gt;</span>
<span class="kw1">class</span> ptr_vector <span class="br0">{</span>
<span class="kw4">void</span> <span class="sy2">**</span>beg, <span class="sy2">**</span>end, <span class="sy2">**</span>cap<span class="sy4">;</span>
<span class="kw1">public</span><span class="sy4">:</span>
<span class="kw4">void</span> push_back<span class="br0">(</span>T<span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span>
<span class="kw1">if</span> <span class="br0">(</span>end <span class="sy1">==</span> cap<span class="br0">)</span> reallocate<span class="br0">(</span>end <span class="sy2">-</span> beg <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span>
<span class="sy2">*</span>end<span class="sy2">++</span> <span class="sy1">=</span> p<span class="sy4">;</span>
<span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span></pre></div>
</div>
<p>&#22240;&#27492;&#65292;&#33021;&#25353;&#21407;&#26679;&#25226;&#31169;&#26377;&#25104;&#21592;&#20256;&#36882;&#32473;&#23454;&#29616;&#65292;&#32780;&#19988; push_back &#21487;&#20197;&#36716;&#21457;&#21040;&#21516;&#26679;&#26410;&#22312;&#25509;&#21475;&#20351;&#29992; T &#30340;&#23454;&#29616;&#65306;</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;">
<div class="cpp source-cpp">
<pre class="de1"><span class="co1">// &#22836;&#25991;&#20214;&#65288;ptr_vector.h&#65289;</span>
<span class="kw1">class</span> ptr_vector_base <span class="br0">{</span>
<span class="kw1">struct</span> impl<span class="sy4">;</span> <span class="co1">// &#19981;&#20381;&#36182; T</span>
<a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span> pImpl<span class="sy4">;</span>
<span class="kw1">protected</span><span class="sy4">:</span>
<span class="kw4">void</span> push_back_fwd<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span><span class="br0">)</span><span class="sy4">;</span>
... <span class="co1">// &#35265;&#29305;&#27530;&#25104;&#21592;&#20989;&#25968;&#30340;&#23454;&#29616;&#37096;&#20998;</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="kw1">template</span><span class="sy1">&lt;</span><span class="kw1">class</span> T<span class="sy1">&gt;</span>
<span class="kw1">class</span> ptr_vector <span class="sy4">:</span> <span class="kw1">private</span> ptr_vector_base <span class="br0">{</span>
<span class="kw1">public</span><span class="sy4">:</span>
<span class="kw4">void</span> push_back<span class="br0">(</span>T<span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span> push_back_fwd<span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="co1">// &#28304;&#25991;&#20214;&#65288;ptr_vector.cpp&#65289;</span>
<span class="kw1">struct</span> ptr_vector_base<span class="sy4">::</span><span class="me2">impl</span> <span class="br0">{</span>
<span class="kw4">void</span> <span class="sy2">**</span>beg, <span class="sy2">**</span>end, <span class="sy2">**</span>cap<span class="sy4">;</span>
<span class="kw4">void</span> push_back<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span>
<span class="kw1">if</span> <span class="br0">(</span>end <span class="sy1">==</span> cap<span class="br0">)</span> reallocate<span class="br0">(</span>end <span class="sy2">-</span> beg <span class="sy2">+</span> <span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span>
<span class="sy2">*</span>end<span class="sy2">++</span> <span class="sy1">=</span> p<span class="sy4">;</span>
<span class="br0">}</span>
<span class="kw4">void</span> reallocate<span class="br0">(</span>size_t sz<span class="br0">)</span> <span class="br0">{</span> ... <span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="kw4">void</span> ptr_vector_base<span class="sy4">::</span><span class="me2">push_back_fwd</span><span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>push_back<span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
ptr_vector_base<span class="sy4">::</span><span class="me2">ptr_vector_base</span><span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> pImpl<span class="br0">(</span><a href="cpp-memory-unique_ptr-make_unique.html"><span class="kw735">std::<span class="me2">make_unique</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span></pre></div>
</div>
<h4><span class="mw-headline" id=".E8.BF.90.E8.A1.8C.E6.97.B6.E5.BC.80.E9.94.80">&#36816;&#34892;&#26102;&#24320;&#38144;</span></h4>
<ul>
<li>&#35775;&#38382;&#24320;&#38144;&#65306;pImpl &#20013;&#65292;&#27599;&#27425;&#23545;&#31169;&#26377;&#25104;&#21592;&#20989;&#25968;&#30340;&#35843;&#29992;&#37117;&#36890;&#36807;&#19968;&#20010;&#25351;&#38024;&#38388;&#25509;&#36827;&#34892;&#12290;&#31169;&#26377;&#25104;&#21592;&#23545;&#20844;&#24320;&#25104;&#21592;&#30340;&#27599;&#27425;&#35775;&#38382;&#20063;&#37117;&#36890;&#36807;&#21478;&#19968;&#20010;&#25351;&#38024;&#38388;&#25509;&#36827;&#34892;&#12290;&#20004;&#20010;&#35775;&#38382;&#37117;&#36328;&#32763;&#35793;&#21333;&#20803;&#36793;&#30028;&#65292;&#20174;&#32780;&#21482;&#33021;&#34987;&#36830;&#25509;&#26102;&#20248;&#21270;&#20248;&#21270;&#25481;&#12290;&#27880;&#24847; OO &#24037;&#21378;&#23545;&#20844;&#24320;&#25968;&#25454;&#21644;&#23454;&#29616;&#32454;&#33410;&#30340;&#35775;&#38382;&#37117;&#35201;&#27714;&#36328;&#32763;&#35793;&#21333;&#20803;&#38388;&#25509;&#36827;&#34892;&#65292;&#32780;&#19988;&#30001;&#20110;&#34394;&#27966;&#21457;&#32780;&#32473;&#20104;&#36830;&#25509;&#26102;&#20248;&#21270;&#22120;&#26356;&#23569;&#30340;&#26426;&#20250;&#12290;</li>
<li>&#31354;&#38388;&#24320;&#38144;&#65306;pImpl &#28155;&#21152;&#19968;&#20010;&#25351;&#38024;&#21040;&#20844;&#24320;&#32452;&#20998;&#65292;&#24182;&#19988;&#33509;&#26377;&#20219;&#20309;&#31169;&#26377;&#25104;&#21592;&#38656;&#35201;&#35775;&#38382;&#20844;&#24320;&#25104;&#21592;&#65292;&#21017;&#35201;&#20040;&#28155;&#21152;&#21478;&#19968;&#20010;&#25351;&#38024;&#21040;&#23454;&#29616;&#32452;&#20998;&#65292;&#35201;&#20040;&#27599;&#27425;&#35843;&#29992;&#35201;&#27714;&#23427;&#30340;&#31169;&#26377;&#25104;&#21592;&#26102;&#20316;&#20026;&#21442;&#25968;&#20256;&#36882;&#12290;&#33509;&#25903;&#25345;&#26377;&#29366;&#24577;&#33258;&#23450;&#20041;&#20998;&#37197;&#22120;&#65292;&#21017;&#24517;&#39035;&#19968;&#21516;&#23384;&#20648;&#20998;&#37197;&#22120;&#23454;&#20363;&#12290;</li>
<li>&#29983;&#23384;&#26399;&#31649;&#29702;&#24320;&#38144;&#65306;pImpl&#65288;&#36824;&#26377; OO &#24037;&#21378;&#65289;&#23558;&#23454;&#29616;&#23545;&#35937;&#25918;&#22312;&#22534;&#19978;&#65292;&#36825;&#22312;&#26500;&#36896;&#19982;&#38144;&#27585;&#26102;&#24378;&#21152;&#20102;&#26174;&#33879;&#30340;&#36816;&#34892;&#26102;&#24320;&#38144;&#12290;&#36825;&#21487;&#20197;&#37096;&#20998;&#22320;&#30001;&#33258;&#23450;&#20041;&#20998;&#37197;&#22120;&#25152;&#24357;&#34917;&#65292;&#22240;&#20026; pImpl&#65288;&#20294;&#38750; OO &#24037;&#21378;&#65289;&#30340;&#22823;&#23567;&#22312;&#32534;&#35793;&#26102;&#26159;&#24050;&#30693;&#30340;&#12290;</li>
</ul>
<p>&#21478;&#19968;&#26041;&#38754;&#65292;pImpl &#31867;&#26159;&#23545;&#31227;&#21160;&#21451;&#22909;&#30340;&#65307;&#25226;&#22823;&#22411;&#30340;&#31867;&#37325;&#26500;&#20026;&#21487;&#31227;&#21160; pImpl&#65292;&#21487;&#20197;&#25552;&#21319;&#23545;&#20445;&#26377;&#36825;&#20123;&#23545;&#35937;&#30340;&#23481;&#22120;&#36827;&#34892;&#25805;&#20316;&#30340;&#31639;&#27861;&#24615;&#33021;&#65292;&#21363;&#20415;&#21487;&#31227;&#21160; pImpl &#20063;&#20855;&#26377;&#39069;&#22806;&#30340;&#36816;&#34892;&#26102;&#24320;&#38144;&#65306;&#20219;&#20309;&#22312;&#34987;&#31227;&#21160;&#23545;&#35937;&#19978;&#23481;&#35768;&#20351;&#29992;&#24182;&#38656;&#35201;&#35775;&#38382;&#31169;&#26377;&#23454;&#29616;&#30340;&#20844;&#24320;&#25104;&#21592;&#20989;&#25968;&#24517;&#39035;&#36827;&#34892;&#31354;&#25351;&#38024;&#26816;&#26597;&#12290;</p>
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
<tr>
<td class="mbox-empty-cell"></td>
<td class="mbox-text" style="">&#26412;&#33410;&#26410;&#23436;&#25104;<br />
&#21407;&#22240;&#65306;&#24494;&#22522;&#20934;&#27979;&#35797;&#65311;)</td>
</tr>
</table>
<h4><span class="mw-headline" id=".E7.BB.B4.E6.8A.A4.E5.BC.80.E9.94.80">&#32500;&#25252;&#24320;&#38144;</span></h4>
<p>pImpl &#30340;&#20351;&#29992;&#35201;&#27714;&#19987;&#29992;&#30340;&#32763;&#35793;&#21333;&#20803;&#65288;&#21482;&#26377;&#22836;&#25991;&#20214;&#30340;&#24211;&#26080;&#27861;&#20351;&#29992; pImpl&#65289;&#65292;&#24341;&#20837;&#19968;&#20010;&#39069;&#22806;&#31867;&#65292;&#19968;&#32452;&#36716;&#21457;&#20989;&#25968;&#65292;&#19988;&#24403;&#20351;&#29992;&#20998;&#37197;&#22120;&#26102;&#65292;&#20250;&#26292;&#38706;&#20844;&#24320;&#25509;&#21475;&#25152;&#20351;&#29992;&#30340;&#20998;&#37197;&#22120;&#30340;&#32454;&#33410;&#12290;</p>
<p>&#22240;&#20026;&#34394;&#25104;&#21592;&#26159; pImpl &#30340;&#25509;&#21475;&#32452;&#20998;&#30340;&#19968;&#37096;&#20998;&#65292;&#25925;&#27169;&#25311; pImpl &#24847;&#21619;&#30528;&#21333;&#29420;&#27169;&#25311;&#25509;&#21475;&#32452;&#20998;&#12290;&#21487;&#27979;&#35797;&#30340; pImpl &#20856;&#22411;&#22320;&#34987;&#35774;&#35745;&#20026;&#20801;&#35768;&#36890;&#36807;&#21487;&#29992;&#25509;&#21475;&#36798;&#25104;&#23436;&#25972;&#30340;&#27979;&#35797;&#35206;&#30422;&#12290;</p>
<h3><span class="mw-headline" id=".E5.AE.9E.E7.8E.B0">&#23454;&#29616;</span></h3>
<p>&#30001;&#20110;&#25509;&#21475;&#31867;&#22411;&#30340;&#23545;&#35937;&#25511;&#21046;&#23454;&#29616;&#31867;&#22411;&#23545;&#35937;&#30340;&#29983;&#23384;&#26399;&#65292;&#25351;&#21521;&#23454;&#29616;&#30340;&#25351;&#38024;&#36890;&#24120;&#26159; <span class="t-lc"><a href="cpp-memory-unique_ptr.html">std::unique_ptr</a></span>&#12290;</p>
<p>&#22240;&#20026; <span class="t-lc"><a href="cpp-memory-unique_ptr.html">std::unique_ptr</a></span> &#35201;&#27714;&#34987;&#25351;&#21521;&#31867;&#22411;&#22312;&#20219;&#20309;&#23454;&#20363;&#21270;&#21024;&#38500;&#22120;&#30340;&#35821;&#22659;&#20013;&#22343;&#20026;&#23436;&#25972;&#31867;&#22411;&#65292;&#25925;&#29305;&#27530;&#25104;&#21592;&#20989;&#25968;&#24517;&#39035;&#20026;&#29992;&#25143;&#22768;&#26126;&#65292;&#19988;&#22312;&#23454;&#29616;&#31867;&#20026;&#23436;&#25972;&#30340;&#23454;&#29616;&#25991;&#20214;&#20013;&#31867;&#22806;&#23450;&#20041;&#12290;</p>
<p>&#22240;&#20026;&#24403; const &#25104;&#21592;&#36890;&#36807;&#38750; const &#25104;&#21592;&#25351;&#38024;&#35843;&#29992;&#20989;&#25968;&#26102;&#20250;&#35843;&#29992;&#23454;&#29616;&#20989;&#25968;&#30340;&#38750; const &#37325;&#36733;&#65292;&#25925;&#35813;&#25351;&#38024;&#24517;&#39035;&#21253;&#35013;&#20110; <span class="t-lc"><a href="cpp-experimental-propagate_const.html">std::experimental::propagate_const</a></span> &#25110;&#31561;&#20215;&#29289;&#20013;&#12290;</p>
<p>&#23558;&#25152;&#26377;&#31169;&#26377;&#25968;&#25454;&#25104;&#21592;&#21644;&#25152;&#26377;&#31169;&#26377;&#38750;&#34394;&#25104;&#21592;&#20989;&#25968;&#32622;&#20110;&#23454;&#29616;&#31867;&#20013;&#12290;&#23558;&#25152;&#26377;&#20844;&#24320;&#12289;&#21463;&#20445;&#25252;&#21644;&#34394;&#25104;&#21592;&#30041;&#20110;&#25509;&#21475;&#31867;&#20013;&#65288;&#23545;&#26367;&#20195;&#26041;&#26696;&#30340;&#35752;&#35770;&#35265; <a rel="nofollow" class="external text" href="http://herbsutter.com/gotw/_100/">GOTW #100</a>&#65289;&#12290;</p>
<p>&#33509;&#20219;&#20309;&#31169;&#26377;&#25104;&#21592;&#38656;&#35201;&#35775;&#38382;&#20844;&#24320;&#25110;&#21463;&#20445;&#25252;&#25104;&#21592;&#65292;&#21017;&#21487;&#20197;&#23558;&#25351;&#21521;&#25509;&#21475;&#30340;&#24341;&#29992;&#25110;&#25351;&#38024;&#20316;&#20026;&#21442;&#25968;&#20256;&#36882;&#32473;&#31169;&#26377;&#20989;&#25968;&#12290;&#21478;&#22806;&#65292;&#20063;&#21487;&#20197;&#23558;&#22238;&#28335;&#24341;&#29992;&#20316;&#20026;&#23454;&#29616;&#31867;&#30340;&#19968;&#37096;&#20998;&#32500;&#25345;&#12290;</p>
<p>&#33509;&#26377;&#24847;&#20351;&#29992;&#38750;&#40664;&#35748;&#20998;&#37197;&#22120;&#20197;&#25903;&#25345;&#23454;&#29616;&#23545;&#35937;&#30340;&#20998;&#37197;&#65292;&#21017;&#21487;&#20197;&#21033;&#29992;&#20219;&#20309;&#24120;&#29992;&#30340;&#20855;&#20998;&#37197;&#22120;&#27169;&#24335;&#65292;&#21253;&#25324;&#32570;&#30465;&#20026; <span class="t-lc"><a href="cpp-memory-allocator.html">std::allocator</a></span> &#30340;&#20998;&#37197;&#22120;&#27169;&#26495;&#24418;&#21442;&#65292;&#20197;&#21450;&#31867;&#22411;&#20026; <a href="cpp-memory-memory_resource.html"><tt>std::pmr::memory_resource*</tt></a> &#30340;&#26500;&#36896;&#20989;&#25968;&#23454;&#21442;&#12290;</p>
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">&#31034;&#20363;</span></h3>
<div class="t-example">
<p>&#28436;&#31034;&#24102;&#26377; const_propagation &#30340; pImpl&#65292;&#24102;&#26377;&#20316;&#20026;&#21442;&#25968;&#20256;&#36882;&#30340;&#22238;&#28335;&#24341;&#29992;&#65292;&#19981;&#20855;&#20998;&#37197;&#22120;&#65292;&#24182;&#21551;&#29992;&#19981;&#24102;&#36816;&#34892;&#26102;&#26816;&#26597;&#30340;&#31227;&#21160;</p>
<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 &lt;iostream&gt;</span>
<span class="co2">#include &lt;memory&gt;</span>
<span class="co2">#include &lt;experimental/propagate_const&gt;</span>
<span class="co1">// &#25509;&#21475;&#65288;widget.h&#65289;</span>
<span class="kw1">class</span> widget <span class="br0">{</span>
<span class="kw1">class</span> impl<span class="sy4">;</span>
<a href="cpp-experimental-propagate_const.html"><span class="kw2423">std::<span class="me2">experimental</span><span class="sy4">::</span><span class="me2">propagate_const</span></span></a><span class="sy1">&lt;</span><a href="cpp-memory-unique_ptr.html"><span class="kw733">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;&gt;</span> pImpl<span class="sy4">;</span>
<span class="kw1">public</span><span class="sy4">:</span>
<span class="kw4">void</span> draw<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span><span class="sy4">;</span> <span class="co1">// &#20844;&#24320; API&#65292;&#23558;&#34987;&#36716;&#21457;&#32473;&#23454;&#29616;</span>
<span class="kw4">void</span> draw<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
<span class="kw4">bool</span> shown<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">// &#20844;&#24320; API&#65292;&#23454;&#29616;&#24517;&#39035;&#35843;&#29992;&#20043;</span>
widget<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span>
~widget<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// &#23450;&#20041;&#20110;&#23454;&#29616;&#25991;&#20214;&#65292;&#20854;&#20013; impl &#26159;&#23436;&#25972;&#31867;&#22411;</span>
widget<span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// &#23450;&#20041;&#20110;&#23454;&#29616;&#25991;&#20214; </span>
<span class="co1">// &#27880;&#24847;&#65306;&#22312;&#34987;&#31227;&#21160;&#30340;&#23545;&#35937;&#19978;&#35843;&#29992; draw() &#26159; UB</span>
widget<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span><span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span>
widget<span class="sy3">&amp;</span> operator<span class="sy1">=</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// &#23450;&#20041;&#20110;&#23454;&#29616;&#25991;&#20214;</span>
widget<span class="sy3">&amp;</span> operator<span class="sy1">=</span><span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span><span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="co1">// &#23454;&#29616;&#65288;widget.cpp&#65289;</span>
<span class="kw1">class</span> widget<span class="sy4">::</span><span class="me2">impl</span> <span class="br0">{</span>
<span class="kw4">int</span> n<span class="sy4">;</span> <span class="co1">// &#31169;&#26377;&#25968;&#25454;</span>
<span class="kw1">public</span><span class="sy4">:</span>
<span class="kw4">void</span> draw<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span> w<span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span>
<span class="kw1">if</span><span class="br0">(</span>w.<span class="me1">shown</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="co1">// &#23545;&#20844;&#24320;&#25104;&#21592;&#20989;&#25968;&#30340;&#27492;&#35843;&#29992;&#35201;&#27714;&#22238;&#28335;&#24341;&#29992;</span>
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1">&lt;&lt;</span> <span class="st0">&quot;drawing a const widget &quot;</span> <span class="sy1">&lt;&lt;</span> n <span class="sy1">&lt;&lt;</span> <span class="st0">&#39;<span class="es1">\n</span>&#39;</span><span class="sy4">;</span>
<span class="br0">}</span>
<span class="kw4">void</span> draw<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span> w<span class="br0">)</span> <span class="br0">{</span>
<span class="kw1">if</span><span class="br0">(</span>w.<span class="me1">shown</span><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">&lt;&lt;</span> <span class="st0">&quot;drawing a non-const widget &quot;</span> <span class="sy1">&lt;&lt;</span> n <span class="sy1">&lt;&lt;</span> <span class="st0">&#39;<span class="es1">\n</span>&#39;</span><span class="sy4">;</span>
<span class="br0">}</span>
impl<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span>n<span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
<span class="kw4">void</span> widget<span class="sy4">::</span><span class="me2">draw</span><span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>draw<span class="br0">(</span><span class="sy2">*</span>this<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
<span class="kw4">void</span> widget<span class="sy4">::</span><span class="me2">draw</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>draw<span class="br0">(</span><span class="sy2">*</span>this<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
widget<span class="sy4">::</span><span class="me2">widget</span><span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="sy4">:</span> pImpl<span class="br0">{</span><a href="cpp-memory-unique_ptr-make_unique.html"><span class="kw735">std::<span class="me2">make_unique</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span><span class="br0">(</span>n<span class="br0">)</span><span class="br0">}</span> <span class="br0">{</span><span class="br0">}</span>
widget<span class="sy4">::</span><span class="me2">widget</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
widget<span class="sy4">::</span>~widget<span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
widget<span class="sy3">&amp;</span> widget<span class="sy4">::</span><span class="me2">operator</span><span class="sy1">=</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
<span class="co1">// &#29992;&#25143;&#65288;main.cpp&#65289;</span>
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
<span class="br0">{</span>
widget w<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span><span class="sy4">;</span>
<span class="kw4">const</span> widget w2<span class="br0">(</span><span class="nu0">8</span><span class="br0">)</span><span class="sy4">;</span>
w.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
w2.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
<span class="br0">}</span></pre></div>
</div>
<p>&#36755;&#20986;&#65306;</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;">
<div class="text source-text">
<pre class="de1">drawing a non-const widget 7
drawing a const widget 8</pre></div>
</div>
</div>
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">&#27880;&#35299;</span></h3>
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
<tr>
<td class="mbox-empty-cell"></td>
<td class="mbox-text" style="">&#26412;&#33410;&#26410;&#23436;&#25104;<br />
&#21407;&#22240;&#65306;&#27880;&#24847;&#36830;&#25509;&#21040;&#20540;&#35821;&#20041;&#22810;&#24577;</td>
</tr>
</table>
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">&#24341;&#29992;</span></h3>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="cpp-language-pimpl.html#cite_ref-1">&uarr;</a></span> <span class="reference-text"><a rel="nofollow" class="external text" href="http://herbsutter.com/gotw/_100/">GotW #100</a>&#65306;&#32534;&#35793;&#38450;&#28779;&#22681;</span></li>
</ol>
</div>
<div class="visualClear"></div>
</div>
</div>
</div>
</body>
</html>