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

📄 index.html

📁 《Big C++ 》Third Edition电子书和代码全集-Part1
💻 HTML
📖 第 1 页 / 共 2 页
字号:
		<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 &amp; Inheritance
	</font></h2>
<font size="+1">

<ul>
	<li>Can still be caught with:
		<blockquote><tt>
		catch (logic_error&amp; e)
		</tt></blockquote>
	</li>
	<li>Or, can be caught with:
		<blockquote><tt>
		catch (FutureValueError&amp; e)
		</tt></blockquote>
	</li>
</ul>

</font>

<hr><h2><font color="#009999">19.3.2 Exceptions &amp; 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&amp; e)
{  <i>handler<sub>1</sub></i>  }
   <font color="#0000cc">// catches all other logic_error</font>
catch (logic_error&amp; e)
{  <i>handler<sub>2</sub></i>  }
catch (bad_alloc&amp; 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&amp; e)
   {
      cout &lt;&lt; "caught logic_error " &lt;&lt; e.what() &lt;&lt; "\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&amp; e)
   {
      cout &lt;&lt; "caught bad_alloc error " &lt;&lt; e.what() &lt;&lt; "\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&amp; 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:&nbsp;&nbsp;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&amp; fs)
{
   getline(fs, name);
   if (name == "") return false; <font color="#0000cc">// End of file</font>
   fs &gt;&gt; price &gt;&gt; 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-&gt;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-&gt;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&amp; 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&amp; 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 + -