📄 [11] destructors, c++ faq lite.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0043)http://www.sunistudio.com/cppfaq/dtors.html -->
<HTML><HEAD><TITLE>[11] Destructors, C++ FAQ Lite</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META http-equiv=Content-Language content=zh-cn>
<META content=dtors.html name=FILENAME>
<META content="[11] Destructors, C++ FAQ Lite" name=ABSTRACT>
<META content=cline@parashift.com name=OWNER>
<META content="Marshall Cline, cline@parashift.com" name=AUTHOR>
<META content="MSHTML 6.00.2462.0" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><LINK rev=made
href="mailto:cline@parashift.com"><LINK
href="[11] Destructors, C++ FAQ Lite.files/cpp-faq.css" type=text/css
rel=stylesheet></HEAD>
<BODY>
<H1><A name=top></A>[11] 析构函数<BR><SMALL><SMALL>(Part of <A
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A>, <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">Copyright ©
1991-2001</A>, <A href="http://www.parashift.com/" target=OutsideTheFAQ>Marshall
Cline</A>, <A
href="mailto:cline@parashift.com">cline@parashift.com</A>)</SMALL></SMALL></H1>
<P>简体中文版翻译:<A href="http://www.sunistudio.com/nicrosoft">申旻</A>,<A
href="mailto:nicrosoft@sunistudio.com">nicrosoft@sunistudio.com</A>(<A
href="http://www.sunistudio.com/">东日制作室</A>,<A
href="http://www.sunistudio.com/asp/sunidoc.asp">东日文档</A>)</P>
<HR>
<H3>FAQs in section [11]:</H3>
<UL>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.1]">[11.1]
析构函数做什么?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.2]">[11.2]
局部对象析构的顺序是什么?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.3]">[11.3]
数组中的对象析构顺序是什么?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.4]">[11.4]
我能重载类的析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.5]">[11.5]
我可以对局部变量显式调用析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.6]">[11.6]
如果我要一个局部对象在其被创建的代码块的 } 之前被析构,如果我真的想这样,能调用其析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.7]">[11.7]
好,好;我不显式调用局部对象的析构函数;但如何处理上面那种情况?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.8]">[11.8]
如果我无法将局部对象包裹于人为的块中,怎么办?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.9]">[11.9] 如果我是用
<TT>new </TT>分配对象的,可以显式调用析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.10]">[11.10]
什么是“定位放置 <TT>new</TT>(placement <TT>new</TT> )”,为什么要用它?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.11]">[11.11]
编写析构函数时,需要显式调用成员对象的析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.12]">[11.12]
当我写派生类的析构函数时,需要显式调用基类的析构函数吗?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.13]">[11.13]
当析构函数检测到错误时,可以抛出异常吗?</A> <IMG alt=NEW!
src="[11] Destructors, C++ FAQ Lite.files/new.gif"> </LI></UL>
<P>
<HR>
<P><A name=[11.1]></A>
<DIV class=FaqTitle>
<H3>[11.1] 析构函数做什么?</H3></DIV>
<P>析构函数为对象举行葬礼。
<P>析构函数用来释放对象所分配的资源。举例来说,<TT>Lock
</TT>类可能锁定了一个信号量,那么析构函数将释放该信号量。最通常的例子是,当构造函数中使用了<TT>new</TT>,那么析构函数则使用<TT>delete</TT>。
<P>析构函数是“准备后事”的成员函数。经常缩写成“dtor”。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.2]></A>
<DIV class=FaqTitle>
<H3>[11.2] 局部对象析构的顺序是什么?</H3></DIV>
<P>与构造函数反序:先构造,后析构。
<P>以下的例子中,<TT>b</TT><TT> </TT>的析构函数会被首先执行,然后是 <TT>a </TT>的析构函数:
<P>
<DIV
class=CodeBlock><TT> void userCode()<BR> {<BR> Fred a;<BR> Fred b;<BR> </TT><EM>// ...</EM><TT><BR> }
</TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.3]></A>
<DIV class=FaqTitle>
<H3>[11.3] 数组中的对象析构顺序是什么?</H3></DIV>
<P>与构造函数反序:先构造,后析构。
<P>以下的例子中,析构的顺序是<TT>a[9]</TT>, <TT>a[8]</TT>, ..., <TT>a[1]</TT>, <TT>a[0]</TT>:
<P>
<DIV
class=CodeBlock><TT> void userCode()<BR> {<BR> Fred a[10];<BR> </TT><EM>// ...</EM><TT><BR> }
</TT></DIV>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.4]></A>
<DIV class=FaqTitle>
<H3>[11.4] 我能重载类的析构函数吗?</H3></DIV>
<P>不行。
<P><TT>Fred</TT><TT>
</TT>类只能有一个析构函数。它只能是<TT>Fred::~Fred()</TT>。不带任何参数,不返回任何东西(译注:void也不行)。
<P>由于你<A
href="http://www.sunistudio.com/cppfaq/dtors.html#[11.5]">不会显式地调用析构函数</A>(是的,<A
href="http://www.sunistudio.com/cppfaq/dtors.html#[11.10]">永远不会</A>),因此无论如何不能传递参数给析构函数。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.5]></A>
<DIV class=FaqTitle>
<H3>[11.5] 我可以对局部变量显式调用析构函数吗?</H3></DIV>
<P>不行!
<P>在创建该局部对象的代码块的 <TT>}
</TT>处,析构函数会再次被调用。这是语言所保证的;自动发生。没有办法阻止它。但两次调用同一个对象的析构函数,你得到的真是坏的结果!砰!你完蛋了!
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.6]></A>
<DIV class=FaqTitle>
<H3>[11.6] 如果我要一个局部对象在其被创建的代码块的 <TT>}</TT>之前被析构,如果我真的想这样,能调用其析构函数吗?</H3></DIV>
<P>不行![详见 <A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.5]">前一个FAQ<!--rawtext:[11.5]:rawtext--></A>].
<P>假设析构 <TT>File </TT>对象的作用是关闭文件。现在假定你有一个 <TT>File</TT><TT> </TT>类的对象
<TT>f</TT>,并且你想 <TT>File</TT> <TT>f </TT>在 <TT>f </TT>对象的作用范围结束(也就是 <TT>}
</TT>)之前被关闭:
<P>
<DIV
class=CodeBlock><TT> void someCode()<BR> {<BR> File f;<BR> <BR> </TT><EM>// ... [这些代码在
<TT>f
</TT>打开的时候执行] ...</EM><TT><BR> <BR> </TT><EM>// <— 希望在此处关闭
<TT>f</TT></EM><TT><BR> <BR> </TT><EM>// ... [这些代码在
<TT>f</TT> 关闭后执行] ...</EM><TT><BR> } </TT></DIV>
<P>对这个问题<A
href="http://www.sunistudio.com/cppfaq/dtors.html#[11.7]">有一个简单的解决方案</A>。但现在请记住:<I><A
href="http://www.sunistudio.com/cppfaq/dtors.html#[11.5]">不要显式调用析构函数</A>!</I>
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/dtors.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/dtors.html#bottom">Bottom</A> | <A
href="http://www.sunistudio.com/cppfaq/ctors.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/assignment-operators.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[11.7]></A>
<DIV class=FaqTitle>
<H3>[11.7] 好,好;我不显式调用局部对象的析构函数;但如何处理上面那种情况?</H3></DIV>
<P>[内容详见 <A href="http://www.sunistudio.com/cppfaq/dtors.html#[11.6]">前一个 FAQ<!--rawtext:[11.6]:rawtext--></A>].
<P>只要将局部对象的生命期长度包裹于一个人为的 <TT>{</TT>...<TT>} </TT>块中:
<P>
<DIV
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -