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

📄 ch20.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
54:            pType[i] = rhs[i];55:      }56:      template &lt;class T&gt;57:      Array&lt;T&gt;::Array(const Array&lt;T&gt; &amp;rhs)58:      {59:         itsSize = rhs.GetitsSize();60:         pType = new T[itsSize];61:         for (int i = 0; i&lt;itsSize; i++)62:            pType[i] = rhs[i];63:      }64:    65:      template &lt;class T&gt;66:      T&amp; Array&lt;T&gt;::operator[](int offSet)67:      {68:         int size = GetitsSize();69:         if (offSet &gt;= 0 &amp;&amp; offSet &lt; GetitsSize())70:            return pType[offSet];71:         throw xBoundary();72:         return pType[0];73:      }74:    75:      template &lt;class T&gt;76:      const T&amp; Array&lt;T&gt;::operator[](int offSet) const77:      {78:         int mysize = GetitsSize();79:         if (offSet &gt;= 0 &amp;&amp; offSet &lt; GetitsSize())80:            return pType[offSet];81:         throw xBoundary();82:      }83:    84:      template &lt;class T&gt;85:      ostream&amp; operator&lt;&lt; (ostream&amp; output, const Array&lt;T&gt;&amp; theArray)86:      {87:         for (int i = 0; i&lt;theArray.GetitsSize(); i++)88:            output &lt;&lt; &quot;[&quot; &lt;&lt; i &lt;&lt; &quot;] &quot; &lt;&lt; theArray[i] &lt;&lt; endl;89:         return output;90:      }91:    92:    93:      int main()94:      {95: 96:         try97:         {98:            Array&lt;int&gt; intArray(9);99:            for (int j = 0; j&lt; 100; j++)100:            {101:               intArray[j] = j;102:               cout &lt;&lt; &quot;intArray[&quot; &lt;&lt; j &lt;&lt; &quot;] okay...&quot; &lt;&lt; endl;103:            }104:         }105:         catch (xBoundary)106:         {107:            cout &lt;&lt; &quot;Unable to process your input!\n&quot;;108:         }109:         catch (Array&lt;int&gt;::xSize)110:         {111:            cout &lt;&lt; &quot;Bad Size!\n&quot;;112:         }113:    114:         cout &lt;&lt; &quot;Done.\n&quot;;115:        return 0;<TT>116: }</TT></FONT><FONT COLOR="#0066FF">Output: Bad Size!Done.</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>The first exception, <TT>xBoundary</TT>,is declared outside the template definition on line 3. The second exception, <TT>xSize</TT>,is declared from within the definition of the template, on line 27.<BR><BR>The exception <TT>xBoundary</TT> is not tied to the <TT>template</TT> class, butcan be used like any other class. <TT>xSize</TT> is tied to the template, and mustbe called based on the instantiated <TT>Array</TT>. You can see the difference inthe syntax for the two <TT>catch</TT> statements. Line 105 shows <TT>catch (xBoundary)</TT>,but line 109 shows <TT>catch (Array&lt;int&gt;::xSize)</TT>. The latter is tied tothe instantiation of an integer <TT>Array</TT>.<H3 ALIGN="CENTER"><A NAME="Heading25"></A><FONT COLOR="#000077">Exceptions WithoutErrors</FONT></H3><P>When C++ programmers get together for a virtual beer in the cyberspace bar afterwork, talk often turns to whether exceptions should be used for routine conditions.Some maintain that by their nature, exceptions should be reserved for those predictablebut exceptional circumstances (hence the name!) that a programmer must anticipate,but that are not part of the routine processing of the code.</P><P>Others point out that exceptions offer a powerful and clean way to return throughmany layers of function calls without danger of memory leaks. A frequent exampleis this: The user requests an action in a GUI environment. The part of the code thatcatches the request must call a member function on a dialog manager, which in turncalls code that processes the request, which calls code that decides which dialogbox to use, which in turn calls code to put up the dialog box, which finally callscode that processes the user's input. If the user presses Cancel, the code must returnto the very first calling method, where the original request was handled.</P><P>One approach to this problem is to put a <TT>try</TT> block around the originalcall and catch <TT>CancelDialog</TT> as an exception, which can be raised by thehandler for the Cancel button. This is safe and effective, but pressing Cancel isa routine circumstance, not an exceptional one.</P><P>This frequently becomes something of a religious argument, but there is a reasonableway to decide the question: Does use of exceptions in this way make the code easieror harder to understand? Are there fewer risks of errors and memory leaks, or more?Will it be harder or easier to maintain this code? These decisions, like so manyothers, will require an analysis of the trade-offs; there is no single, obvious rightanswer.<H3 ALIGN="CENTER"><A NAME="Heading26"></A><FONT COLOR="#000077">Bugs and Debugging</FONT></H3><P>You saw on Day 17 how to use <TT>assert()</TT> to trap runtime bugs during thetesting phase, and today you saw how to use exceptions to trap runtime problems.There is one more powerful weapon you'll want to add to your arsenal as you attackbugs: the debugger.</P><P>Nearly all modern development environments include one or more high-powered debuggers.The essential idea of using a debugger is this: You run the debugger, which loadsyour source code, and then you run your program from within the debugger. This allowsyou to see each instruction in your program as it executes, and to examine your variablesas they change during the life of your program.</P><P>All compilers will let you compile with or without symbols. Compiling with symbolstells the compiler to create the necessary mapping between your source code and thegenerated program; the debugger uses this to point to the line of source code thatcorresponds to the next action in the program.</P><P>Full-screen symbolic debuggers make this chore a delight. When you load your debugger,it will read through all your source code and show the code in a window. You canstep over function calls or direct the debugger to step into the function, line byline.</P><P>With most debuggers, you can switch between the source code and the output tosee the results of each executed statement. More powerfully, you can examine thecurrent state of each variable, look at complex data structures, examine the valueof member data within classes, and look at the actual values in memory of variouspointers and other memory locations. You can execute several types of control withina debugger that include setting breakpoints, setting watch points, examining memory,and looking at the assembler code.<H4 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">Breakpoints</FONT></H4><P>Breakpoints are instructions to the debugger that when a particular line of codeis ready to be executed, the program should stop. This allows you to run your programunimpeded until the line in question is reached. Breakpoints help you analyze thecurrent condition of variables just before and after a critical line of code.<H4 ALIGN="CENTER"><A NAME="Heading28"></A><FONT COLOR="#000077">Watch Points</FONT></H4><P>It is possible to tell the debugger to show you the value of a particular variableor to break when a particular variable is read or written to. Watch points allowyou to set these conditions, and at times even to modify the value of a variablewhile the program is running.<H4 ALIGN="CENTER"><A NAME="Heading29"></A><FONT COLOR="#000077">Examining Memory</FONT></H4><P>At times it is important to see the actual values held in memory. Modern debuggerscan show values in the form of the actual variable; that is, strings can be shownas characters, <TT>long</TT>s as numbers rather than as four bytes, and so forth.Sophisticated C++ debuggers can even show complete classes, providing the currentvalue of all the member variables, including the <TT>this</TT> pointer.<H4 ALIGN="CENTER"><A NAME="Heading30"></A><FONT COLOR="#000077">Assembler</FONT></H4><P>Although reading through the source can be all that is required to find a bug,when all else fails it is possible to instruct the debugger to show you the actualassembly code generated for each line of your source code. You can examine the memoryregisters and flags, and generally delve as deep into the inner workings of yourprogram as required.</P><P>Learn to use your debugger. It can be the most powerful weapon in your holy waragainst bugs. Runtime bugs are the hardest to find and squash, and a powerful debuggercan make it possible, if not easy, to find nearly all of them.<H3 ALIGN="CENTER"><A NAME="Heading31"></A><FONT COLOR="#000077">Summary</FONT></H3><P>Today you learned how to create and use exceptions. Exceptions are objects thatcan be created and thrown at points in the program where the executing code cannothandle the error or other exceptional condition that has arisen. Other parts of theprogram, higher in the call stack, implement <TT>catch</TT> blocks that catch theexception and take appropriate action.</P><P>Exceptions are normal, user-created objects, and as such may be passed by valueor by reference. They may contain data and methods, and the <TT>catch</TT> blockmay use that data to decide how to deal with the exception.</P><P>It is possible to create multiple <TT>catch</TT> blocks, but once an exceptionmatches a <TT>catch</TT> block's signature, it is considered to be handled and isnot given to the subsequent <TT>catch</TT> blocks. It is important to order the <TT>catch</TT>blocks appropriately, so that more specific <TT>catch</TT> blocks have first chanceand more general <TT>catch</TT> blocks handle those not otherwise handled.</P><P>This chapter also examined some of the fundamentals of symbolic debuggers, includingusing watch points, breakpoints, and so forth. These tools can help you zero in onthe part of your program that is causing the error, and let you see the value ofvariables as they change during the course of the execution of the program.<H3 ALIGN="CENTER"><A NAME="Heading32"></A><FONT COLOR="#000077">Q&amp;A</FONT></H3><DL>	<DD><B>Q. Why bother with raising exceptions? Why not handle the error right where	it happens?<BR>	</B><BR>	<B>A.</B> Often, the same error can be generated in a number of different parts of	the code. Exceptions let you centralize the handling of errors. Additionally, the	part of the code that generates the error may not be the best place to determine	how to handle the error.<BR>	<BR>	<B>Q. Why generate an object? Why not just pass an error code?<BR>	</B><BR>	<B>A.</B> Objects are more flexible and powerful than error codes. They can convey	more information, and the constructor/destructor mechanisms can be used for the creation	and removal of resources that may be required to properly handle the exceptional	condition.<BR>	<BR>	<B>Q. Why not use exceptions for non-error conditions? Isn't it convenient to be	able to express-train back to previous areas of the code, even when non-exceptional	conditions exist?</B><BR>	<BR>	<B>A.</B> Yes, some C++ programmers use exceptions for just that purpose. The danger	is that exceptions might create memory leaks as the stack is unwound and some objects	are inadvertently left in the free store. With careful programming techniques and	a good compiler, this can usually be avoided. Otherwise, it is a matter of personal	aesthetic; some programmers feel that by their nature exceptions should not be used	for routine conditions.<BR>	<BR>	<B>Q. Does an exception have to be caught in the same place where the try block created	the exception?</B><BR>	<BR>	<B>A.</B> No, it is possible to catch an exception anywhere in the call stack. As	the stack is unwound, the exception is passed up the stack until it is handled.<BR>	<BR>	<B>Q. Why use a debugger when you can use cout with conditional (#ifdef debug) compiling?<BR>	</B><BR>	<B>A.</B> The debugger provides a much more powerful mechanism for stepping through	your code and watching values change without having to clutter your code with thousands	of debugging statements.</DL><H3 ALIGN="CENTER"><A NAME="Heading33"></A><FONT COLOR="#000077">Workshop</FONT></H3><P>The Workshop contains quiz questions to help solidify your understanding of thematerial covered and exercises to provide you with experience in using what you'velearned. Try to answer the quiz and exercise questions before checking the answersin Appendix D, and make sure you understand the answers before going to the nextchapter.<H4 ALIGN="CENTER"><A NAME="Heading34"></A><FONT COLOR="#000077">Quiz</FONT></H4><DL>	<DD><B>1.</B> What is an exception?<BR>	<BR>	<B>2.</B> What is a <TT>try</TT> block?<BR>	<BR>	<B>3.</B> What is a <TT>catch</TT> statement?<BR>	<BR>	<B>4.</B> What information can an exception contain?<BR>	<BR>	<B>5.</B> When are exception objects created?<BR>	<BR>	<B>6.</B> Should you pass exceptions by value or by reference?<BR>	<BR>	<B>7.</B> Will a <TT>catch</TT> statement catch a derived exception if it is looking	for the base class?<BR>	<BR>	<B>8.</B> If there are two <TT>catch</TT> statements, one for base and one for derived,	which should come first?<BR>	<BR>	<B>9.</B> What does <TT>catch(...)</TT> mean?<BR>	<BR>	<B>10.</B> What is a breakpoint?</DL><H4 ALIGN="CENTER"><A NAME="Heading35"></A><FONT COLOR="#000077">Exercises</FONT></H4><DL>	<DD><B>1.</B> Create a <TT>try</TT> block, a <TT>catch</TT> statement, and a simple	exception.<BR>	<BR>	<B>2.</B> Modify the answer from Exercise 1, put data into the exception, along with	an accessor function, and use it in the <TT>catch</TT> block.<BR>	<BR>	<B>3.</B> Modify the class from Exercise 2 to be a hierarchy of exceptions. Modify	the <TT>catch</TT> block to use the derived objects and the base objects.<BR>	<BR>	<B>4.</B> Modify the program from Exercise 3 to have three levels of function calls.<BR>	<BR>	<B>5.</B> BUG BUSTERS: What is wrong with the following code?</DL><PRE><FONT COLOR="#0066FF">class xOutOfMemory{public:     xOutOfMemory( const String&amp; message ) : itsMsg( message ){}     ~xOutOfMemory(){}     virtual const String&amp; Message(){ return itsMsg};private:     String itsMsg;          }main(){     try {          char *var = new char;          if ( var == 0 )               throw xOutOfMemory();     }     catch( xOutOfMemory&amp; theException )     {          cout &lt;&lt;  theException.Message() &lt;&lt; &quot;\n&quot;;     }}</FONT></PRE><P ALIGN="CENTER"><A HREF="ch19.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch19.htm"><IMG SRC="BLANPREV.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANPREV.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="tppmsgs/msgs0.htm#1" tppabs="http://www.mcp.com/sams"><IMGSRC="BLANHOME.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"BORDER="0"></A><A HREF="index.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/index.htm"><IMG SRC="BLANTOC.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANTOC.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch21.htm" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/htm/ch21.htm"><IMG SRC="BLANNEXT.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANNEXT.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="#heading1"><IMG SRC="BLANTOP.GIF" tppabs="http://www.mcp.com/814147200/0-672/0-672-31070-8/buttons/BLANTOP.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A></BODY></HTML>

⌨️ 快捷键说明

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