⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- -*-html-*-
	$Source: /usr/local/cvsroot/BigC++/19/index.html,v $
	$Revision: 1.7 $
	Big C++, chptr 19
	editor: cols=80, tabstop=2

	(c) 2005 John Wiley & Sons
	Kurt Schmidt, kschmidt@cs.drexel.edu

	NOTES
	- 3 spaces are used for each indent in examples

	REVISIONS
		12/14 - Creation
		1/4/04 - Removed sloppy comments, upped <h1>
		1/10/04 - fixed spelling
		$Log: index.html,v $
		Revision 1.7  2004/04/12 05:00:40  kurt
		added copyright meta tags
		
		Revision 1.6  2004/03/29 05:49:15  kurt
		Pared language, fixed tabs (spaces), added copyright to comments
		
-->

<html>

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name='Copyright' content='2005 John Wiley & Sons'>
  <meta name='Author' content='Kurt Schmidt'>
	<script language="JavaScript" src="./config.js"></script>
	<script language="JavaScript" src="./pageFormat.js"></script>
	<script><!-- // Set title on browser window
		 title()
	//--></script>
</head>

<body>


<h2><font color="#009999" size="+3">Chapter 19 - Exception
	Handling</font></h2>
<font size="+1">

<script><!--
   image( "cover.png" )
//--></script>

</font>

<hr><h2><font color="#009999" size="+2">Chapter Goals</font></h2>
<hr noshade size="4" color="#009999">

<ul>
	<li>To understand how exceptional conditions can arise within a program</li>
	<li>To understand how dealing with exceptional conditions can make your
		programs more reliable and robust</li>
	<li>To learn how to use a variety of mechanisms to handle exceptional
		conditions</li>
	<li>To understand how to use try blocks and catch handlers in your own
		programs</li>
</ul>

</font>

<hr><h2><font color="#009999">19.1 Handling Exceptional
	Situations</font></h2>
<font size="+1">

<ul>
	<li>Things sometimes go wrong.  E.g.,
		<ul>
			<li>User input errors</li>
			<li>Device errors</li>
			<li>Physical limitations</li>
			<li>Component (sw) failures</li>
		</ul>
	</li>
	<li>Importance increases as complexity of systems increases</li>
</ul>

</font>

<hr><h2><font color="#009999">19.1 Handling Exceptional
	Situations (cont.)</font></h2>
<font size="+1">

<ul>
	<li>Some different approaches we've seen to handling exceptional conditions:
		<ul>
			<li>The <tt>fail</tt> predicate used by the <tt>stream</tt> I/O
				library</li>
			<li>The <tt>assert</tt> macro</li>
		</ul>
	</li>
	<li>Some errors can be detected and resolved at the point they occur</li>
	<li>Others are <i>non-local</i>; i.e., must be resolved at a higher-level</li>
</ul>

</font>

<hr><h2><font color="#009999">19.1 Handling Exceptional
	Situations - Example</font></h2>
<font size="+1">

<p>Consider a container class (chptr. 16), and programmers P1 and P2:</p>

<ul>
	<li>P1 develops a stack that P2 will use</li>
	<li>P2 is ignorant of the implementation details, needs only the
		interface:

		<blockquote>
<pre>Stack s;
s.push(3.14);
s.push(1.41);
s.push(2.76);
while (s.size() &gt; 0)
{
   cout &lt;&lt; s.top() &lt;&lt; "\n";
   s.pop();
}</pre>
		</blockquote>

	</li>
</ul>

</font>

<hr><h2><font color="#009999">19.1 Handling Exceptional
	Situations - Example</font></h2>
<font size="+1">

<ul>
	<li>Imagine that <tt>pop</tt> is called on an empty <tt>Stack</tt>
		<ul>
			<li>P2 didn't understand the i/f, or</li>
			<li>P2 wrote a function that had a logic error</li>
		</ul>
	</li>
	<li>P1 is unaware of the application P2 is creating</li>
	<li>P2 is in a better position to recover from the error</li>
	<li><tt>Stack</tt> must report the error to the application written by
		P2</li>
</ul>

</font>

<hr><h2><font color="#009999">19.2 Alternative Mechanisms for Handling
	Exceptions</font></h2>
<font size="+1">

<p>Alternative (historical) ways of handling exceptional conditions:</p>

<ul>
	<li>Assume errors will not occur</li>
	<li>Print an error message</li>
	<li>Special return values</li>
	<li>External flags</li>
	<li>Use <tt>assert</tt> to halt execution</li>
	<li>Error Handlers (callback functions</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3 Exceptions</font></h2>
<font size="+1">

<p><tt>try-catch-throw</tt> mechanism</p>

<ul>
	<li>Later addition to C++</li>
	<li>An error is signaled by <i>throwing an exception</i></li>
	<li>Any type can be thrown</li>
	<li>If not handled (<i>caught</i>) locally, function exits</li>
	<li>Does not return to caller</li>
	<li>Unwinds call stack, looking for an appropriate handler</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3 Exceptions</font></h2>
<font size="+1">

<table border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 19.1:
			Throwing an Exception</font>

<pre>throw <i>expression</i>;</pre>

			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td><font size="+1">
						<pre>throw logic_error("illegal future_value parameter");</pre>
						</font>
					</td>
				</tr>
				<tr>
					<td><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Abandon this function and throw a value
						to an exception handler.</font></td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">19.3 Exceptions - Example</font></h2>
<font size="+1">

<blockquote>
<pre>double future_value(double initial_balance, double p, int n)
{
   if (p &lt; 0 || n &lt; 0)
   {
      logic_error description("illegal future_value parameter");
      <b><font color="#009999">throw</font></b> description;
   }
   return initial_balance * pow(1 + p / 100, n);
}</pre>
</blockquote>

<p><font color="#009999"><b>Note:</b></font>  <tt>logic_error</tt> is a
standard exception class, declared in <tt>&lt;stdexcept&gt;</tt></p>

</font>

<hr><h2><font color="#009999">19.3.1 Catching Exceptions</font></h2>
<font size="+1">

<ul>
	<li>Supply a handler with the <tt>try</tt> statement:
	
		<blockquote>
<pre>try
{
   <i>code</i>
}
catch (logic_error&amp; e)
{
   <i>handler</i>
}</pre>
		</blockquote>

	</li>
	<li>If an error is thrown in the <tt>try</tt> clause, execution goes to
		the <tt>catch</tt> clause</li>
	<li>If no appropriate handler is found, the next outer <tt>try</tt> block
		is examined</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3.1 Catching Exceptions - Syntax
	</font></h2>
<font size="+1">

<table width='100%' border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">Syntax 19.2 :
			<tt>try</tt> Block</font>

<pre>try
{
   <i>statements</i>
}
catch (<i>type_name</i><sub>1</sub> <i>variable_name</i><sub>1</sub>)
{
   <i>statements</i>
}
catch (<i>type_name</i><sub>2</sub> <i>variable_name</i><sub>2</sub>)
{
   <i>statements</i>
}
...
catch (<i>type_name</i><sub><i>n</i></sub> <i>variable_name</i><sub><i>n</i></sub>)
{
	<i>statements</i>
}</pre>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">19.3.1 Catching Exceptions - Syntax (cont.)
	</font></h2>
<font size="+1">

<table border="1" cellpadding="4" bgcolor="#00cccc">
	<tr>
		<td bgcolor="#ffffff"><font size="+1"><font color="#009999">
				Syntax 19.2 (cont.)
			<table border="0" cellpadding="4">
				<tr>
					<td valign="top"><font size="+1" color="#009999">
						Example:</font></td>
					<td><font size="+1">

<pre>try
{
   List staff = read_list();
   process_list(staff);
}
catch (logic_error&amp; e)
{
   cout &lt;&lt; "Processing error " &lt;&lt; e.what() &lt;&lt; "\n";
}</pre>
						</font>
					</td>
				</tr>
				<tr>
					<td><font size="+1" color="#009999">Purpose:</font></td>
					<td><font size="+1">Provide one or more handlers for types of
						exceptions that may be thrown when executing a block of statements.
						</font></td>
				</tr>
			</table>
			</font>
		</td>
	</tr>
</table>

</font>

<hr><h2><font color="#009999">19.3.1 <tt>try</tt> Block -
	Example</font></h2>
<font size="+1">

<ul>
	<li>Place a handler into the main function that:
 		<ul>
			<li>tells the user that something has gone wrong, and</li>
			<li>offers a chance to try again with different inputs:</li>
		</ul>
	</li>
	<li>Handler inspects the object thrown</li>
	<li><tt>catch</tt> clause resembles a function, w/out a return</li>
	<li><tt>catch</tt> calls the <tt>what</tt> member of <tt>logic_error</tt>
		<ul>
			<li><tt>what</tt> returns the string passed to <tt>e</tt>'s c'tor</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3.1 <tt>try</tt> Block -
	Example</font></h2>
<font size="+1">

<blockquote>
<pre>int main()
{
   bool more = true;
   while (more)
   {
      try
      {
         <i>code</i>
      }
      catch (logic_error&amp; e)
      {
         cout &lt;&lt; "A logic error has occurred: "
            &lt;&lt; e.what() &lt;&lt; "\n" &lt;&lt; "Retry? (y/n)";
         string input;
         getline(cin, input);
         if (input == "n") more = false;
      }
   }
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">19.3.2 Values Thrown and Caught</font></h2>
<font size="+1">

<ul>
	<li>Can throw (and catch) any type, including integer</li>
	<li>User-defined objects are commonly thrown</li>
	<li>Implicit conversion (e.g., <tt>int</tt> to <tt>double</tt>)
		not performed on thrown values</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3.2 Values Thrown and Caught
	(cont.)</font></h2>
<font size="+1">

<p>This doesn't work as intended:</p>

<blockquote>
<pre>try
{
   . . .
   throw "Stack Underflow";
   . . .
}
catch (string err)
{
   cerr &lt;&lt; err &lt;&lt; "\n";
}</pre>
</blockquote>

</font>

<hr><h2><font color="#009999">19.3.2 (cont.) Throwing Objects 
	</font></h2>
<font size="+1">

<p>Users often define their own exceptions:</p>

	<blockquote>
<pre>class MyApplicationError
{
public:
   MyApplicationError(const string&amp; r);
   string&amp; what() const;
private:
   string reason;
};

MyApplicationError::MyApplicationError(const string&amp; r)
   : reason(r) {}

string&amp; what() const
{
   return reason;
}</pre>
	</blockquote>

</font>

<hr><h2><font color="#009999">19.3.2 (cont.) Throwing Objects 
	</font></h2>
<font size="+1">

<p>Errors are now indicated by throwing an instance of this class:</p>

	<blockquote>
<pre>try
{
   . . .
   throw MyApplicationError("illegal value");
   . . .
}
catch (MyApplicationError&amp; e)
{
   cerr &lt;&lt; "Caught exception " &lt;&lt; e.what() &lt;&lt; "\n";
}</pre>
	</blockquote>

</font>

<hr><h2><font color="#009999">19.3.2 (cont.) Objects
	as Exceptions</font></h2>
<font size="+1">

<ul>
	<li>We usually catch references:
		<ul>
			<li>Efficiency</li>
			<li>Avoid slicing objects of inherited classes</li>
		</ul>
	</li>
	<li>Use inheritance for exceptions:
		<ul>
			<li>Reuse</li>
			<li>Standard interface</li>
			<li>Create categories, so handlers can be broad or specific</li>
		</ul>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3.2 (cont.) Standard exception hierarchy
	(partial), in <tt>&lt;stdexcept&gt;</tt></font></h2>
<font size="+1">

<script><!-- 
	image( "fig1.png" )
//--></script>

</font>

<hr><h2><font color="#009999">19.3.2 (cont.) Inheriting From
	Standard Exceptions</font></h2>
<font size="+1">

<ul>
	<li>Use library exceptions as-is (see initial example), or</li>
	<li>Inherit from these to create further specialized categories:

		<blockquote>
<pre>class FutureValueError : public logic_error
{
public:
   FutureValueError(string reason);
};

FutureValueError::FutureValueError(string reason)
   : logic_error(reason) {}</pre>
		</blockquote>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -