📄 index.html
字号:
<!-- -*-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() > 0)
{
cout << s.top() << "\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 < 0 || n < 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><stdexcept></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& 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& e)
{
cout << "Processing error " << e.what() << "\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& e)
{
cout << "A logic error has occurred: "
<< e.what() << "\n" << "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 << err << "\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& r);
string& what() const;
private:
string reason;
};
MyApplicationError::MyApplicationError(const string& r)
: reason(r) {}
string& 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& e)
{
cerr << "Caught exception " << e.what() << "\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><stdexcept></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 + -