📄 reeves.htm
字号:
<P><A NAME="dingp23"></A><A NAME="AUTO00014"></A>I differ primarily with Dr. Müller over the question of what operations are valid when applied to an object that is not in a good state. In the real world of typical C++ software, an object in an inconsistent or bad state may still be quite usable and the program in which the object is embedded may continue to run <NOBR>correctly.<SCRIPT>create_link(23);</SCRIPT>
</NOBR></P>
<P><A NAME="dingp24"></A><A NAME="AUTO00015"></A>For certain examples in the rest of this article, I use the same <CODE>Stack</CODE> template class as Dr. Müller uses in his paper. The original version of this template was presented by Tom Cargill in <A HREF="#ref1" ONMOUSEOVER = "self.status = 'Reference 1'; return true" ONMOUSEOUT = "self.status = self.defaultStatus">Reference 1</A>. The interface for this class is shown in <A HREF="#list1" ONMOUSEOVER = "self.status = 'Listing 1'; return true" ONMOUSEOUT = "self.status = self.defaultStatus">Listing 1</A>. While the <CODE>Stack</CODE> class is fairly simple, it remains a good example of the difficulties inherent in using <NOBR>exceptions.<SCRIPT>create_link(24);</SCRIPT>
</NOBR></P>
<P><A NAME="dingp25"></A><A NAME="AUTO00016"></A>A couple of brief notes about coding <NOBR>style:<SCRIPT>create_link(25);</SCRIPT>
</NOBR></P>
<OL><A NAME="dingp26"></A><LI>I prefer to use the constant symbol null to represent the <CODE>null</CODE> pointer in my code instead of the current convention of using <CODE>0</CODE>. I ask the reader to assume the following declaration exists within the scope of all the code that follows:<SCRIPT>create_link(26);</SCRIPT>
<A NAME="AUTO00148"></A><UL><PRE>
const long null = 0L; // see <SCRIPT>sendmetoo(25,6292,'E');</SCRIPT> ONMOUSEOVER = "self.status = 'Item E25'; return true" ONMOUSEOUT = "self.status = self.defaultStatus">Item E25</A> for a discussion
// of this approach
</PRE>
</UL>
<A NAME="AUTO00017"></A>
<A NAME="dingp27"></A><LI>I have adopted a commenting convention of <CODE>//>x</CODE> to indicate places in a function where exceptions are possible. Like any manual approach, this technique is error prone and very likely to miss something. It is better than nothing, however, and I have found it useful.<SCRIPT>create_link(27);</SCRIPT>
</OL>
<P><A NAME="dingp28"></A><A NAME="AUTO00018"></A>The following table summarizes the goals and guidelines that are presented in the next <NOBR>section.<SCRIPT>create_link(28);</SCRIPT>
</NOBR></P>
<A NAME="AUTO00019"></A>
<TABLE ALIGN="center" WIDTH="95%" CELLSPACING="2" CELLPADDING="2" BGCOLOR="#FFFFCC" BORDER="0">
<TR><TH COLSPAN="2" BGCOLOR="#000000"><FONT COLOR="#FFFFFF" FACE="Arial">Table: Goals and Guidelines</FONT></TH></TR>
<TR><TD VALIGN="top"><A NAME="dingp29"></A><B>I.</B></TD><TD><B>When you propagate an exception, try to leave the object in the state it had when the function was entered.</B><SCRIPT>create_link(29);</SCRIPT>
<OL VALUE="1">
<A NAME="dingp30"></A><LI> Make sure your <CODE>const</CODE> functions really are <CODE>const</CODE>.<SCRIPT>create_link(30);</SCRIPT>
<A NAME="AUTO00020"></A>
<A NAME="dingp31"></A><LI> Perform exception prone operations early, and/or through temporaries.<SCRIPT>create_link(31);</SCRIPT>
<A NAME="AUTO00021"></A>
<A NAME="dingp32"></A><LI> Watch out for side effects in expressions that might propagate exceptions.<SCRIPT>create_link(32);</SCRIPT>
<BR>
</OL></TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp33"></A><B>II.</B></TD><TD><B>If you can not leave the object in the same state it was in when the function was entered, try to leave it in a good state.</B><SCRIPT>create_link(33);</SCRIPT>
<A NAME="AUTO00022"></A>
<OL TYPE="1">
<A NAME="dingp34"></A><LI VALUE="4"> Either reinitialize the object, or mark it internally to indicate that it is no longer usable but might be recovered.<SCRIPT>create_link(34);</SCRIPT>
</OL>
<A NAME="AUTO00023"></A>
</TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp35"></A><B>III.</B></TD><TD><B>If you can not leave the object in a "good" state, make sure the destructor will still work.</B><SCRIPT>create_link(35);</SCRIPT>
<A NAME="AUTO00024"></A>
<OL TYPE="1">
<A NAME="dingp36"></A><LI VALUE="5">Do not leave dangling pointers in your objects. Delete pointers through temporaries.<SCRIPT>create_link(36);</SCRIPT>
</OL>
<A NAME="AUTO00025"></A>
</TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp37"></A><B>IV.</B></TD><TD><B>Avoid resource leaks.</B><SCRIPT>create_link(37);</SCRIPT>
<A NAME="AUTO00026"></A>
<OL TYPE="1">
<A NAME="AUTO00027"></A>
<A NAME="dingp38"></A><LI VALUE="6">If you have raw data pointers as members, initialize them to null in the initializer list of your constructor(s), then do necessary allocations in the constructor body where a catch block can deal with potential resource leaks.<SCRIPT>create_link(38);</SCRIPT>
</OL>
<A NAME="AUTO00028"></A>
</TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp39"></A><B>V.</B></TD><TD> <B>Do not catch any exception you do not have to.</B><SCRIPT>create_link(39);</SCRIPT>
<A NAME="AUTO00029"></A><P>
<OL TYPE="1">
<A NAME="AUTO00030"></A>
<A NAME="dingp40"></A><LI VALUE="7">Rewrite functions to preserve state, if possible.<SCRIPT>create_link(40);</SCRIPT>
<A NAME="AUTO00031"></A>
<A NAME="dingp41"></A><LI VALUE="8">Always use a catch <CODE>(...)</CODE> <CODE>block</CODE> to cope with propagating exceptions.<SCRIPT>create_link(41);</SCRIPT>
<A NAME="AUTO00032"></A>
<A NAME="dingp42"></A><LI VALUE="9">If you get stuck, call <CODE>terminate()</CODE>.<SCRIPT>create_link(42);</SCRIPT>
</OL>
<A NAME="AUTO00033"></A>
</TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp43"></A><B>VI.</B></TD><TD><B> Do not hide exception information from other parts of the program that
might need it.</B><SCRIPT>create_link(43);</SCRIPT>
<A NAME="AUTO00034"></A>
<OL TYPE="1">
<A NAME="dingp44"></A><LI VALUE="10"> Always rethrow the exception caught in a catch (<CODE>(...)</CODE> <CODE>block</CODE>).<SCRIPT>create_link(44);</SCRIPT>
<A NAME="AUTO00035"></A>
<A NAME="dingp45"></A><LI VALUE="11"> Rethrow a different exception only to provide additional information or capability.<SCRIPT>create_link(45);</SCRIPT>
<A NAME="AUTO00036"></A>
<A NAME="dingp46"></A><LI VALUE="12"> Make sure one catch <CODE>block</CODE> does not hide another.<SCRIPT>create_link(46);</SCRIPT>
</OL>
</P>
<A NAME="AUTO00037"></A>
</TD></TR>
<TR><TD VALIGN="top"><A NAME="dingp47"></A><B>VII.</B></TD><TD> <B>Never depend upon destructors for functionality in any situation where
fault-tolerance is required.</B><SCRIPT>create_link(47);</SCRIPT>
<A NAME="AUTO00038"></A>
<OL TYPE="1">
<A NAME="dingp48"></A><LI VALUE="13"> Do not throw exceptions from a destructor body.<SCRIPT>create_link(48);</SCRIPT>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -