📄 index.html
字号:
<ul>
<li>No added attributes or functionality</li>
<li>C'tor passes its argument to its parent class' c'tor</li>
</ul>
</li>
<li>All subclasses of <tt>exception</tt> have a <tt>what()</tt> method</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.2 (cont.) Exceptions & Inheritance
</font></h2>
<font size="+1">
<ul>
<li>Can still be caught with:
<blockquote><tt>
catch (logic_error& e)
</tt></blockquote>
</li>
<li>Or, can be caught with:
<blockquote><tt>
catch (FutureValueError& e)
</tt></blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.2 Exceptions & Inheritance (cont.)
</font></h2>
<font size="+1">
<ul>
<li>Or, do both:
<blockquote>
<pre>try
{
<i>code</i>
}
<font color="#0000cc">// only catches FutureValueError</font>
catch (FutureValueError& e)
{ <i>handler<sub>1</sub></i> }
<font color="#0000cc">// catches all other logic_error</font>
catch (logic_error& e)
{ <i>handler<sub>2</sub></i> }
catch (bad_alloc& e)
{ <i>handler<sub>3</sub></i> }</pre>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.2 (cont.) <tt>catch</tt> Clauses
</font></h2>
<font size="+1">
<ul>
<li>Examined top to bottom</li>
<li>Executes the first handler that matches, then stops processing
that exception</li>
<li>Match derived class before its base class</li>
<li>If uncaught, the previous try block is examined</li>
<li>If call stack is unwound, <tt>std::terminate</tt> is called</li>
<li>May specify your own by using <tt>std::set_terminate</tt></li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.2 (cont.) Example - <tt>catch</tt>
Clauses </font></h2>
<font size="+1">
<p>Consider the function <tt>process_record</tt>, which calls <tt>read</tt>,
which in turn calls <tt>future_value</tt>, which throws an exception. Who
catches it?</p>
<blockquote>
<pre>void process_record()
{
try
{
read();
}
catch (logic_error& e)
{
cout << "caught logic_error " << e.what() << "\n";
}
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.2 (cont.) Example - <tt>catch</tt>
Clauses </font></h2>
<font size="+1">
<blockquote>
<pre>void read()
{
try
{
. . .
double d = future_value();
}
catch (bad_alloc& e)
{
cout << "caught bad_alloc error " << e.what() << "\n";
}
}
double future_value(...)
{
. . .
throw FutureValueError("illegal future_value parameter");
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.2 (cont.) <tt>catch(...)</tt>,
rethrow</font></h2>
<font size="+1">
<ul>
<li><tt>catch(...)</tt> used to catch any exception</li>
<li>Should be last in list</li>
<li>Exception unnamed</li>
<li>Use <tt>throw</tt> w/no arguments to rethrow error</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.2 <tt>catch(...)</tt>, rethrow (cont.)
</font></h2>
<font size="+1">
<blockquote>
<pre>try
{
<i>code</i>
}
catch (FutureValueError& e)
{
<i>statements<sub>1</sub></i>
}
catch (...) // Catch any remaining exceptions
{
<i>statements<sub>2</sub></i>
throw; // Rethrow the error
}</pre>
</blockquote>
<font size="+0"><font color="#009999">(See 19.3.3 for example)</font></font>
</font>
<hr><h2><font color="#009999">Common Error 19.2</font></h2>
<font size="+1">
<font color="#009999"><font size=+2>Throwing Objects versus Throwing Pointers
</font></font>
<ul>
<li>Compare the following:
<blockquote>
<ol type="a">
<li><tt>throw FutureValueError("illegal parameter");</tt></li>
<li><tt>throw <b><font color="#009999">new</font></b>
FutureValueError("illegal parameter");</tt></li>
</ol>
</li>
<li><b>b.</b> must be caught like this:
<blockquote><tt>
catch (FutureValueError* e) ...
</tt></blockquote>
(or a ptr to a parent class)
</li>
<li>Who deletes the object?</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.3 Stack Unwinding</font></h2>
<font size="+1">
<font color="#009999"><p>Example: reading input</p></font>
<ul>
<li><tt>Product::read</tt> attempts to read a single <tt>Product</tt> from
input</li>
<li>Returns <tt>false</tt> on the expected end of input</li>
<li>Throws an exception if an error has occurred:</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.3 Stack Unwinding (cont.)</font></h2>
<font size="+1">
<blockquote>
<pre>bool Product::read(fstream& fs)
{
getline(fs, name);
if (name == "") return false; <font color="#0000cc">// End of file</font>
fs >> price >> score;
if (fs.fail())
throw runtime_error("Error while reading product");
string remainder;
getline(fs, remainder);
return true;
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.3 Stack Unwinding (cont.)
</font></h2>
<font size="+1">
<ul>
<li>C++ unwinds call stack in search of a try block to handle the
exception</li>
<li>Before each function is terminated, destructors are called on all
stack variables</li>
<li>First-class types don't have destructors:
<blockquote>
<pre>Product* p = new Product();
if (p->read())
{
. . .
}
delete p; <font color="#0000cc">// Never executes if read throws an exception</font>
</blockquote>
</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.3 (cont.) Exceptions and Cleaning
Up</font></h2>
<font size="+1">
<ol>
<li>Make sure all stack values are instances of a class, or</li>
<li>Catch the error, clean up, and rethrow the error:
<blockquote>
<pre>Product* p = NULL;
try
{
p = new Product();
if (p->read())
{ . . . }
delete p;
}
catch (...)
{
delete p;
throw;
}</pre>
</blockquote>
</li>
</ol>
</font>
<hr><h2><font color="#009999">19.3.4 Exceptions and Constructors /
Destructors</font></h2>
<font size="+1">
<ul>
<li>C'tors and d'tors do not return a value</li>
<li>Throwing an exception is a clean way to indicate failure
<ul>
<li><font color="#009999">Caveat:</font> Static values are initialized
before <tt>main</tt> is entered. There is no try block to catch
exceptions</li>
</ul>
</li>
<li>If a c'tor fails, the object is not created
<ul>
<li>The d'tor isn't called</li>
<li>Subtle source of leaks</li>
(See next slide)
</ul>
</li>
<li>Two concurrent exceptions will halt the program
<ul>
<li>Don't throw exceptions from within a d'tor</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.4 (cont.) Memory Leak in a
Constructor</font></h2>
<font size="+1">
<blockquote>
<pre>class DataArray
{
public:
DataArray(int s);
~DataArray();
void init(int s);
private:
int* data;
};</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.4 Memory Leak in a
Constructor (cont.)</font></h2>
<font size="+1">
<blockquote>
<pre>DataArray::DataArray(int s)
{
data = new int[s];
init(s); <font color="#0000cc">// What happens if init throws exception?</font>
}
DataArray::~DataArray()
{
delete[] data;
}
void DataArray::init(int s) throw (overflow_error)
{ . . . }</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.4 Memory Leak in a Constructor
(cont.)</font></h2>
<font size="+1">
<p>Here's one solution:</p>
<blockquote>
<pre>DataArray::DataArray(int s)
{
data = new int[s];
try
{
init(s);
}
catch (...) <font color="#0000cc">// Catch any exception init throws</font>
{
delete[] data;
data = NULL;
throw; <font color="#0000cc">// Rethrow exception</font>
}
}</pre>
</blockquote>
</font>
<hr><h2><font color="#009999">19.3.5 Exception Specifications</font></h2>
<font size="+1">
<ul>
<li>Uncaught exceptions can be dangerous (Ariane rocket)</li>
<li>Exceptions thrown by a function or method can be specified:</li>
<li>An empty list denotes that no exceptions are thrown:
<blockquote><tt>
void process_products(fstream& fs) throw ()
</tt></blockquote>
</li>
<li>A function w/no <tt>throw</tt> specification can throw any exception</li>
</ul>
</font>
<hr><h2><font color="#009999">19.3.5 Exception Specifications (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.3 :
Exception Specification</font>
<pre><i>return_type function_name</i>(<i>parameters</i>)
throw (<i>type_name<sub>1</sub>, type_name<sub>2</sub>, ..., type_name<sub>n</sub></i>)
}</pre>
<table border="0" cellpadding="4">
<tr>
<td valign="top"><font size="+1" color="#009999">
Example:</font></td>
<td><font size="+1">
<pre>void process_products(fstream& fs)
throw (UnexpectedEndOfFile, bad_alloc)</pre>
</font>
</td>
</tr>
<tr>
<td><font size="+1" color="#009999">Purpose:</font></td>
<td><font size="+1">List the types of all exceptions that a function
can throw.</font></td>
</tr>
</table>
</font>
</td>
</tr>
</table>
</font>
<hr><h2><font color="#009999">19.3.5 Exception
Specifications (cont.)</font></h2>
<font size="+1">
<p>Caveats:</p>
<ul>
<li>Compiler does not enforce them
<ul>
<li>If a function indirectly throws an exception not in its specification,
the program is halted</li>
</ul>
</li>
<li>Specifications are not tied to function signatures during inheritance
<ul>
<li>An override in a derived class can throw an exception not specified
in the base class definition</li>
</ul>
</li>
</ul>
</font>
<hr><h2><font color="#009999">19.4 Case Study: Matrices</font></h2>
<font size="+1">
<ul>
<li>Define 2 new classes:
<ul>
<li><tt>MatrixMismatchException</tt>, inherits from the standard class
<tt>invalid_argument</tt></li>
<li><tt>MatrixIndexExceptions</tt>, inherits from <tt>out_of_range</tt>
<ul>
<li>C'tor also takes the offending index value</li>
<li>Uses a private method to append index to string before calling
the base-class c'tor</li>
</ul>
</li>
</ul>
</li>
<li>The test program has an example of using a single catch clause to catch
both of these exceptions</li>
</ul>
</font>
<hr><h2><font color="#009999">19.4 Case Study: Matrices
(<tt>matrix3.h</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrix3.h", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">19.4 Case Study: Matrices
(<tt>matrix3.cpp</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrix3.cpp", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">19.4 Case Study: Matrices
(<tt>matrixtest3.cpp</tt>)</font></h2>
<font size="+1">
<script><!--
iframeWrapCode( "matrixtest3.cpp", "80%", "80%" )
//--></script>
</font>
<hr><h2><font color="#009999">Chapter Summary</font></h2>
<font size="+1">
<hr color="#00ffff" size="6">
<ol>
<li>Programs should be robust</li>
<li>Select appropriate exception handling mechanism for the task</li>
<li>Exception management becomes more important on multiple-developer
projects</li>
<li><tt>throw</tt> an exception to signal an error. One of the callers
must supply a <tt>try</tt> block w/an appropriate <tt>catch</tt>
clause</li>
</ol>
</font>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -