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

📄 ch17.htm

📁 Why C++ is the emerging standard in software development. The steps to develop a C++ program. How
💻 HTM
📖 第 1 页 / 共 5 页
字号:
12:     #else13:     #define ASSERT(x) \14:         if (! (x)) \15:         { \16:            cout &lt;&lt; &quot;ERROR!! Assert &quot; &lt;&lt; #x &lt;&lt; &quot; failed\n&quot;; \17:            cout &lt;&lt; &quot; on line &quot; &lt;&lt; __LINE__  &lt;&lt; &quot;\n&quot;; \18:            cout &lt;&lt; &quot; in file &quot; &lt;&lt; __FILE__ &lt;&lt; &quot;\n&quot;;  \19:         }20:     #endif21:    22:     #if DEBUGLEVEL &lt; MEDIUM23:     #define EVAL(x)24:     #else25:     #define EVAL(x) \26:       cout &lt;&lt; #x &lt;&lt; &quot;:\t&quot; &lt;&lt; x &lt;&lt; endl;27:     #endif28:    29:    #if DEBUGLEVEL &lt; HIGH30:     #define PRINT(x)31:     #else32:     #define PRINT(x) \33:       cout &lt;&lt; x &lt;&lt; endl;34:     #endif35:    36:    37:     class String38:     {39:        public:40:           // constructors41:           String();42:           String(const char *const);43:           String(const String &amp;);44:           ~String();45:    46:           char &amp; operator[](int offset);47:           char operator[](int offset) const;48:    49:           String &amp; operator= (const String &amp;);50:           int GetLen()const { return itsLen; }51:           const char * GetString() const 52:            { return itsString; }53:           BOOL Invariants() const;54: 55:        private:56:           String (int);         // private constructor57:           char * itsString;58:           unsigned short itsLen;59:     };60:    61:     BOOL String::Invariants() const62:     {63:         PRINT(&quot;(String Invariants Checked)&quot;);64:         return ( (BOOL) (itsLen &amp;&amp; itsString) || 65:             (!itsLen &amp;&amp; !itsString) );66:     }67:    68:     class Animal69:     {70:     public:71:        Animal():itsAge(1),itsName(&quot;John Q. Animal&quot;)72:            {ASSERT(Invariants());}73:    74:        Animal(int, const String&amp;);75:        ~Animal(){}76:    77:        int GetAge() 78:            {  79:                ASSERT(Invariants()); 80:                return itsAge;81:            }82:    83:        void SetAge(int Age) 84:            { 85:                ASSERT(Invariants()); 86:                itsAge = Age; 87:                ASSERT(Invariants());88:            }89:        String&amp; GetName() 90:            { 91:                ASSERT(Invariants()); 92:                return itsName;  93:            }94:    95:        void SetName(const String&amp; name)96:            { 97:                ASSERT(Invariants()); 98:                itsName = name; 99:                ASSERT(Invariants());100:            }101:    102:        BOOL Invariants();103:     private:104:        int itsAge;105:        String itsName;106:     };107:    108:     BOOL Animal::Invariants()109:     {110:        PRINT(&quot;(Animal Invariants Checked)&quot;);111:        return (itsAge &gt; 0 &amp;&amp; itsName.GetLen());112:     }113:    114:     int main()115:     {116:        const int AGE = 5;117:        EVAL(AGE);118:        Animal sparky(AGE,&quot;Sparky&quot;);119:        cout &lt;&lt; &quot;\n&quot; &lt;&lt; sparky.GetName().GetString();120:        cout &lt;&lt; &quot; is &quot;;121:        cout &lt;&lt; sparky.GetAge() &lt;&lt; &quot; years old.&quot;;122:        sparky.SetAge(8);123:        cout &lt;&lt; &quot;\n&quot; &lt;&lt; sparky.GetName().GetString();124:        cout &lt;&lt; &quot; is &quot;;125:        cout &lt;&lt; sparky.GetAge() &lt;&lt; &quot; years old.&quot;;126:        return 0;<TT>127: }</TT></FONT><FONT COLOR="#0066FF">Output: AGE:     5 (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked) (String Invariants Checked)Sparky is (Animal Invariants Checked)5 Years old. (Animal Invariants Checked) (Animal Invariants Checked) (Animal Invariants Checked)Sparky is (Animal Invariants Checked)8 years old. (String Invariants Checked) (String Invariants Checked)// run again with DEBUG = MEDIUMAGE:     5Sparky is 5 years old.Sparky is 8 years old.</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On lines 10 to 20, the <TT>assert()</TT>macro is defined to be stripped if <TT>DEBUGLEVEL</TT> is less than <TT>LOW</TT>(that is, <TT>DEBUGLEVEL</TT> is <TT>NONE</TT>). If any debugging is enabled, the<TT>assert()</TT> macro will work. On line 23, <TT>EVAL</TT> is declared to be strippedif <TT>DEBUG</TT> is less than <TT>MEDIUM</TT>; if <TT>DEBUGLEVEL</TT> is <TT>NONE</TT>or <TT>LOW</TT>, <TT>EVAL</TT> is stripped.<BR>Finally, on lines 29-34, the <TT>PRINT</TT> macro is declared to be stripped if <TT>DEBUGLEVEL</TT>is less than <TT>HIGH</TT>. <TT>PRINT</TT> is used only when <TT>DEBUGLEVEL</TT>is <TT>HIGH</TT>; you can eliminate this macro by setting <TT>DEBUGLEVEL</TT> to<TT>MEDIUM</TT> and still maintain your use of <TT>EVAL</TT> and <TT>assert()</TT>.</P><P><TT>PRINT</TT> is used within the <TT>Invariants()</TT> methods to print an informativemessage. <TT>EVAL</TT> is used on line 117 to evaluate the current value of the constantinteger <TT>AGE</TT>.<BLOCKQUOTE>	<P><HR><B>DO</B> use CAPITALS for your macro names. This is a pervasive convention, and	other programmers will be confused if you don't. <B>DON'T</B> allow your macros to	have side effects. Don't increment variables or assign values from within a macro.	<B>DO</B> surround all arguments with parentheses in macro functions. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading42"></A><FONT COLOR="#000077">Summary</FONT></H3><P>Today you learned more details about working with the preprocessor. Each timeyou run the compiler, the preprocessor runs first and translates your preprocessordirectives such as <TT>#define</TT> and <TT>#ifdef</TT>.</P><P>The preprocessor does text substitution, although with the use of macros thesecan be somewhat complex. By using <TT>#ifdef</TT>,<TT> #else</TT>, and <TT>#ifndef</TT>,you can accomplish conditional compilation, compiling in some statements under oneset of conditions and in another set of statements under other conditions. This canassist in writing programs for more than one platform and is often used to conditionallyinclude debugging information.</P><P>Macro functions provide complex text substitution based on arguments passed atcompile time to the macro. It is important to put parentheses around every argumentin the macro to ensure the correct substitution takes place.</P><P>Macro functions, and the preprocessor in general, are less important in C++ thanthey were in C. C++ provides a number of language features, such as <TT>const</TT>variables and templates, that offer superior alternatives to use of the preprocessor.<H3 ALIGN="CENTER"><A NAME="Heading43"></A><FONT COLOR="#000077">Q&amp;A</FONT></H3><DL>	<DD><B>Q. If C++ offers better alternatives than the preprocessor, why is this option	still available?<BR>	</B><BR>	<B>A.</B> First, C++ is backward-compatible with C, and all significant parts of	C must be supported in C++. Second, there are some uses of the preprocessor that	are still used frequently in C++, such as inclusion guards.<BR>	<BR>	<B>Q. Why use macro functions when you can use a regular function?<BR>	</B><BR>	<B>A.</B> Macro functions are expanded inline and are used as a substitute for repeatedly	typing the same commands with minor variations. Again, though, templates offer a	better alternative.<BR>	<BR>	<B>Q. How do you know when to use a macro versus an inline function?<BR>	</B><BR>	<B>A.</B> Often it doesn't matter much; use whichever is simpler. However, macros	offer character substitution, stringizing, and concatenation. None of these is available	with functions.<BR>	<BR>	<B>Q. What is the alternative to using the preprocessor to print interim values during	debugging?</B><BR>	<B><BR>	A.</B> The best alternative is to use <TT>watch</TT> statements within a debugger.	For information on <TT>watch</TT> statements, consult your compiler or debugger documentation.<BR>	<BR>	<B>Q. How do you decide when to use an assert() and when to throw an exception?<BR>	</B><BR>	<B>A.</B> If the situation you're testing can be true without your having committed	a programming error, use an exception. If the only reason for this situation to ever	be true is a bug in your program, use an <TT>assert()</TT>.</DL><H3 ALIGN="CENTER"><A NAME="Heading44"></A><FONT COLOR="#000077">Workshop</FONT></H3><P>The Workshop provides quiz questions to help you solidify your understanding ofthe material 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 continuing to thenext chapter.<H4 ALIGN="CENTER"><A NAME="Heading45"></A><FONT COLOR="#000077">Quiz</FONT></H4><DL>	<DD><B>1.</B> What is an inclusion guard?<BR>	<B><BR>	2. </B>How do you instruct your compiler to print the contents of the intermediate	file showing the effects of the preprocessor?<BR>	<B><BR>	3.</B> What is the difference between <TT>#define debug 0</TT> and <TT>#undef debug</TT>?<BR>	<B><BR>	4.</B> Name four predefined macros.<BR>	<B><BR>	5.</B> Why can't you call <TT>Invariants()</TT> as the first line of your constructor?</DL><H4 ALIGN="CENTER"><A NAME="Heading46"></A><FONT COLOR="#000077">Exercises</FONT></H4><DL>	<DD><B>1.</B> Write the inclusion guard statements for the header file <TT>STRING.H</TT>.<BR>	<B><BR>	2.</B> Write an <TT>assert()</TT> macro that prints an error message and the file	and line number if debug level is 2, just a message (without file and line number)	if the level is 1, and does nothing if the level is 0.<BR>	<B><BR>	3.</B> Write a macro <TT>DPrint</TT> that tests if <TT>DEBUG</TT> is defined and,	if it is, prints the value passed in as a parameter.<BR>	<B><BR>	4.</B> Write a function that prints an error message. The function should print the	line number and filename where the error occurred. Note that the line number and	filename are passed in to this function.<BR>	<B><BR>	5.</B> How would you call the preceding error function?<BR>	<B><BR>	6.</B> Write an <TT>assert()</TT> macro that uses the error function from Exercise	4, and write a driver program that calls this <TT>assert()</TT> macro.</DL><P ALIGN="CENTER"><BR><A HREF="ch16.htm"><IMG SRC="../buttons/BLANPREV.GIF" WIDTH="37"HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="http://www.mcp.com/sams"><IMGSRC="../buttons/BLANHOME.GIF" WIDTH="37" HEIGHT="37" ALIGN="BOTTOM"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../buttons/BLANTOC.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="ch18.htm"><IMG SRC="../buttons/BLANNEXT.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A><A HREF="#heading1"><IMG SRC="../buttons/BLANTOP.GIF"WIDTH="37" HEIGHT="37" ALIGN="BOTTOM" BORDER="0"></A></BODY></HTML>

⌨️ 快捷键说明

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