919 lines
88 KiB
HTML
919 lines
88 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_operator_member_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>访问其操作数的一个成员。</p>
|
|
<table class="wikitable" style="font-size:85%;">
|
|
<tr>
|
|
<th rowspan="2">运算符名</th>
|
|
<th rowspan="2">语法</th>
|
|
<th rowspan="2"><a href="cpp-language-operators.html">可重载</a></th>
|
|
<th colspan="2">原型示例(对于 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">class</span> T</span></span> )</th>
|
|
</tr>
|
|
<tr>
|
|
<th>类定义内</th>
|
|
<th>类定义外</th>
|
|
</tr>
|
|
<tr>
|
|
<td>下标</td>
|
|
<td><code>a[b]</code></td>
|
|
<td style="background: #90ff90; color: black; vertical-align: middle; text-align: center;" class="table-yes">是</td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>S b<span class="br0">)</span><span class="sy4">;</span></span></span>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>S1 s1, ...<span class="br0">)</span><span class="sy4">;</span></span></span></p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
</tr>
|
|
<tr>
|
|
<td>间接寻址</td>
|
|
<td><code>*a</code></td>
|
|
<td style="background: #90ff90; color: black; vertical-align: middle; text-align: center;" class="table-yes">是</td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="sy2">*</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> operator<span class="sy2">*</span><span class="br0">(</span>T a<span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td>取地址</td>
|
|
<td><code>&a</code></td>
|
|
<td style="background: #90ff90; color: black; vertical-align: middle; text-align: center;" class="table-yes">是</td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy2">*</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="sy3">&</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy2">*</span> operator<span class="sy3">&</span><span class="br0">(</span>T a<span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td>对象的成员</td>
|
|
<td><code>a.b</code></td>
|
|
<td style="background:#ff9090; color:black; vertical-align: middle; text-align: center;" class="table-no">否</td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
</tr>
|
|
<tr>
|
|
<td>指针的成员</td>
|
|
<td><code>a->b</code></td>
|
|
<td style="background: #90ff90; color: black; vertical-align: middle; text-align: center;" class="table-yes">是</td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy2">*</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="sy2">-</span><span class="sy1">></span><span class="br0">(</span><span class="br0">)</span></span></span></td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
</tr>
|
|
<tr>
|
|
<td>指向对象的成员的指针</td>
|
|
<td><code>a.*b</code></td>
|
|
<td style="background:#ff9090; color:black; vertical-align: middle; text-align: center;" class="table-no">否</td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
<td style="background: #ececec; color: grey; vertical-align: middle; text-align: center;" class="table-na"><small>N/A</small></td>
|
|
</tr>
|
|
<tr>
|
|
<td>指向指针的成员的指针</td>
|
|
<td><code>a->*b</code></td>
|
|
<td style="background: #90ff90; color: black; vertical-align: middle; text-align: center;" class="table-yes">是</td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> T<span class="sy4">::</span><span class="me2">operator</span><span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span><span class="br0">(</span>S b<span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
<td><span class="t-c"><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> operator<span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span><span class="br0">(</span>T a, S b<span class="br0">)</span><span class="sy4">;</span></span></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<dl>
|
|
<dd><b>注解</b><br /></dd>
|
|
</dl>
|
|
<ul>
|
|
<li>与大多数用户定义的重载相同,返回类型应当与内建运算符所提供的返回类型相匹配,以便<a href="cpp-language-operators.html">用户定义的运算符</a>可以和内建运算符以相同的方式使用。不过,在用户定义的运算符重载中,任何类型都可以作为其返回类型(包括 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span></span></span>)。一个例外是 <code>operator-></code>,它必须返回一个指针或者另一个带有重载的 <code>operator-></code> 的类以使其真正可用。</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>内建的<i>下标 (subscript)</i>运算符提供对其<a href="cpp-language-pointer.html">指针</a>或<a href="cpp-language-array.html">数组</a>操作数所指向的对象的访问。</p>
|
|
<p>内建的<i>间接寻址 (indirection)</i>运算符提供对其指针操作数所指向的对象或函数的访问。</p>
|
|
<p>内建的<i>取地址 (address of)</i>运算符创建指向其对象或函数操作数的指针。</p>
|
|
<p><i>对象的成员</i>和<i>指向对象的成员的指针</i>运算符提供对其对象操作数的数据成员或成员函数的访问。</p>
|
|
<p>内建的<i>指针的成员</i>和<i>指向指针的成员的指针</i>运算符提供对其指针操作数所指向的类的数据成员或成员函数的访问。</p>
|
|
<h4><span class="mw-headline" id=".E5.86.85.E5.BB.BA.E7.9A.84.E4.B8.8B.E6.A0.87.E8.BF.90.E7.AE.97.E7.AC.A6">内建的下标运算符</span></h4>
|
|
<p>下标运算符表达式的形式为</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">表达式1</span> <code><b>[</b></code> <span class="t-spar">表达式2</span> <code><b>]</b></code></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><span class="t-spar">表达式1</span> <code><b>[</b></code> <code><b>{</b></code> <span class="t-spar">表达式, ...</span> <code><b>}</b></code> <code><b>]</b></code></td>
|
|
<td>(2)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">表达式1</span> <code><b>[</b></code> <span class="t-spar">表达式2</span> <code><b>,</b></code> <span class="t-spar">expr, ...</span> <code><b>]</b></code></td>
|
|
<td>(3)</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 对于内建运算符,表达式之一(<span class="t-spar">表达式1</span> 或 <span class="t-spar">表达式2</span>)必须是“T 的数组”类型的泛左值或“T 的指针”类型的纯右值,而另一表达式(分别为 <span class="t-spar">表达式2</span> 或 <span class="t-spar">表达式1</span>)必须是无作用域枚举或整型类型的纯右值。此表达式的结果类型为 <code>T</code>。 <span class="t-rev-inl t-since-cxx23"><span><span class="t-spar">表达式2</span> 不能为无括号的<a href="cpp-language-operator_other.html#.E5.86.85.E5.BB.BA.E7.9A.84.E9.80.97.E5.8F.B7.E8.A1.A8.E8.BE.BE.E5.BC.8F">逗号表达式</a>。</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 方括号中有花括号环绕列表的形式仅用于调用重载的 <code>operator[]</code>。</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 方括号中有逗号分隔的表达式列表的形式仅用于调用重载的 <code>operator[]</code>。</div>
|
|
<p>内建下标表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="br0">[</span>E2<span class="br0">]</span></span></span> <span class="t-rev-inl t-since-cxx17"><span>除了<a href="cpp-language-eval_order.html">求值顺序</a>之外</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>与表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span><span class="br0">(</span>E1 <span class="sy2">+</span> E2<span class="br0">)</span></span></span> 严格等同,就是说,它遵循<a href="cpp-language-operator_arithmetic.html">指针算术</a>的规则,将指针操作数(可以是数组到指针转换的结果,但它必须指向某数组的元素或末尾后一位置)调整为指向同数组的另一元素,然后再进行解引用。</p>
|
|
<p>应用到数组时,<span class="t-rev-inl t-since-cxx11"><span>若数组为左值,则</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>下标表达式为<a href="cpp-language-value_category.html">左值</a><span class="t-rev-inl t-since-cxx11"><span>,否则为<a href="cpp-language-value_category.html">亡值</a></span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>。</p>
|
|
<p>应用到指针时,下标表达式始终是左值。</p>
|
|
<p>类型 <code>T</code> 不得为<a href="cpp-language-incomplete_type.html" class="mw-redirect">不完整类型</a>,即使始终不会使用 <code>T</code> 的大小或其内部结构也是如此,如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span>x<span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span></span></span>。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx20 t-until-cxx23">
|
|
<td>
|
|
<p>以无括号的<a href="cpp-language-operator_other.html#.E5.86.85.E5.BB.BA.E7.9A.84.E9.80.97.E5.8F.B7.E8.BF.90.E7.AE.97.E7.AC.A6">逗号表达式</a>为下标运算符的第二(右)操作数是被弃用的。</p>
|
|
<p>例如, <span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">[</span>b, c<span class="br0">]</span></span></span> 被弃用而 <span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">[</span><span class="br0">(</span>b, c<span class="br0">)</span><span class="br0">]</span></span></span> 未被弃用。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span><br />
|
|
<span class="t-mark-rev t-until-cxx23">(C++23 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<p>无括号的<a href="cpp-language-operator_other.html#.E5.86.85.E5.BB.BA.E7.9A.84.E9.80.97.E5.8F.B7.E8.A1.A8.E8.BE.BE.E5.BC.8F">逗号表达式</a>不能为下标运算符的第二(右)参数。例如 <span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">[</span>b, c<span class="br0">]</span></span></span> 要么非良构要么等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp">a.<span class="me1">operator</span><span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>b, c<span class="br0">)</span></span></span>。</p>
|
|
<p>为将逗号表达式用作下标需要括号,例如 <span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">[</span><span class="br0">(</span>b, c<span class="br0">)</span><span class="br0">]</span></span></span>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>在<a href="cpp-language-overload_resolution.html#.E8.B0.83.E7.94.A8.E9.87.8D.E8.BD.BD.E8.BF.90.E7.AE.97.E7.AC.A6">对于用户定义运算符的重载决议</a>中,对于每个对象类型 <code>T</code>(可有 cv 限定),下列函数签名参与重载决议:</p>
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td class="t-dcl-nopad">
|
|
<div><span class="mw-geshi cpp source-cpp">T<span class="sy3">&</span> operator<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span>T<span class="sy2">*</span>, <a href="cpp-types-ptrdiff_t.html"><span class="kw101">std::<span class="me2">ptrdiff_t</span></span></a><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td class="t-dcl-nopad">
|
|
<div><span class="mw-geshi cpp source-cpp">T<span class="sy3">&</span> operator<span class="br0">[</span><span class="br0">]</span><span class="br0">(</span><a href="cpp-types-ptrdiff_t.html"><span class="kw101">std::<span class="me2">ptrdiff_t</span></span></a>, T<span class="sy2">*</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="t-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="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> a<span class="br0">[</span><span class="nu0">4</span><span class="br0">]</span> <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span>, <span class="nu0">4</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> p <span class="sy1">=</span> <span class="sy3">&</span>a<span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> p<span class="br0">[</span><span class="nu0">1</span><span class="br0">]</span> <span class="sy1"><<</span> p<span class="br0">[</span><span class="sy2">-</span><span class="nu0">1</span><span class="br0">]</span> <span class="sy1"><<</span> <span class="nu0">1</span><span class="br0">[</span>p<span class="br0">]</span> <span class="sy1"><<</span> <span class="br0">(</span><span class="sy2">-</span><span class="nu0">1</span><span class="br0">)</span><span class="br0">[</span>p<span class="br0">]</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<a href="cpp-container-map.html"><span class="kw1281">std::<span class="me2">map</span></span></a><span class="sy1"><</span><a href="cpp-utility-pair.html"><span class="kw1096">std::<span class="me2">pair</span></span></a><span class="sy1"><</span><span class="kw4">int</span>, <span class="kw4">int</span><span class="sy1">></span>, <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy1">></span> m<span class="sy4">;</span>
|
|
m<span class="br0">[</span><span class="br0">{</span><span class="nu0">1</span>, <span class="nu0">2</span><span class="br0">}</span><span class="br0">]</span> <span class="sy1">=</span> <span class="st0">"abc"</span><span class="sy4">;</span> <span class="co1">// 使用 [{...}] 版本</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">4242</pre></div>
|
|
</div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E5.86.85.E5.BB.BA.E7.9A.84.E9.97.B4.E6.8E.A5.E5.AF.BB.E5.9D.80.E8.BF.90.E7.AE.97.E7.AC.A6">内建的间接寻址运算符</span></h4>
|
|
<p>间接寻址运算符表达式的形式为</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>*</b></code> <span class="t-spar">表达式</span></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<p>内建间接寻址运算符的操作数必须是对象指针或函数指针,其结果就是 <span class="t-spar">表达式</span> 所指向的指针或函数。</p>
|
|
<p>指向(可有 <a href="cpp-language-cv.html">cv</a> 限定)的 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">void</span></span></span> 的指针不能解引用。指向其他不完整类型的指针可以解引用,但产生的左值只能在允许不完整类型的语境中使用,例如初始化一个引用。</p>
|
|
<p>在<a href="cpp-language-overload_resolution.html#.E8.B0.83.E7.94.A8.E9.87.8D.E8.BD.BD.E8.BF.90.E7.AE.97.E7.AC.A6">对于用户定义运算符的重载决议</a>中,对于每个要么为(可有 cv 限定的)对象类型要么为(未被 const 或引用限定的)函数类型的类型 <code>T</code>,下列函数签名参与重载决议:</p>
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td class="t-dcl-nopad">
|
|
<div><span class="mw-geshi cpp source-cpp">T<span class="sy3">&</span> operator<span class="sy2">*</span><span class="br0">(</span>T<span class="sy2">*</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="t-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="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">42</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> n <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> pn <span class="sy1">=</span> <span class="sy3">&</span>n<span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span><span class="sy3">&</span> r <span class="sy1">=</span> <span class="sy2">*</span>pn<span class="sy4">;</span> <span class="co1">// 左值可以绑定到引用</span>
|
|
<span class="kw4">int</span> m <span class="sy1">=</span> <span class="sy2">*</span>pn<span class="sy4">;</span> <span class="co1">// 间接寻址 + 左值到右值转换</span>
|
|
|
|
<span class="kw4">int</span> <span class="br0">(</span><span class="sy2">*</span>fp<span class="br0">)</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy3">&</span>f<span class="sy4">;</span>
|
|
<span class="kw4">int</span> <span class="br0">(</span><span class="sy3">&</span>fr<span class="br0">)</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy2">*</span>fp<span class="sy4">;</span> <span class="co1">// 函数左值可以绑定到引用</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E5.86.85.E5.BB.BA.E7.9A.84.E5.8F.96.E5.9C.B0.E5.9D.80.E8.BF.90.E7.AE.97.E7.AC.A6">内建的取地址运算符</span></h4>
|
|
<p>取地址运算符表达式的形式为</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><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>&</b></code> <span class="t-spar">类</span> <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>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 当操作数是某个对象或函数类型 <code>T</code> 的左值表达式时,<code>operator&</code> 创建并返回一个有相同 cv 限定的 <code>T*</code> 类型的纯右值,并指向由该操作数所代表的对象或函数。当其操作数具有不完整类型时,可以构成指针,但若该不完整类型恰好为某个定义了其自身的 <code>operator&</code> 的类,则使用内建还是重载运算符是未指明的。对于其类型带有用户定义的 <code>operator&</code> 的操作数,可以使用 <span class="t-lc"><a href="cpp-memory-addressof.html">std::addressof</a></span> 来获取真正的指针。注意,这和 C99 以及其后的 C 语言版本不同,不存在对一元 <code>operator*</code> 运算符的运算结果应用一元 <code>operator&</code> 运算符的特殊情况。</div>
|
|
<div class="t-li1"><span class="t-li"></span> 当其操作数为重载函数的名字时,仅当根据其语境可以解析这个重载时才能取得其地址。详细说明参见<a href="cpp-language-overloaded_address.html">重载函数的地址</a>。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 当其操作数为非静态成员的限定名(比如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span>C<span class="sy4">::</span><span class="me2">member</span></span></span>)时,其结果为 <code>C</code> 类中的 <code>T</code> 类型的<a href="cpp-language-pointer.html#.E6.88.90.E5.91.98.E5.87.BD.E6.95.B0.E6.8C.87.E9.92.88">成员函数指针</a>或<a href="cpp-language-pointer.html#.E6.95.B0.E6.8D.AE.E6.88.90.E5.91.98.E6.8C.87.E9.92.88">数据成员指针</a>的纯右值。注意,<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span>member</span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp">C<span class="sy4">::</span><span class="me2">member</span></span></span>,甚至 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span><span class="br0">(</span>C<span class="sy4">::</span><span class="me2">member</span><span class="br0">)</span></span></span> 都不能用于初始化成员指针。</div>
|
|
<p>在<a href="cpp-language-overload_resolution.html#.E8.B0.83.E7.94.A8.E9.87.8D.E8.BD.BD.E8.BF.90.E7.AE.97.E7.AC.A6">对于用户定义运算符的重载决议</a>中,此运算符不引入任何额外函数签名:若存在作为<a href="cpp-language-overload_resolution.html#.E5.8F.AF.E8.A1.8C.E5.87.BD.E6.95.B0">可行函数</a>的重载 <code>operator&</code>,则内建的取址运算符不适用。</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="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">double</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
<span class="kw1">struct</span> A <span class="br0">{</span> <span class="kw4">int</span> i<span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> B <span class="br0">{</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="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> pn <span class="sy1">=</span> <span class="sy3">&</span>n<span class="sy4">;</span> <span class="co1">// 指针</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> pn2 <span class="sy1">=</span> <span class="sy3">&</span><span class="sy2">*</span>pn<span class="sy4">;</span> <span class="co1">// pn2 == pn</span>
|
|
<span class="kw4">int</span> A<span class="sy4">::</span><span class="sy2">*</span> mp <span class="sy1">=</span> <span class="sy3">&</span>A<span class="sy4">::</span><span class="me2">i</span><span class="sy4">;</span> <span class="co1">// 指向数据成员的指针</span>
|
|
<span class="kw4">void</span> <span class="br0">(</span>B<span class="sy4">::</span><span class="sy2">*</span>mpf<span class="br0">)</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy3">&</span>B<span class="sy4">::</span><span class="me2">f</span><span class="sy4">;</span> <span class="co1">// 指向成员函数的指针</span>
|
|
|
|
<span class="kw4">void</span> <span class="br0">(</span><span class="sy2">*</span>pf<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy3">&</span>f<span class="sy4">;</span> <span class="co1">// 根据初始化语境进行重载决议</span>
|
|
<span class="co1">// auto pf2 = &f; // 错误:重载函数类型有歧义</span>
|
|
<span class="kw4">auto</span> pf2 <span class="sy1">=</span> <span class="kw1">static_cast</span><span class="sy1"><</span><span class="kw4">void</span> <span class="br0">(</span><span class="sy2">*</span><span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy1">></span><span class="br0">(</span><span class="sy3">&</span>f<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 由于转型进行重载决议</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E5.86.85.E5.BB.BA.E7.9A.84.E6.88.90.E5.91.98.E8.AE.BF.E9.97.AE.E8.BF.90.E7.AE.97.E7.AC.A6">内建的成员访问运算符</span></h4>
|
|
<p>成员访问运算符表达式的形式为</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">表达式</span> <code><b>.</b></code> <code><b>template</b></code><span class="t-mark">(可选)</span> <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><span class="t-spar">表达式</span> <code><b>-></b></code> <code><b>template</b></code><span class="t-mark">(可选)</span> <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><span class="t-spar">表达式</span> <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-spar">表达式</span> <code><b>-></b></code> <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>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 第一操作数必须是<a href="cpp-language-type.html#.E4.B8.8D.E5.AE.8C.E6.95.B4.E7.B1.BB.E5.9E.8B">完整类类型</a> <code>T</code> 的表达式。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 第一操作数必须是指向完整类类型的指针 <code>T*</code> 的表达式。</div>
|
|
<div class="t-li1"><span class="t-li">3,4)</span> 第一操作数必须是标量类型表达式(见下文)。</div>
|
|
<p>两种运算符的第一个操作数都被求值,即便它并不是必须的(比如其第二个操作数指名的是静态成员)。</p>
|
|
<p>两个运算符的第二个操作数是 <code>T</code> 或 <code>T</code> 的某个无歧义且可访问的基类 <code>B</code> 的数据成员或成员函数的名字(正式的说法是<a href="cpp-language-identifiers.html#.E5.9C.A8.E8.A1.A8.E8.BE.BE.E5.BC.8F.E4.B8.AD">标识表达式(id-expression)</a>)(如 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="me1">E2</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="sy2">-</span><span class="sy1">></span>E2</span></span>),并可选地<a href="cpp-language-identifiers.html#.E6.9C.89.E9.99.90.E5.AE.9A.E7.9A.84.E6.A0.87.E8.AF.86.E7.AC.A6">有限定</a>(如 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="me1">B</span><span class="sy4">::</span><span class="me2">E2</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="sy2">-</span><span class="sy1">></span>B<span class="sy4">::</span><span class="me2">E2</span></span></span>),可选地使用 <a href="cpp-language-dependent_name.html">template 歧义消解符</a>(如 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="kw1">template</span> E2</span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="sy2">-</span><span class="sy1">></span><span class="kw1">template</span> E2</span></span>)。</p>
|
|
<p>如果提供的是用户定义的 <code>operator-></code>,则递归地对其所返回的值再次调用 <code>operator-></code>,直到到达返回普通指针的 <code>operator-></code> 为止。之后再对这个指针采用内建语义。</p>
|
|
<p>对于内建类型,表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="sy2">-</span><span class="sy1">></span>E2</span></span> 严格等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>E1<span class="br0">)</span>.<span class="me1">E2</span></span></span>;因此以下规则仅处理了 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="me1">E2</span></span></span> 的情形。</p>
|
|
<p>在表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="me1">E2</span></span></span> 中:</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 当 <code>E2</code> 为<a href="cpp-language-static.html">静态数据成员</a>时:
|
|
<ul>
|
|
<li>如果 <code>E2</code> 具有引用类型 <code>T&</code> 或 <code>T&&</code>,则其结果为 <code>T</code> 类型的左值,代表 <code>E2</code> 所代表的对象或函数,</li>
|
|
<li>否则,其结果为代表该静态数据成员的左值。</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>基本上,这两种情况下 <code>E1</code> 均被求值随即被丢弃;</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 当 <code>E2</code> 为<a href="cpp-language-data_members.html">非静态数据成员</a>时:
|
|
<ul>
|
|
<li>如果 <code>E2</code> 具有引用类型 <code>T&</code> 或 <code>T&&</code>,则其结果为 <code>T</code> 类型的左值,代表 <code>E2</code> 所代表的对象或函数,</li>
|
|
<li>否则,如果 <code>E1</code> 为左值,则其结果为代表 <code>E1</code> 的这个非静态数据成员的左值,</li>
|
|
<li>否则(<code>E1</code> 为<span class="t-rev-inl t-until-cxx17"><span>右值</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span><span class="t-rev-inl t-since-cxx17"><span>亡值(可能是从纯右值<a href="cpp-language-implicit_conversion.html#.E4.B8.B4.E6.97.B6.E9.87.8F.E5.AE.9E.E8.B4.A8.E5.8C.96">实质化</a>而来)</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>),其结果为代表 <code>E1</code> 的这个非静态数据成员的<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>。</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>若 <code>E2</code> 不是 mutable 成员,则结果的 <a href="cpp-language-cv.html">cv 限定性</a>是 <code>E1</code> 和 <code>E2</code> 的 cv 限定性的合并,否则(<code>E2</code> 是 mutable 成员)为 <code>E1</code> 和 <code>E2</code> 的 volatile 限定性的合并;</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 当 <code>E2</code> 为<a href="cpp-language-static.html">静态成员函数</a>时,其结果为代表该静态成员函数的左值。基本上,这种情况下 <code>E1</code> 被求值随即被丢弃;</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 当 <code>E2</code> 为(包括<a href="cpp-language-destructor.html">析构函数</a>在内的)<a href="cpp-language-member_functions.html">非静态成员函数</a>时,其结果为代表 <code>E1</code> 的这个非静态成员函数的一种特殊的纯右值,它只能用作成员函数调用运算符的左操作数,而不能用于其他目的;</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> 当 <code>E2</code> 为成员枚举项时,其结果为等于 <code>E1</code> 的这个成员枚举项的纯右值;</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> 当 <code>E2</code> 为<a href="cpp-language-nested_classes.html" class="mw-redirect">嵌套类型</a>时,程序非良构(无法编译);</div>
|
|
<div class="t-li1"><span class="t-li">7)</span> 当 <code>E1</code> 为<a href="cpp-language-type.html">标量类型</a>而 <code>E2</code> 为一个 <code><b>~</b></code> 之后跟着代表(移除 cv 限定后)相同类型的<a href="cpp-language-type.html#.E7.B1.BB.E5.9E.8B.E7.9A.84.E5.91.BD.E5.90.8D">类型名</a>或 <a href="cpp-language-decltype.html">decltype 说明符</a>,可选地<a href="cpp-language-identifiers.html#.E6.9C.89.E9.99.90.E5.AE.9A.E7.9A.84.E6.A0.87.E8.AF.86.E7.AC.A6">有限定</a>时,其结果为一种特殊的纯右值,它只能用作函数调用运算符的左操作数,而不能用于其他目的。所构成的函数调用表达式被称为<i>伪析构函数调用(pseudo destructor call)</i>。它不接受任何实参,返回 void ,求值 <code>E1</code> 后结束其结果对象的生存期。这是唯一使 <code>operator.</code> 的左操作数具有非类类型的情形。允许进行伪析构函数调用,使得编写代码时无须了解某个给定类型是否存在析构函数成为可能。</div>
|
|
<p><code>operator.</code> 不能重载,而对于 <code>operator-></code> 来说,在<a href="cpp-language-overload_resolution.html#.E8.B0.83.E7.94.A8.E9.87.8D.E8.BD.BD.E8.BF.90.E7.AE.97.E7.AC.A6">对于用户定义运算符的重载决议</a>中,内建运算符不引入任何额外函数签名:若存在作为<a href="cpp-language-overload_resolution.html#.E5.8F.AF.E8.A1.8C.E5.87.BD.E6.95.B0">可行函数</a>的重载 <code>operator&</code>,则不采用内建的 <code>operator-></code>。</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">struct</span> P
|
|
<span class="br0">{</span>
|
|
<span class="kw1">template</span><span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
|
<span class="kw4">static</span> T<span class="sy2">*</span> ptr<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> new T<span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">template</span><span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
|
<span class="kw1">struct</span> A
|
|
<span class="br0">{</span>
|
|
A<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="kw4">int</span> n<span class="sy4">;</span>
|
|
<span class="kw4">static</span> <span class="kw4">int</span> sn<span class="sy4">;</span>
|
|
<span class="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">10</span> <span class="sy2">+</span> n<span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw4">static</span> <span class="kw4">int</span> sf<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="nu0">4</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">class</span> B <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw2">enum</span> E <span class="br0">{</span>RED <span class="sy1">=</span> <span class="nu0">1</span>, BLUE <span class="sy1">=</span> <span class="nu0">2</span><span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">void</span> g<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">typedef</span> <span class="kw4">int</span> U<span class="sy4">;</span>
|
|
<span class="co1">// 待决的模板成员需要关键词 template</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> p <span class="sy1">=</span> P<span class="br0">(</span><span class="br0">)</span>.<span class="kw1">template</span> ptr<span class="sy1"><</span>U<span class="sy1">></span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
p<span class="sy2">-</span><span class="sy1">></span>~U<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// U 为 int,调用 int 的伪析构函数</span>
|
|
delete p<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">template</span><span class="sy1"><></span> <span class="kw4">int</span> A<span class="sy1"><</span>P<span class="sy1">></span><span class="sy4">::</span><span class="me2">sn</span> <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
A<span class="sy1"><</span>P<span class="sy1">></span> a<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> a.<span class="me1">n</span> <span class="sy1"><<</span> <span class="st0">' '</span>
|
|
<span class="sy1"><<</span> a.<span class="me1">sn</span> <span class="sy1"><<</span> <span class="st0">' '</span> <span class="co1">// A::sn 也可以</span>
|
|
<span class="sy1"><<</span> a.<span class="me1">f</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">' '</span>
|
|
<span class="sy1"><<</span> a.<span class="me1">sf</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">' '</span> <span class="co1">// A::sf() 也可以</span>
|
|
<span class="co1">// << a.B << ' ' // 错误:不允许嵌套类型</span>
|
|
<span class="sy1"><<</span> a.<span class="me1">RED</span> <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span> <span class="co1">// 枚举项</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">1 2 11 4 1</pre></div>
|
|
</div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E5.86.85.E5.BB.BA.E7.9A.84.E6.88.90.E5.91.98.E6.8C.87.E9.92.88.E8.AE.BF.E9.97.AE.E8.BF.90.E7.AE.97.E7.AC.A6">内建的成员指针访问运算符</span></h4>
|
|
<p>通过成员指针进行的成员访问运算符表达式的形式为</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">左操作数</span> <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><span class="t-spar">左操作数</span> <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>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> <span class="t-spar">左操作数</span> 必须是类类型 <code>T</code> 的表达式。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> <span class="t-spar">左操作数</span> 必须是指向类类型指针 <code>T*</code> 的表达式。</div>
|
|
<p>两个运算符的第二操作数都是类型为指向 <code>T</code> 的(<a href="cpp-language-pointer.html#.E6.95.B0.E6.8D.AE.E6.88.90.E5.91.98.E6.8C.87.E9.92.88">数据</a>或<a href="cpp-language-pointer.html#.E6.88.90.E5.91.98.E5.87.BD.E6.95.B0.E6.8C.87.E9.92.88">函数</a>)成员指针类型,或为指向 <code>T</code> 的无歧义且可访问基类 <code>B</code> 成员指针类型的表达式。</p>
|
|
<p>对于内建类型,表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1<span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span>E2</span></span> 严格等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span><span class="sy2">*</span>E1<span class="br0">)</span>.<span class="sy2">*</span>E2</span></span>;因此以下规则仅处理了 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="sy2">*</span>E2</span></span> 的情形。</p>
|
|
<p>在表达式 <span class="t-c"><span class="mw-geshi cpp source-cpp">E1.<span class="sy2">*</span>E2</span></span> 中:</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 当 <code>E2</code> 为指向数据成员的指针时,
|
|
<ul>
|
|
<li>如果 <code>E1</code> 为左值,则其结果为代表这个成员的左值,</li>
|
|
<li>否则(<code>E1</code> 为<span class="t-rev-inl t-until-cxx17"><span>右值</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span><span class="t-rev-inl t-since-cxx17"><span>亡值(可能是从纯右值<a href="cpp-language-implicit_conversion.html#.E4.B8.B4.E6.97.B6.E9.87.8F.E5.AE.9E.E8.B4.A8.E5.8C.96">实质化</a>而来)</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>),其结果为代表这个数据成员的<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>;</li>
|
|
</ul>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 当 <code>E2</code> 为指向成员函数的指针时,其结果为代表这个成员函数的一种特殊的纯右值,它只能用作成员函数调用运算符的左运算数,而不能用于其他目的;</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> cv 限定性的规则与对象的成员运算符相同,但有一条额外规则:指代 mutable 成员的成员指针不能用于改动 const 对象中的这个成员;</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 当 <code>E2</code> 为空成员指针值时,其行为未定义;</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> 当 <code>E1</code> 的<a href="cpp-language-type.html#.E5.8A.A8.E6.80.81.E7.B1.BB.E5.9E.8B">动态类型</a>并不包含 <code>E2</code> 所指代的成员时,其行为未定义;</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> 当 <code>E1</code> 为右值而 <code>E2</code> 指向带有引用限定符 & 的成员函数时,程序非良构<span class="t-rev-inl t-since-cxx20"><span>,除非该成员函数亦为 <code>const</code> 限定但非 <code>volatile</code> 限定</span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>;</div>
|
|
<div class="t-li1"><span class="t-li">7)</span> 当 <code>E1</code> 为左值而 <code>E2</code> 指向带有引用限定符 && 的成员函数时,程序非良构。</div>
|
|
<p>在<a href="cpp-language-overload_resolution.html#.E8.B0.83.E7.94.A8.E9.87.8D.E8.BD.BD.E8.BF.90.E7.AE.97.E7.AC.A6">对于用户定义运算符的重载决议</a>中,对于每个类型 <code>D</code>, <code>B</code>, <code>R</code> 的组合,其中类类型 <code>B</code> 是与 <code>D</code> 相同的类或 <code>D</code> 的无歧义且可访问基类,而 <code>R</code> 是对象或函数类型,下列函数签名参与重载决议:</p>
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td class="t-dcl-nopad">
|
|
<div><span class="mw-geshi cpp source-cpp">R<span class="sy3">&</span> operator<span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span><span class="br0">(</span>D<span class="sy2">*</span>, R B<span class="sy4">::</span><span class="sy2">*</span><span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>其中两个操作数都可以是 cv 限定的,这种情况下返回类型的 cv 限定性是个操作数的 cv 限定性的合并。</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">struct</span> S
|
|
<span class="br0">{</span>
|
|
S<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span><span class="sy4">:</span> mi<span class="br0">(</span>n<span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
mutable <span class="kw4">int</span> mi<span class="sy4">;</span>
|
|
<span class="kw4">int</span> f<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> mi <span class="sy2">+</span> n<span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> D<span class="sy4">:</span> <span class="kw1">public</span> S
|
|
<span class="br0">{</span>
|
|
D<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span><span class="sy4">:</span> S<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">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> S<span class="sy4">::</span><span class="sy2">*</span> pmi <span class="sy1">=</span> <span class="sy3">&</span>S<span class="sy4">::</span><span class="me2">mi</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span> <span class="br0">(</span>S<span class="sy4">::</span><span class="sy2">*</span> pf<span class="br0">)</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span> <span class="sy1">=</span> <span class="sy3">&</span>S<span class="sy4">::</span><span class="me2">f</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">const</span> S s<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="co1">// s.*pmi = 10; // 错误:无法通过 mutable 进行修改</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> s.<span class="sy2">*</span>pmi <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
D d<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 基类的指针可以在派生类对象上工作</span>
|
|
D<span class="sy2">*</span> pd <span class="sy1">=</span> <span class="sy3">&</span>d<span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="br0">(</span>d.<span class="sy2">*</span>pf<span class="br0">)</span><span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">' '</span>
|
|
<span class="sy1"><<</span> <span class="br0">(</span>pd<span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span>pf<span class="br0">)</span><span class="br0">(</span><span class="nu0">8</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><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">7
|
|
14 15</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.A0.87.E5.87.86.E5.BA.93">标准库</span></h3>
|
|
<p>许多标准容器类都重载了下标运算符</p>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-utility-bitset-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问指定的位<br />
|
|
<span class="t-mark">(<code>std::bitset<N></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-unique_ptr-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>提供到被管理数组的有索引访问<br />
|
|
<span class="t-mark">(<code>std::unique_ptr<T,Deleter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-string-basic_string-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问指定字符<br />
|
|
<span class="t-mark">(<code>std::basic_string<CharT,Traits,Allocator></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-container-array-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>访问指定的元素<br />
|
|
<span class="t-mark">(<code>std::array<T,N></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-container-deque-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问指定的元素<br />
|
|
<span class="t-mark">(<code>std::deque<T,Allocator></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-container-vector-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问指定的元素<br />
|
|
<span class="t-mark">(<code>std::vector<T,Allocator></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-container-map-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问或插入指定的元素<br />
|
|
<span class="t-mark">(<code>std::map<Key,T,Compare,Allocator></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-container-unordered_map-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>访问或插入指定的元素<br />
|
|
<span class="t-mark">(<code>std::unordered_map<Key,T,Hash,KeyEqual,Allocator></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-reverse_iterator-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>按索引访问元素<br />
|
|
<span class="t-mark">(<code>std::reverse_iterator<Iter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-move_iterator-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>按索引访问元素<br />
|
|
<span class="t-mark">(<code>std::move_iterator<Iter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-numeric-valarray-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>获取/设置 valarray 数组元素、切片或掩码<br />
|
|
<span class="t-mark">(<code>std::valarray<T></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-regex-match_results-operator_at.html"><span class="t-lines"><span>operator[]</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>返回指定的子匹配<br />
|
|
<span class="t-mark">(<code>std::match_results<BidirIt,Alloc></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>许多迭代器和智能指针类都重载了间接寻址和成员运算符</p>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-unique_ptr-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>解引用指向被管理对象的指针<br />
|
|
<span class="t-mark">(<code>std::unique_ptr<T,Deleter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-shared_ptr-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>解引用存储的指针<br />
|
|
<span class="t-mark">(<code>std::shared_ptr<T></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-auto_ptr-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问被管理对象<br />
|
|
<span class="t-mark">(<code>std::auto_ptr<T></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-memory-raw_storage_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>解引用迭代器<br />
|
|
<span class="t-mark">(<code>std::raw_storage_iterator<OutputIt,T></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-reverse_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>对递减后的底层迭代器进行解引用<br />
|
|
<span class="t-mark">(<code>std::reverse_iterator<Iter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-back_insert_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>无操作<br />
|
|
<span class="t-mark">(<code>std::back_insert_iterator<Container></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-front_insert_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>无操作<br />
|
|
<span class="t-mark">(<code>std::front_insert_iterator<Container></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-insert_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>无操作<br />
|
|
<span class="t-mark">(<code>std::insert_iterator<Container></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-move_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span><span><span class="t-mark-rev t-since-cxx11">(C++11)</span><span class="t-mark-rev t-deprecated-cxx20">(C++20 中弃用)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>访问被指向的元素<br />
|
|
<span class="t-mark">(<code>std::move_iterator<Iter></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-istream_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>返回当前元素<br />
|
|
<span class="t-mark">(<code>std::istream_iterator<T,CharT,Traits,Distance></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-ostream_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>无操作<br />
|
|
<span class="t-mark">(<code>std::ostream_iterator<T,CharT,Traits></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-istreambuf_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
<div><span class="t-lines"><span></span><span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>获得当前字符的副本<br />
|
|
若 <code>CharT</code> 拥有成员,则访问当前字符的成员<br />
|
|
<span class="t-mark">(<code>std::istreambuf_iterator<CharT,Traits></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-iterator-ostreambuf_iterator-operator*.html"><span class="t-lines"><span>operator*</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>无操作<br />
|
|
<span class="t-mark">(<code>std::ostreambuf_iterator<CharT,Traits></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-regex-regex_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问当前匹配<br />
|
|
<span class="t-mark">(<code>std::regex_iterator<BidirIt,CharT,Traits></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-regex-regex_token_iterator-operator*.html"><span class="t-lines"><span>operator*</span><span>operator-></span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>访问当前子匹配<br />
|
|
<span class="t-mark">(<code>std::regex_token_iterator<BidirIt,CharT,Traits></code> 的公开成员函数)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>标准库中的类都没有重载 <code>operator&</code>。最为人所知的重载 <code>operator&</code> 的例子是微软的 COM 类 <a rel="nofollow" class="external text" href="http://msdn.microsoft.com/en-us/library/31k6d0k7(v=vs.100).aspx">CComPtr</a>,但在如 <a rel="nofollow" class="external text" href="http://www.boost.org/doc/libs/release/libs/spirit/doc/html/spirit/qi/reference/operator/and_predicate.html">boost.spirit</a> 这样的 EDSL 中也会出现重载它的例子。</p>
|
|
<p>标准库中的类都没有重载 <code>operator->*</code>。曾有建议将其作为<a rel="nofollow" class="external text" href="http://www.aristeia.com/Papers/DDJ_Oct_1999.pdf">智能指针接口</a>的一部分,并在 <a rel="nofollow" class="external text" href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/phoenix/modules/operator.html#phoenix.modules.operator.member_pointer_operator">boost.phoenix</a> 中的 actor 上有实际应用,但它在如 <a rel="nofollow" class="external text" href="https://github.com/schlangster/cpp.react/blob/master/include/react/Signal.h#L557">cpp.react</a> 这样的 EDSL 中更为常见。</p>
|
|
<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/issue1213">CWG 1213</a></td>
|
|
<td>C++11</td>
|
|
<td>数组右值的下标操作导致左值</td>
|
|
<td>重分类为亡值</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue1458">CWG 1458</a></td>
|
|
<td>C++98</td>
|
|
<td>应用 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span></span></span> 到声明 <span class="t-c"><span class="mw-geshi cpp source-cpp">operator<span class="sy3">&</span></span></span> 的不完整类型左值导致未定义行为</td>
|
|
<td>未指明使用哪个 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">&</span></span></span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<p><a href="cpp-language-operator_precedence.html">运算符优先级</a></p>
|
|
<p><a href="cpp-language-operators.html">运算符重载</a></p>
|
|
<table class="wikitable">
|
|
<tr style="text-align:center">
|
|
<th colspan="7">常见运算符</th>
|
|
</tr>
|
|
<tr style="text-align:center">
|
|
<td><a href="cpp-language-operator_assignment.html">赋值</a></td>
|
|
<td><a href="cpp-language-operator_incdec.html">自增<br />
|
|
自减</a></td>
|
|
<td><a href="cpp-language-operator_arithmetic.html">算术</a></td>
|
|
<td><a href="cpp-language-operator_logical.html">逻辑</a></td>
|
|
<td><a href="cpp-language-operator_comparison.html">比较</a></td>
|
|
<td><strong class="selflink">成员访问</strong></td>
|
|
<td><a href="cpp-language-operator_other.html">其他</a></td>
|
|
</tr>
|
|
<tr style="text-align:center">
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">a <span class="sy1">=</span> b<br />
|
|
a <span class="sy2">+</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">-</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">*</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">/</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">%</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">&</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">|</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">^</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy1"><<=</span> b<br />
|
|
a <span class="sy1">>>=</span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">++</span>a<br />
|
|
<span class="sy2">--</span>a<br />
|
|
a<span class="sy2">++</span><br />
|
|
a<span class="sy2">--</span></span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">+</span>a<br />
|
|
<span class="sy2">-</span>a<br />
|
|
a <span class="sy2">+</span> b<br />
|
|
a <span class="sy2">-</span> b<br />
|
|
a <span class="sy2">*</span> b<br />
|
|
a <span class="sy2">/</span> b<br />
|
|
a <span class="sy2">%</span> b<br />
|
|
~a<br />
|
|
a <span class="sy3">&</span> b<br />
|
|
a <span class="sy3">|</span> b<br />
|
|
a <span class="sy3">^</span> b<br />
|
|
a <span class="sy1"><<</span> b<br />
|
|
a <span class="sy1">>></span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy3">!</span>a<br />
|
|
a <span class="sy3">&&</span> b<br />
|
|
a <span class="sy3">||</span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">a <span class="sy1">==</span> b<br />
|
|
a <span class="sy3">!</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy1"><</span> b<br />
|
|
a <span class="sy1">></span> b<br />
|
|
a <span class="sy1"><=</span> b<br />
|
|
a <span class="sy1">>=</span> b<br />
|
|
a <span class="sy1"><=></span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">[</span>b<span class="br0">]</span><br />
|
|
<span class="sy2">*</span>a<br />
|
|
<span class="sy3">&</span>a<br />
|
|
a<span class="sy2">-</span><span class="sy1">></span>b<br />
|
|
a.<span class="me1">b</span><br />
|
|
a<span class="sy2">-</span><span class="sy1">></span><span class="sy2">*</span>b<br />
|
|
a.<span class="sy2">*</span>b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">a<span class="br0">(</span>...<span class="br0">)</span><br />
|
|
a, b<br />
|
|
<span class="sy4">?</span> <span class="sy4">:</span></span></span></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th colspan="7">特殊运算符</th>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="7">
|
|
<p><a href="cpp-language-static_cast.html"><tt>static_cast</tt></a> 转换一个类型为另一相关类型<br />
|
|
<a href="cpp-language-dynamic_cast.html"><tt>dynamic_cast</tt></a> 在继承层级中转换<br />
|
|
<a href="cpp-language-const_cast.html"><tt>const_cast</tt></a> 添加或移除 <a href="cpp-language-cv.html">cv</a> 限定符<br />
|
|
<a href="cpp-language-reinterpret_cast.html"><tt>reinterpret_cast</tt></a> 转换类型到无关类型<br />
|
|
<a href="cpp-language-explicit_cast.html">C 风格转型</a> 以 <code>static_cast</code> 、 <code>const_cast</code> 及 <code>reinterpret_cast</code> 的混合转换一个类型到另一类型<br />
|
|
<a href="cpp-language-new.html"><tt>new</tt></a> 创建有动态存储期的对象<br />
|
|
<a href="cpp-language-delete.html"><tt>delete</tt></a> 销毁先前由 new 表达式创建的对象,并释放其所拥有的内存区域<br />
|
|
<a href="cpp-language-sizeof.html"><tt>sizeof</tt></a> 查询类型的大小<br />
|
|
<a href="cpp-language-sizeof....html"><tt>sizeof...</tt></a> 查询<a href="cpp-language-parameter_pack.html">形参包</a>的大小<span class="t-mark-rev t-since-cxx11">(C++11 起)</span><br />
|
|
<a href="cpp-language-typeid.html"><tt>typeid</tt></a> 查询类型的类型信息<br />
|
|
<a href="cpp-language-noexcept.html"><tt>noexcept</tt></a> 查询表达式是否能抛出异常<span class="t-mark-rev t-since-cxx11">(C++11 起)</span><br />
|
|
<a href="cpp-language-alignof.html"><tt>alignof</tt></a> 查询类型的对齐要求<span class="t-mark-rev t-since-cxx11">(C++11 起)</span></p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|