📄 [17] exceptions and error handling, 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=(0048)http://www.sunistudio.com/cppfaq/exceptions.html -->
<HTML><HEAD><TITLE>[17] Exceptions and error handling, C++ FAQ Lite</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META http-equiv=Content-Language content=zh-cn>
<META content=exceptions.html name=FILENAME>
<META content="[17] Exceptions and error handling, 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="[17] Exceptions and error handling, C++ FAQ Lite.files/cpp-faq.css"
type=text/css rel=stylesheet></HEAD>
<BODY>
<H1><A name=top></A>[17] 异常和错误处理<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 [17]:</H3>
<UL>
<LI><A href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.1]">[17.1]
<TT>try</TT> / <TT>catch</TT> / <TT>throw</TT> 通过哪些方法来改善软件质量?</A> <IMG
alt=NEW! src="[17] Exceptions and error handling, C++ FAQ Lite.files/new.gif">
<LI><A href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.2]">[17.2]
如何处理构造函数的失败?</A> <IMG alt=UPDATED!
src="[17] Exceptions and error handling, C++ FAQ Lite.files/updated.gif">
<LI><A href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.3]">[17.3]
如何处理析构函数的失败?</A> <IMG alt=NEW!
src="[17] Exceptions and error handling, C++ FAQ Lite.files/new.gif">
<LI><A href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.4]">[17.4]
如果构造函数会抛出异常,我该怎样处理资源?</A>
<LI><A href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.5]">[17.5]
当别人抛出异常时,我如何改变字符数组的字符串长度来防止内存泄漏?</A><IMG alt=UPDATED!
src="[17] Exceptions and error handling, C++ FAQ Lite.files/updated.gif">
</LI></UL>
<P>
<HR>
<P><A name=[17.1]></A>
<DIV class=FaqTitle>
<H3>[17.1] <TT>try</TT> / <TT>catch</TT> / <TT>throw</TT> 通过哪些方法来改善软件质量? <IMG
alt=NEW!
src="[17] Exceptions and error handling, C++ FAQ Lite.files/new.gif"></H3></DIV><SMALL><EM>[Recently
created (on 7/00). <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.2]">Click here to go
to the next FAQ in the "chain" of recent
changes<!--rawtext:[17.2]:rawtext--></A>.]</EM></SMALL>
<P>通过排除使用<TT>if</TT>语句的一个理由。
<P>代替 <TT>try</TT> / <TT>catch</TT> / <TT>throw</TT>
的通常做法是返回一个返回代码(有时称为错误代码),调用者通过诸如<TT>if</TT>的条件语句明确地测试。例如,<TT>printf()</TT>,
<TT>scanf()</TT> 和 <TT>malloc()</TT>就是这样工作的:调用者被假定为会测试返回值来判断函数是否成功。
<P>尽管返回代码技术有时是最适当的错误处理技术,但会产生增加不必要的<TT>if</TT>语句这样的令人讨厌的效果。
<UL>
<LI><B>质量降级:</B>众所周知,条件语句可能包含的错误大约十倍于其他类型的语句。因此,在其他都相同时,如果你能从代码中消除条件语句,你会得到更健壮的代码。
<LI><B>推迟面市:</B>由于条件语句是分支点,而它们关系到白盒法测试时的测试条件的个数,因此不必要的条件语句会增加测试的时间总量。如果你没有走过每个分支点,那么你的代码中就会有在测试中没有被执行过的指令,直到用户/客户发现它,那就糟了。
<LI><B>增加开发成本:</B>不必要的控制流程的复杂性增加了寻找bug,修复bug,和测试的工作。 </LI></UL>
<P>因此,相对于通过返回代码和<TT>if</TT>来报告错误,使用<TT>try</TT> / <TT>catch</TT> /
<TT>throw</TT>所产生更少有bug,更低的开发成本和更快面市的代码。当然,如果你的团队没有任何使用<TT>try</TT> /
<TT>catch</TT> /
<TT>throw</TT>的经验,你也许想先在一个玩具性的项目上使用一下,以便确定你明白正在做的事情——在把武器拿上真枪实弹的前线前,总应该演练一下吧。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/freestore-mgmt.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/const-correctness.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[17.2]></A>
<DIV class=FaqTitle>
<H3>[17.2] 如何处理构造函数的失败? <IMG alt=UPDATED!
src="[17] Exceptions and error handling, C++ FAQ Lite.files/updated.gif"></H3></DIV><SMALL><EM>[Recently
fixed typo ("its" <I>vs.</I> "it's") thanks to <A
href="mailto:wbemont@clearcommerce.com">Wes Bemont</A> (on 4/01). <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#[17.3]">Click here to go
to the next FAQ in the "chain" of recent
changes<!--rawtext:[17.3]:rawtext--></A>.]</EM></SMALL>
<P>抛出一个异常。
<P>构造函数没有返回类型,所以返回错误代码是不可能的。因此抛出异常是标记构造函数失败的最好方法。
<P>如果你没有或者不愿意使用异常,这里有一种方法。如果构造函数失败了,构造函数可以把对象带入一种“僵尸”状态。你可以通过设置一个内部状态位使对象就象死了一样,即使从技术上来说,它仍然活着。然后加入一个查询(“检察员”)成员函数,以便类的用户能够通过检查这个“僵尸位”来确定对象是真的活着还是已经成为僵尸(也就是一个“活着的死对象”)。你也许想有另一个成员函数来检查这个僵尸位,并且当对象并不是真正活着的时候,执行一个
no-op(或者是更令人讨厌的如 <TT>abort()</TT>)。这样做真的不漂亮,但是如果你不能(或者不想)使用异常的话,这是最好的方法了。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/exceptions.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/freestore-mgmt.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/const-correctness.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[17.3]></A>
<DIV class=FaqTitle>
<H3>[17.3] 如何处理析构函数的失败?<IMG alt=NEW!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -