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

📄 ch26.htm

📁 VC使用大全。里面集合了VC使用的各种使用技巧。非常有用。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>Listing 26.3 is a short program that demonstrates this concept. The program throws the exception from the <font color="#008000">AllocateBuffer()</font> function but catches the exception in <font color="#008000">main()</font>, which is the function 
from which <font color="#008000">AllocateBuffer()</font> is called.</P>

<P><I>Listing 26.3&#151;EXCEPTION3.CPP&#151;Catching Exceptions Outside of the Throwing Function</I></P>

<pre><font color="#008000">#include &lt;iostream.h&gt;</font></pre>

<pre><font color="#008000">class MyException</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">protected:</font></pre>

<pre><font color="#008000">    char* m_msg;</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">    MyException(char *msg) { m_msg = msg;}</font></pre>

<pre><font color="#008000">    ~MyException(){}</font></pre>

<pre><font color="#008000">    char* GetError() {return m_msg;}</font></pre>

<pre><font color="#008000">};</font></pre>

<pre><font color="#008000">class BigObect</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">private:</font></pre>

<pre><font color="#008000">     int* intarray;</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">     BigObject() {intarray = new int[1000];}</font></pre>

<pre><font color="#008000">     ~BigObject() {delete intarray;}</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">int* AllocateBuffer();</font></pre>

<pre><font color="#008000">int main()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    int* buffer;</font></pre>

<pre><font color="#008000">    </font></pre>

<pre><font color="#008000">    try</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        buffer = AllocateBuffer();</font></pre>

<pre><font color="#008000">        delete buffer;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    catch (MyException* exception)</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        char* msg = exception-&gt;GetError();</font></pre>

<pre><font color="#008000">        cout &lt;&lt; msg &lt;&lt; endl;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    return 0;</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">int* AllocateBuffer()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    BigObject huge;</font></pre>

<pre><font color="#008000">    float* floatarray = new float[1000];</font></pre>

<pre><font color="#008000">    int* buffer = new int[256];</font></pre>

<pre><font color="#008000">    if (buffer == NULL)</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        MyException* exception =</font></pre>

<pre><font color="#008000">            new MyException(&quot;Memory allocation failed!&quot;);</font></pre>

<pre><font color="#008000">        throw exception;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    delete floatarray;</font></pre>

<pre><font color="#008000">    return buffer;</font></pre>

<pre><font color="#008000">}</font></pre>

<P>When the exception is thrown in <font color="#008000">AllocateBuffer()</font>, the remainder of the function is not executed. The dynamically allocated floatarray will not be deleted. The BigObject that was allocated on the stack will go out of scope 
and its destructor will be executed, deleting the intarray member variable that was allocated with <font color="#008000">new</font> in the constructor. This is an important concept to grasp: objects created on the stack will be destructed as the stack 
unwinds. Objects created on the heap will not. Your code must take care of these. For example, <font color="#008000">AllocateBuffer()</font> should include code to delete floatarray before throwing the exception, like this:</P>

<pre><font color="#008000">if (buffer == NULL)</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        MyException* exception =</font></pre>

<pre><font color="#008000">            new MyException(&quot;Memory allocation failed!&quot;);</font></pre>

<pre><font color="#008000">        delete floatarray;</font></pre>

<pre><font color="#008000">        throw exception;</font></pre>

<pre><font color="#008000">    }</font></pre>

<P>In many cases, using an object with a carefully written destructor can save you significant code duplication when you are using exceptions. If you are using objects allocated on the heap, you may need to catch and rethrow exceptions just so that you 
can delete them. Consider the code in Listing 26.4, in which the exception is thrown right past an intermediate function up to the catching function.</P>

<P><I>Listing 26.4&#151;EXCEPTION4.CPP&#151;Unwinding the stack</I></P>

<pre><font color="#008000">#include &lt;iostream.h&gt;</font></pre>

<pre><font color="#008000">class MyException</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">protected:</font></pre>

<pre><font color="#008000">    char* m_msg;</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">    MyException(char *msg) { m_msg = msg;}</font></pre>

<pre><font color="#008000">    ~MyException(){}</font></pre>

<pre><font color="#008000">    char* GetError() {return m_msg;}</font></pre>

<pre><font color="#008000">};</font></pre>

<pre><font color="#008000">class BigObject</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">private:</font></pre>

<pre><font color="#008000">     int* intarray;</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">     BigObject() {intarray = new int[1000];}</font></pre>

<pre><font color="#008000">     ~BigObject() {delete intarray;}</font></pre>

<pre><font color="#008000">};</font></pre>

<pre><font color="#008000">int* AllocateBuffer();</font></pre>

<pre><font color="#008000">int* Intermediate();</font></pre>

<pre><font color="#008000">int main()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    int* buffer;</font></pre>

<pre><font color="#008000">    </font></pre>

<pre><font color="#008000">    try</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        buffer = Intermediate();</font></pre>

<pre><font color="#008000">        delete buffer;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    catch (MyException* exception)</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        char* msg = exception-&gt;GetError();</font></pre>

<pre><font color="#008000">        cout &lt;&lt; msg &lt;&lt; endl;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    return 0;</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">int* Intermediate()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    BigObject bigarray;</font></pre>

<pre><font color="#008000">    float* floatarray = new float[1000];</font></pre>

<pre><font color="#008000">    int* retval = AllocateBuffer();</font></pre>

<pre><font color="#008000">    delete floatarray;</font></pre>

<pre><font color="#008000">    return retval; </font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">int* AllocateBuffer()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    int* buffer = new int[256];</font></pre>

<pre><font color="#008000">    if (buffer == NULL)</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        MyException* exception =</font></pre>

<pre><font color="#008000">            new MyException(&quot;Memory allocation failed!&quot;);</font></pre>

<pre><font color="#008000">        throw exception;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">    </font></pre>

<pre><font color="#008000">    return buffer;</font></pre>

<pre><font color="#008000">}</font></pre>

<P>Now if the exception is thrown, execution of <font color="#008000">AllocateBuffer()</font> is abandoned immediately. The stack unwinds. Since there is no catch block in <font color="#008000">Intermediate()</font>, execution of that function will be 
abandoned after the call to <font color="#008000">AllocateBuffer()</font>. The delete for floatarray will not happen, but the destructor for bigarray will be executed. Listing 26.5 shows a way around this problem.</P>

<P><I>Listing 26.5&#151;Rethrowing exceptions</I></P>

<pre><font color="#008000">int* Intermediate()</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    BigObject bigarray;</font></pre>

<pre><font color="#008000">    float* floatarray = new float[1000];</font></pre>

<pre><font color="#008000">    int* retval = NULL;</font></pre>

<pre><font color="#008000">    try</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000"> </font><font color="#008000">retval = AllocateBuffer();</font></pre>

⌨️ 快捷键说明

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