336 lines
35 KiB
HTML
336 lines
35 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_constructor 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-member_functions.html">成员函数</a>,用于初始化该类类型的对象。</p>
|
|
<p>在类的构造函数定义中,<i>成员初始化器列表</i>指定各个直接基类、虚基类和非静态数据成员的初始化器。 (请勿与 <span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span> 混淆)</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<p>构造函数不能是<a href="cpp-language-coroutines.html">协程</a>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<p>构造函数用以下形式的成员<a href="cpp-language-function.html">函数声明符</a>声明:</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><span class="t-mark">(可选)</span> <code><b>)</b></code> <span class="t-spar">异常说明</span><span class="t-mark">(可选)</span> <span class="t-spar">属性</span><span class="t-mark">(可选)</span></td>
|
|
<td>(1)</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>构造函数声明的 <span class="t-spar">声明说明符序列</span> 中只允许说明符 <a href="cpp-language-friend.html"><code>friend</code></a>、<a href="cpp-language-inline.html"><code>inline</code></a><span class="t-rev-inl t-since-cxx11"><span>、<a href="cpp-language-constexpr.html"><code>constexpr</code></a></span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span><span class="t-rev-inl t-since-cxx20"><span>、<a href="cpp-language-consteval.html"><code>consteval</code></a></span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span> 及 <a href="cpp-language-explicit.html"><code>explicit</code></a>(尤其是不允许返回类型)。注意 <a href="cpp-language-member_functions.html">cv 及引用限定符</a>也不受允许;const 与 volatile 语义对于构造过程中的对象没有效果,它们要到最终派生类的构造函数完成才会生效。</p>
|
|
<p>任何构造函数的<a href="cpp-language-function.html">函数定义</a>的函数体可以在复合语句的开花括号之前包含<i>成员初始化器列表</i>,其语法是冒号字符 <code><b>:</b></code> 后随一个或多个 <span class="t-spar">成员初始化器</span> 的逗号分隔列表,每项均具有以下语法:</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><span class="t-mark">(可选)</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">类或标识符</span> <span class="t-spar">花括号初始化器列表</span></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">形参包</span> <code><b>...</b></code></td>
|
|
<td>(3)</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>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 用<a href="cpp-language-direct_initialization.html">直接初始化</a>,或当 <span class="t-spar">表达式列表</span> 为空时用<a href="cpp-language-value_initialization.html">值初始化</a>,初始化 <span class="t-spar">类或标识符</span> 所指名的基类或成员</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 用<a href="cpp-language-list_initialization.html">列表初始化</a>(如果列表为空则为<a href="cpp-language-value_initialization.html">值初始化</a>,而在初始化聚合体时为<a href="cpp-language-aggregate_initialization.html">聚合初始化</a>),初始化 <span class="t-spar">类或标识符</span> 所指名的基类或成员</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 用<a href="cpp-language-parameter_pack.html#.E5.9F.BA.E7.B1.BB.E8.AF.B4.E6.98.8E.E7.AC.A6.E4.B8.8E.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96.E5.99.A8.E5.88.97.E8.A1.A8">包展开</a>初始化多个基类</div>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">类或标识符</span></td>
|
|
<td>-</td>
|
|
<td>任何指名非静态数据成员的标识符,或任何指名该类自身(对于委托构造函数)、直接基类或虚基类的类型名。</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">表达式列表</span></td>
|
|
<td>-</td>
|
|
<td>传递给基类或成员的参数的逗号分隔列表,可以为空</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">花括号初始化器列表</span></td>
|
|
<td>-</td>
|
|
<td>花括号包围的以逗号分隔的初始化器和嵌套的花括号初始化器列表的列表</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">形参包</span></td>
|
|
<td>-</td>
|
|
<td>变参模板<a href="cpp-language-parameter_pack.html#.E5.9F.BA.E7.B1.BB.E8.AF.B4.E6.98.8E.E7.AC.A6.E4.B8.8E.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96.E5.99.A8.E5.88.97.E8.A1.A8">形参包</a>的名字</td>
|
|
</tr>
|
|
</table>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> S <span class="br0">{</span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span>
|
|
S<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 构造函数声明</span>
|
|
S<span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// 构造函数定义</span>
|
|
<span class="co1">// ": n(7)" 是初始化器列表</span>
|
|
<span class="co1">// ": n(7) {}" 是函数体</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
S<span class="sy4">::</span><span class="me2">S</span><span class="br0">(</span><span class="kw4">int</span> x<span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">{</span>x<span class="br0">}</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// 构造函数定义:": n{x}" 是初始化器列表</span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
S s<span class="sy4">;</span> <span class="co1">// 调用 S::S()</span>
|
|
S s2<span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 调用 S::S(int)</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>构造函数没有名字且无法被直接调用。它们在发生<a href="cpp-language-initialization.html">初始化</a>时调用,且它们按照初始化的规则进行选择。没有 <code>explicit</code> 说明符的构造函数是<a href="cpp-language-converting_constructor.html">转换构造函数</a>。有 <code>constexpr</code> 说明符的构造函数会让其类型成为<a href="cpp-named_req-LiteralType.html"><span style="font-style:italic">字面类型</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(LiteralType)</span></a> 。可以不带任何实参调用的构造函数是<a href="cpp-language-default_constructor.html">默认构造函数</a>。可以接收同类型的另一对象为实参的构造函数是<a href="cpp-language-copy_constructor.html">复制构造函数</a>和<a href="cpp-language-move_constructor.html">移动构造函数</a>。</p>
|
|
<p>在开始执行组成构造函数体的复合语句之前,所有直接基类、虚基类和非静态数据成员的初始化均已结束。这些对象的非默认初始化只能在成员初始化器列表指定。对于不能默认初始化的基类或非静态数据成员,例如引用和 const 限定的类型的成员,必须指定成员初始化器。对没有成员初始化器的<a href="cpp-language-union.html#.E5.8C.BF.E5.90.8D.E8.81.94.E5.90.88.E4.BD.93">匿名联合体</a>或<a href="cpp-language-union.html#.E8.81.94.E5.90.88.E4.BD.93.E5.BC.8F.E7.9A.84.E7.B1.BB">变体成员</a>不进行初始化。</p>
|
|
<p><span class="t-spar">类或标识符</span> 指名<a href="cpp-language-derived_class.html">虚基类</a>的初始化器,在并非所构造对象的最终派生类的类的构造期间被忽略。</p>
|
|
<p>在 <span class="t-spar">表达式列表</span> 或 <span class="t-spar">花括号初始化器列表</span> 中出现的名字在构造函数的作用域中求值:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">class</span> X <span class="br0">{</span>
|
|
<span class="kw4">int</span> a, b, i, j<span class="sy4">;</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span>
|
|
<span class="kw4">const</span> <span class="kw4">int</span><span class="sy3">&</span> r<span class="sy4">;</span>
|
|
X<span class="br0">(</span><span class="kw4">int</span> i<span class="br0">)</span>
|
|
<span class="sy4">:</span> r<span class="br0">(</span>a<span class="br0">)</span> <span class="co1">// 初始化 X::r 以指代 X::a</span>
|
|
, b<span class="br0">{</span>i<span class="br0">}</span> <span class="co1">// 初始化 X::b 为形参 i 的值</span>
|
|
, i<span class="br0">(</span>i<span class="br0">)</span> <span class="co1">// 初始化 X::i 为形参 i 的值</span>
|
|
, j<span class="br0">(</span>this<span class="sy2">-</span><span class="sy1">></span>i<span class="br0">)</span> <span class="co1">// 初始化 X::j 为 X::i 的值</span>
|
|
<span class="br0">{</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p>成员初始化器所抛出的异常可以被<a href="cpp-language-function-try-block.html">函数 try 块</a>处理。</p>
|
|
<p>成员函数(包括虚成员函数)可以从成员初始化器调用,但如果在该点还有直接基类尚未被初始化,那么行为未定义。</p>
|
|
<p>对于虚调用(如果在该点已初始化直接基类),适用与从构造函数与析构函数中进行虚函数调用相同的规则:虚成员函数表现如同 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">*</span>this</span></span> 的动态类型是正在构造的类的静态类型(动态派发不在继承层级下传),而对<a href="cpp-language-abstract_class.html">纯虚</a>成员函数的虚调用(但非静态调用)是未定义行为。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>如果非静态数据成员具有 <a href="cpp-language-data_members.html#.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96">默认成员初始化器</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> S <span class="br0">{</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> <span class="nu0">42</span><span class="sy4">;</span> <span class="co1">// 默认成员初始化器</span>
|
|
S<span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// 将设置 n 为 7,而非 42</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
</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> A <span class="br0">{</span>
|
|
A<span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> v<span class="br0">(</span><span class="nu0">42</span><span class="br0">)</span> <span class="br0">{</span> <span class="br0">}</span> <span class="co1">// 错误</span>
|
|
<span class="kw4">const</span> <span class="kw4">int</span><span class="sy3">&</span> v<span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p>注:这同样适用于<a href="cpp-language-data_members.html#.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96">默认成员初始化器</a>。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<h4><span class="mw-headline" id=".E5.A7.94.E6.89.98.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0">委托构造函数</span></h4>
|
|
<p>如果类自身的名字在初始化器列表中作为 <span class="t-spar">类或标识符</span> 出现,那么该列表只能由这一个成员初始化器组成;这种构造函数被称为<i>委托构造函数(delegating constructor)</i>,而构造函数列表的仅有成员所选择的构造函数是<i>目标构造函数</i>。</p>
|
|
<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> Foo <span class="br0">{</span>
|
|
<span class="kw1">public</span><span class="sy4">:</span>
|
|
Foo<span class="br0">(</span><span class="kw4">char</span> x, <span class="kw4">int</span> y<span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
Foo<span class="br0">(</span><span class="kw4">int</span> y<span class="br0">)</span> <span class="sy4">:</span> Foo<span class="br0">(</span><span class="st0">'a'</span>, y<span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// Foo(int) 委托到 Foo(char,int)</span>
|
|
<span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E7.BB.A7.E6.89.BF.E7.9A.84.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0">继承的构造函数</span></h4>
|
|
<p>见 <a href="cpp-language-using_declaration.html">using 声明</a>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h4><span class="mw-headline" id=".E5.88.9D.E5.A7.8B.E5.8C.96.E9.A1.BA.E5.BA.8F">初始化顺序</span></h4>
|
|
<p>列表中的成员初始化器的顺序是不相关的:初始化的实际顺序如下:</p>
|
|
<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> 最后,执行构造函数体</div>
|
|
<p>(注意:如果初始化的顺序是由不同构造函数中的成员初始化器列表中的出现所控制,那么<a href="cpp-language-destructor.html">析构函数</a>就无法确保销毁顺序是构造顺序的逆序了)</p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <fstream></span>
|
|
<span class="co2">#include <string></span>
|
|
<span class="co2">#include <mutex></span>
|
|
|
|
<span class="kw1">struct</span> Base <span class="br0">{</span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Class <span class="sy4">:</span> <span class="kw1">public</span> Base
|
|
<span class="br0">{</span>
|
|
<span class="kw4">unsigned</span> <span class="kw4">char</span> x<span class="sy4">;</span>
|
|
<span class="kw4">unsigned</span> <span class="kw4">char</span> y<span class="sy4">;</span>
|
|
<a href="cpp-thread-mutex.html"><span class="kw2154">std::<span class="me2">mutex</span></span></a> m<span class="sy4">;</span>
|
|
<a href="cpp-thread-lock_guard.html"><span class="kw2166">std::<span class="me2">lock_guard</span></span></a><span class="sy1"><</span><a href="cpp-thread-mutex.html"><span class="kw2154">std::<span class="me2">mutex</span></span></a><span class="sy1">></span> lg<span class="sy4">;</span>
|
|
<a href="cpp-io-basic_fstream.html"><span class="kw1734">std::<span class="me2">fstream</span></span></a> f<span class="sy4">;</span>
|
|
<a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> s<span class="sy4">;</span>
|
|
|
|
Class <span class="br0">(</span> <span class="kw4">int</span> x <span class="br0">)</span>
|
|
<span class="sy4">:</span> Base <span class="br0">{</span> <span class="nu0">123</span> <span class="br0">}</span>, <span class="co1">// 初始化基类</span>
|
|
x <span class="br0">(</span> x <span class="br0">)</span>, <span class="co1">// x(成员)以 x(形参)初始化</span>
|
|
y <span class="br0">{</span> <span class="nu0">0</span> <span class="br0">}</span>, <span class="co1">// y 初始化为 0</span>
|
|
f<span class="br0">{</span><span class="st0">"test.cc"</span>, std<span class="sy4">::</span><span class="me2">ios</span><span class="sy4">::</span><span class="me2">app</span><span class="br0">}</span>, <span class="co1">// 在 m 和 lg 初始化之后发生</span>
|
|
s<span class="br0">(</span>__func__<span class="br0">)</span>, <span class="co1">//__func__ 可用,因为初始化器列表是构造函数的一部分</span>
|
|
lg <span class="br0">(</span> m <span class="br0">)</span>, <span class="co1">// lg 使用已经初始化的 m</span>
|
|
m<span class="br0">{</span><span class="br0">}</span> <span class="co1">// m 在 lg 前初始化,即使它最后出现在此处</span>
|
|
<span class="br0">{</span><span class="br0">}</span> <span class="co1">// 空复合语句</span>
|
|
|
|
Class <span class="br0">(</span> <span class="kw4">double</span> a <span class="br0">)</span>
|
|
<span class="sy4">:</span> y <span class="br0">(</span> a<span class="sy2">+</span><span class="nu0">1</span> <span class="br0">)</span>,
|
|
x <span class="br0">(</span> y <span class="br0">)</span>, <span class="co1">// x 将在 y 前初始化,其值不确定</span>
|
|
lg <span class="br0">(</span> m <span class="br0">)</span>
|
|
<span class="br0">{</span><span class="br0">}</span> <span class="co1">// 基类初始化器未在列表中出现,它被默认初始化(这与使用 Base() 不同,那是值初始化)</span>
|
|
|
|
Class<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="kw1">try</span> <span class="co1">// 函数 try 块在包含初始化器列表的函数体之前开始</span>
|
|
<span class="sy4">:</span> Class<span class="br0">(</span> <span class="nu16">0.0</span> <span class="br0">)</span> <span class="co1">// 委托构造函数</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// ...</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw1">catch</span> <span class="br0">(</span>...<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 初始化中发生的异常</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>
|
|
Class c<span class="sy4">;</span>
|
|
Class c1<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span>
|
|
Class c2<span class="br0">(</span><span class="nu16">0.1</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
|
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
|
<table class="dsctable" style="font-size:0.8em">
|
|
<tr>
|
|
<th>DR</th>
|
|
<th>应用于</th>
|
|
<th>出版时的行为</th>
|
|
<th>正确行为</th>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue1696">CWG 1696</a></td>
|
|
<td>C++98</td>
|
|
<td>引用成员可被初始化为(生存期会在构造函数结尾结束的)临时量</td>
|
|
<td>这种初始化非良构</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-c++11">
|
|
<ul>
|
|
<li>C++11 标准(ISO/IEC 14882:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>12.1 Constructors [class.ctor]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>12.6.2 Initializing bases and members [class.base.init]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c++98">
|
|
<ul>
|
|
<li>C++98 标准(ISO/IEC 14882:1998):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>12.1 Constructors [class.ctor]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>12.6.2 Initializing bases and members [class.base.init]</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<ul>
|
|
<li><a href="cpp-language-copy_elision.html">复制消除</a></li>
|
|
<li><a href="cpp-language-converting_constructor.html">转换构造函数</a></li>
|
|
<li><a href="cpp-language-copy_assignment.html">复制赋值</a></li>
|
|
<li><a href="cpp-language-copy_constructor.html">复制构造函数</a></li>
|
|
<li><a href="cpp-language-default_constructor.html">默认构造函数</a></li>
|
|
<li><a href="cpp-language-destructor.html">析构函数</a></li>
|
|
<li><a href="cpp-language-explicit.html">explicit</a></li>
|
|
<li><a href="cpp-language-initialization.html">初始化</a>
|
|
<ul>
|
|
<li><a href="cpp-language-aggregate_initialization.html">聚合初始化</a></li>
|
|
<li><a href="cpp-language-constant_initialization.html">常量初始化</a></li>
|
|
<li><a href="cpp-language-copy_initialization.html">复制初始化</a></li>
|
|
<li><a href="cpp-language-default_initialization.html">默认初始化</a></li>
|
|
<li><a href="cpp-language-direct_initialization.html">直接初始化</a></li>
|
|
<li><a href="cpp-language-list_initialization.html">列表初始化</a></li>
|
|
<li><a href="cpp-language-reference_initialization.html">引用初始化</a></li>
|
|
<li><a href="cpp-language-value_initialization.html">值初始化</a></li>
|
|
<li><a href="cpp-language-zero_initialization.html">零初始化</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="cpp-language-move_assignment.html">移动赋值</a></li>
|
|
<li><a href="cpp-language-move_constructor.html">移动构造函数</a></li>
|
|
<li><a href="cpp-language-new.html">new</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|