267 lines
32 KiB
HTML
267 lines
32 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>访问说明符</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_access skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">访问说明符</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <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>在 <a href="cpp-language-class.html">class/struct</a> 或 <a href="cpp-language-union.html">union</a> 的 <span class="t-spar">成员说明</span> 中定义其后继成员的可访问性。</p>
|
|
<p>在<a href="cpp-language-derived_class.html">派生类</a>声明的 <span class="t-spar">基类说明符</span> 中定义继承自其后继的基类的成员的可访问性。</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>public</b></code> <code><b>:</b></code> <span class="t-spar">成员说明</span></td>
|
|
<td>(1)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>protected</b></code> <code><b>:</b></code> <span class="t-spar">成员说明</span></td>
|
|
<td>(2)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>private</b></code> <code><b>:</b></code> <span class="t-spar">成员说明</span></td>
|
|
<td>(3)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">public</span></span></span> <span class="t-spar">基类</span></td>
|
|
<td>(4)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">protected</span></span></span> <span class="t-spar">基类</span></td>
|
|
<td>(5)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">private</span></span></span> <span class="t-spar">基类</span></td>
|
|
<td>(6)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 该访问说明符之后的各个成员具有公开成员访问</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 该访问说明符之后的各个成员具有受保护成员访问</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 该访问说明符之后的各个成员具有私有成员访问</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> <a href="cpp-language-derived_class.html#.E5.85.AC.E5.BC.80.E7.BB.A7.E6.89.BF">公开继承</a>:该访问说明符之后列出的<a href="cpp-language-derived_class.html">基类</a>的公开和受保护成员在派生类中保持其成员访问,而基类的私有成员对派生类不可访问</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> <a href="cpp-language-derived_class.html#.E5.8F.97.E4.BF.9D.E6.8A.A4.E7.BB.A7.E6.89.BF">受保护继承</a>:该访问说明符之后列出的<a href="cpp-language-derived_class.html">基类</a>的公开和受保护成员在派生类中是受保护成员,而基类的私有成员对派生类不可访问</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> <a href="cpp-language-derived_class.html#.E7.A7.81.E6.9C.89.E7.BB.A7.E6.89.BF">私有继承</a>:该访问说明符之后列出的<a href="cpp-language-derived_class.html">基类</a>的公开和受保护成员在派生类中是私有成员,而基类的私有成员对派生类不可访问</div>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>每个<a href="cpp-language-class.html">类</a>成员(静态、非静态、函数、类型等)的名字都具有与其关联的“成员访问”。在程序的任何位置使用成员的名字时都会检查其访问,而且如果它不满足访问规则,那么程序不能编译:</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="kw1">class</span> Example <span class="br0">{</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span> <span class="co1">// 此点后的所有声明都是公开的</span>
|
|
<span class="kw4">void</span> add<span class="br0">(</span><span class="kw4">int</span> x<span class="br0">)</span> <span class="br0">{</span> <span class="co1">// 成员 "add" 具有公开访问</span>
|
|
n <span class="sy2">+</span><span class="sy1">=</span> x<span class="sy4">;</span> <span class="co1">// OK:从 Example::add 可以访问私有的 Example::n</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw1">private</span><span class="sy4">:</span> <span class="co1">// 此点后的所有声明都是私有的</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> <span class="co1">// 成员 "n" 具有私有访问</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>
|
|
Example e<span class="sy4">;</span>
|
|
e.<span class="me1">add</span><span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK:从 main 可以访问公开的 Example::add</span>
|
|
<span class="co1">// e.n = 7; // 错误:从 main 不能访问私有的 Example::n</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<p>访问说明符给予类作者决定哪些类成员能被类的用户所访问(即类的<i>接口</i>),而哪些成员用于内部使用(即其<i>实现</i>)的能力。</p>
|
|
<h3><span class="mw-headline" id=".E7.BB.86.E8.8A.82">细节</span></h3>
|
|
<p>类的所有成员(<a href="cpp-language-member_functions.html">成员函数</a>体,成员对象的初始化器,以及整个<a href="cpp-language-nested_types.html">嵌套类定义</a>),都拥有对类所能访问的所有名字的访问权。成员函数内的局部类拥有对成员函数所能访问的所有名字的访问权。</p>
|
|
<p>以关键词 <code>class</code> 定义的类,其成员和其基类默认具有私有访问。以关键词 <code>struct</code> 定义的类,其成员和其基类默认具有公开访问。<a href="cpp-language-union.html">union</a> 的成员默认具有公开访问。</p>
|
|
<p>如果要向其他函数或类授予对受保护或私有成员的访问权,可以使用<a href="cpp-language-friend.html">友元声明</a>。</p>
|
|
<p>可访问性应用到所有名字,而不考虑其来源,因此受检查的是以 <a href="cpp-language-typedef.html">typedef</a> 或 <a href="cpp-language-using_declaration.html">using 声明</a>引入的名字,而非其所指涉的名字:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> A <span class="sy4">:</span> X <span class="br0">{</span>
|
|
<span class="kw1">class</span> B <span class="br0">{</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 在 A 中,B 是私有的</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span>
|
|
<span class="kw1">typedef</span> B BB<span class="sy4">;</span> <span class="co1">// 在 A 中,BB 是公开的</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
A<span class="sy4">::</span><span class="me2">B</span> y<span class="sy4">;</span> <span class="co1">// 错误:A::B 是私有的</span>
|
|
A<span class="sy4">::</span><span class="me2">BB</span> x<span class="sy4">;</span> <span class="co1">// OK:A::BB 是公开的</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>成员访问不影响可见性:私有和私有继承的成员对重载决议可见并被其考虑,到不可访问基类的隐式转换也仍被考虑,等等。成员访问检查是对任何给定语言构造进行解释之后的最后一步。此规则的目的是使得以 <code>public</code> 替换任何 <code>private</code> 时始终不会改变程序的行为。</p>
|
|
<p>对于<a href="cpp-language-default_arguments.html">默认函数实参</a>中以及默认<a href="cpp-language-template_parameters.html#.E9.BB.98.E8.AE.A4.E6.A8.A1.E6.9D.BF.E5.AE.9E.E5.8F.82">模板形参</a>中所使用的名字的访问检查,在声明点而非在使用点进行。</p>
|
|
<p>对<a href="cpp-language-virtual.html">虚函数</a>的名字的访问规则,在调用点,使用(用于代表调用该成员函数的对象的)表达式的类型进行检查。忽略最终覆盖函数的访问:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> B <span class="br0">{</span> <span class="kw1">virtual</span> <span class="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 在 B 中,f 是公开的</span>
|
|
<span class="kw1">class</span> D <span class="sy4">:</span> <span class="kw1">public</span> B <span class="br0">{</span> <span class="kw1">private</span><span class="sy4">:</span> <span class="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 在 D 中,f 是私有的</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
D d<span class="sy4">;</span>
|
|
B<span class="sy3">&</span> b <span class="sy1">=</span> d<span class="sy4">;</span>
|
|
b.<span class="me1">f</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK:B::f() 是公开的,调用 D::f(),即使它是私有的</span>
|
|
d.<span class="me1">f</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 错误:D::f() 是私有的</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>根据无限定<a href="cpp-language-lookup.html">名字查找</a>为私有的名字,有可能通过有限定名字查找访问:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> A <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">class</span> B <span class="sy4">:</span> <span class="kw1">private</span> A <span class="br0">{</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">class</span> C <span class="sy4">:</span> <span class="kw1">public</span> B <span class="br0">{</span>
|
|
A<span class="sy2">*</span> p<span class="sy4">;</span> <span class="co1">// 错误:无限定名字查找找到作为 B 的私有基类的 A</span>
|
|
<span class="sy4">::</span><span class="me2">A</span><span class="sy2">*</span> q<span class="sy4">;</span> <span class="co1">// OK:有限定名字查找找到命名空间层级的声明</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p>如果一个名字可以通过继承图中多条路径访问,那么它的访问是所有路径中带最大访问的路径的访问:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> W <span class="br0">{</span> <span class="kw1">public</span><span class="sy4">:</span> <span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">class</span> A <span class="sy4">:</span> <span class="kw1">private</span> <span class="kw1">virtual</span> W <span class="br0">{</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">class</span> B <span class="sy4">:</span> <span class="kw1">public</span> <span class="kw1">virtual</span> W <span class="br0">{</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">class</span> C <span class="sy4">:</span> <span class="kw1">public</span> A, <span class="kw1">public</span> B <span class="br0">{</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> W<span class="sy4">::</span><span class="me2">f</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">// OK: C 可以通过 B 访问 W</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p>类中可以以任意顺序出现任意数量的访问说明符。成员访问说明符可能影响类的布局:非静态<a href="cpp-language-data_members.html#.E5.B8.83.E5.B1.80">数据成员</a>的地址只保证对于<span class="t-rev-inl t-until-cxx11"><span>未被访问说明符分隔</span> <span><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></span></span><span class="t-rev-inl t-since-cxx11"><span>具有相同访问</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>的成员以声明顺序增加。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>对于<a href="cpp-named_req-StandardLayoutType.html"><span style="font-style:italic">标准布局类型</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(StandardLayoutType)</span></a> ,所有非静态数据成员必须具有相同访问。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>在类中重声明成员时,成员访问必须相同:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> S <span class="br0">{</span>
|
|
<span class="kw1">class</span> A<span class="sy4">;</span> <span class="co1">// S::A 公开</span>
|
|
<span class="kw1">private</span><span class="sy4">:</span>
|
|
<span class="kw1">class</span> A <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 错误:不能更改访问</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.85.AC.E5.BC.80.E6.88.90.E5.91.98.E8.AE.BF.E9.97.AE">公开成员访问</span></h3>
|
|
<p>公开成员组成类公开接口的一部分(公开接口的其他部分是由 <a href="cpp-language-adl.html">ADL</a> 所找到的非成员函数)。</p>
|
|
<p>类的公开成员可以在任意位置访问。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> S <span class="br0">{</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span> <span class="co1">// n、E、A、B、C、U、f 是公开成员</span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span>
|
|
<span class="kw2">enum</span> E <span class="br0">{</span>A, B, C<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> U <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw4">static</span> <span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</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>
|
|
S<span class="sy4">::</span><span class="me2">f</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// S::f 可以在 main 访问</span>
|
|
S s<span class="sy4">;</span>
|
|
s.<span class="me1">n</span> <span class="sy1">=</span> S<span class="sy4">::</span><span class="me2">B</span><span class="sy4">;</span> <span class="co1">// S::n 与 S::B 可以在 main 访问</span>
|
|
S<span class="sy4">::</span><span class="me2">U</span> x<span class="sy4">;</span> <span class="co1">// S::U 可以在 main 访问</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.97.E4.BF.9D.E6.8A.A4.E6.88.90.E5.91.98.E8.AE.BF.E9.97.AE">受保护成员访问</span></h3>
|
|
<p>受保护成员组成所在类针对其派生类的接口(与类的公开接口有别)。</p>
|
|
<p>类的受保护成员只能为下列者所访问</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 该类的成员和友元</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 派生自该类的任何类的成员<span class="t-rev-inl t-until-cxx17"><span>和友元</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span>,但仅在访问受保护成员所通过的对象的类是该派生类或该派生类的派生类时允许:</div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> Base <span class="br0">{</span>
|
|
<span class="kw1">protected</span><span class="sy4">:</span>
|
|
<span class="kw4">int</span> i<span class="sy4">;</span>
|
|
<span class="kw1">private</span><span class="sy4">:</span>
|
|
<span class="kw4">void</span> g<span class="br0">(</span>Base<span class="sy3">&</span> b, <span class="kw1">struct</span> Derived<span class="sy3">&</span> d<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Derived <span class="sy4">:</span> Base <span class="br0">{</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span>Base<span class="sy3">&</span> b, Derived<span class="sy3">&</span> d<span class="br0">)</span> <span class="co1">// 派生类的成员函数</span>
|
|
<span class="br0">{</span>
|
|
<span class="sy2">++</span>d.<span class="me1">i</span><span class="sy4">;</span> <span class="co1">// OK:d 的类型是 Derived</span>
|
|
<span class="sy2">++</span>i<span class="sy4">;</span> <span class="co1">// OK:隐含的 '*this' 的类型是 Derived</span>
|
|
<span class="co1">// ++b.i; // 错误:不能通过 Base 访问受保护成员</span>
|
|
<span class="co1">// (否则可能更改另一派生类,假设为 Derived2 的基实现)</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">void</span> Base<span class="sy4">::</span><span class="me2">g</span><span class="br0">(</span>Base<span class="sy3">&</span> b, Derived<span class="sy3">&</span> d<span class="br0">)</span> <span class="co1">// Base 的成员函数</span>
|
|
<span class="br0">{</span>
|
|
<span class="sy2">++</span>i<span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="sy2">++</span>b.<span class="me1">i</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="sy2">++</span>d.<span class="me1">i</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">void</span> x<span class="br0">(</span>Base<span class="sy3">&</span> b, Derived<span class="sy3">&</span> d<span class="br0">)</span> <span class="co1">// 非成员非友元</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// ++b.i; // 错误:非成员不能访问</span>
|
|
<span class="co1">// ++d.i; // 错误:非成员不能访问</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>组成指向受保护成员的指针时,必须在其声明中使用派生类:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> Base <span class="br0">{</span>
|
|
<span class="kw1">protected</span><span class="sy4">:</span>
|
|
<span class="kw4">int</span> i<span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Derived <span class="sy4">:</span> Base <span class="br0">{</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// int Base::* ptr = &Base::i; // 错误:必须使用 Derived 来指名</span>
|
|
<span class="kw4">int</span> Base<span class="sy4">::</span><span class="sy2">*</span> ptr <span class="sy1">=</span> <span class="sy3">&</span>Derived<span class="sy4">::</span><span class="me2">i</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.A7.81.E6.9C.89.E6.88.90.E5.91.98.E8.AE.BF.E9.97.AE">私有成员访问</span></h3>
|
|
<p>私有成员组成类的实现,以及针对类的其他成员的私有接口。</p>
|
|
<p>类的私有成员仅对类的成员和友元可访问,无关乎成员在相同还是不同实例:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> S <span class="br0">{</span>
|
|
<span class="kw1">private</span><span class="sy4">:</span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span> <span class="co1">// S::n 私有</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span>
|
|
S<span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// this->n 可以在 S::S 访问</span>
|
|
S<span class="br0">(</span><span class="kw4">const</span> S<span class="sy3">&</span> other<span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span>other.<span class="me1">n</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// other.n 可以在 S::S 访问</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p><a href="cpp-language-explicit_cast.html">显式转型</a>(C 风格与函数风格)允许从派生类左值转型为到其私有基类的引用,或从指向派生类的指针转型为指向其私有基类的指针。</p>
|
|
<h3><span class="mw-headline" id=".E7.BB.A7.E6.89.BF">继承</span></h3>
|
|
<p>公开、受保护和私有继承的含义,见<a href="cpp-language-derived_class.html">派生类</a>。</p>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|