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

📄 ch05.htm

📁 C++ From Scratch: An Object-Oriented Approach is designed to walk novice programmers through the ana
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><HTML><HEAD><SCRIPT LANGUAGE="JavaScript"><!--function popUp(pPage) { var fullURL = document.location; var textURL = fullURL.toString(); var URLlen = textURL.length; var lenMinusPage = textURL.lastIndexOf("/"); lenMinusPage += 1; var fullPath = textURL.substring(0,lenMinusPage); popUpWin = window.open('','popWin','resizable=yes,scrollbars=no,width=525,height=394'); figDoc= popUpWin.document; zhtm= '<HTML><HEAD><TITLE>' + pPage + '</TITLE>'; zhtm += '</head>'; zhtm += '<BODY bgcolor="#FFFFFF">'; zhtm += '<IMG SRC="' + fullPath + pPage + '">'; zhtm += '<P><B>' + pPage + '</B>'; zhtm += '</BODY></HTML>'; window.popUpWin.document.write(zhtm); window.popUpWin.document.close(); // Johnny Jackson 4/28/98 }//-->                                                                </SCRIPT>	<META NAME="Author" Content="Steph Mineart">	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">	<TITLE>C++ From Scratch -- Ch 5 -- Playing The Game</TITLE><link rel="stylesheet" href="/includes/stylesheets/ebooks.css"></head><BODY TEXT="#000000" BGCOLOR="#FFFFFF"><CENTER><H1><IMG SRC="../button/que.gif" WIDTH="171" HEIGHT="66" ALIGN="BOTTOM" BORDER="0"><BR>C++ From Scratch</H1></CENTER><CENTER>  <P><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A>   <HR></CENTER><H1 align="center"> 5 <a name="_Toc444312800"></a></H1><h1 align="center"> Playing The Game</h1><ul>  <li><a href="#Heading1">Inline Implementation</a>   <li><a href="#Heading2">Constant Member Methods</a>   <li><a href="#Heading3">Geek SpeakThis entire section needs to be moved to later     in this chapter. Thanks. -jThe Signature</a>   <li><a href="#Heading4">Passing by Reference and by Value</a>     <ul>      <li><a href="#Heading5">References and Passing by Reference</a>     </ul>  <li><a href="#Heading6">Pointers</a>     <ul>      <li><a href="#Heading7">What is a pointer?</a>       <li><a href="#Heading8">Memory Addresses</a>       <li><a href="#Heading9">Dereferencing</a>       <li><a href="#Heading10">Getting the Operators Straight</a>     </ul>  <li><a href="#Heading11">Arrays</a>   <li><a href="#Heading12">Excursion: Pointers and Constants</a>     <ul>      <li><a href="#Heading13">Arrays as Pointers</a>       <li><a href="#Heading14">Passing the Array as a Pointer</a>     </ul>  <li><a href="#Heading15">Using ASSERT</a>     <ul>      <li><a href="#Heading16">How ASSERT Works</a>     </ul>  <li><a href="#Heading17">Excursion: Macros</a>     <ul>      <li><a href="#Heading18">Why All the Parentheses?</a>       <li><a href="#Heading19">Macros Versus Functions</a>     </ul>  <li><a href="#Heading20">String Manipulation</a>     <ul>      <li><a href="#Heading21">Stringizing</a>       <li><a href="#Heading22">Concatenation</a>     </ul>  <li><a href="#Heading23">Predefined Macros</a>   <li><a href="#Heading24"> Through the Program Once, by the Numbers</a> </ul><hr size=4><a name="_Toc440589230"></a><a name="_Toc444312799"></a><p>The declaration of the <tt>Game</tt> object builds on the material we've covered   so far, and it adds a few new elements you'll need to build a robust class.   Let's start by taking a look at the code (see Listing 5.1) and then discussing   it in detail.</p><h4> Listing 5.1 Game.h</h4><pre><tt>1:    #ifndef GAME_H</tt><tt>2:    #define GAME_H</tt><tt>3:    </tt><tt>4:    #include "definedValues.h"</tt><tt>5:    </tt><tt>6:    class Game</tt><tt>7:    {</tt><tt>8:    public:</tt><tt>9:        Game();</tt><tt>10:        ~Game()        {}</tt><tt>11:        void Display(const char * charArray) const</tt><tt>12:        {</tt><tt>13:            cout &lt;&lt; charArray &lt;&lt; endl;</tt><tt>14:        }</tt><tt>15:        void Play();</tt><tt>16:        const char * GetSolution() const</tt><tt>17:        {</tt><tt>18:            return solution;</tt><tt>19:        }</tt><tt>20:    void Score(const char * thisGuess, int &amp; correct, int &amp; position);</tt><tt>21:    </tt><tt>22:    private:</tt><tt>23:        int    howMany(const char *, char);</tt><tt>24:        char solution[maxPos];</tt><tt>25:        int    howManyLetters;</tt><tt>26:        int    howManyPositions;</tt><tt>27:        int    round;</tt><tt>28:        bool duplicates;</tt></pre><p>29: };Once again, you see inclusion guards on line 1, and you now see the naming   pattern that I'll use throughout this book. The inclusion guard will typically   have the name of the class or file, in all uppercase, followed by the underscore   (<tt>_</tt>) and the uppercase letter <i>H</i>. By having a standard for the   creation of inclusion guards, you can reduce the likelihood of using the same   guard name on two different header files.</p><p>On line 4, we include definedValues.h. As promised, this file will be included   throughout the program.</p><p>On line 6, we begin the declaration of the <tt>Game</tt> class. In the public   section we see the public interface for this class. Note that the public interface   contains only methods, not data; in fact, it contains only those methods that   we want to expose to clients of this class. </p><p>On line 9, we see the default constructor, as described in Chapter 4, "Creating   Classes," and on line 10, we see the destructor. The destructor, as it is shown   here, has an <i>inline</i> implementation, as do <tt>Display()</tt> (lines 11   to 14) and <tt>GetSolution</tt> (lines 16 to 19).</p><h2> <a name="Heading1">Inline Implementation</a></h2><p>Normally, when a function is called, processing literally jumps from the calling   function to the called function. </p><p>The processor must stash away information about the current state of the program.   It stores this information in an area of memory known as the <i>stack</i>, which   is also where local variables are created.</p><blockquote>  <hr>  <p><strong>NOTE: </strong> The <i>stack</i> is an area of memory in which local     variables and other information about the state of the program are stored.</p>  <hr></blockquote><p>The processor must also put the parameters to the new function on the stack   and adjust the instruction pointer (which keeps track of which instruction will   execute next), as illustrated in Figure 5.1. When the function returns, the   return value must be popped off the stack, the local variables and other local   state from the function must be cleaned up, and the registers must be readjusted   to return you to the state you were in before the function call. </p><p><b>Figure 5.1</b><tt><b> </b></tt><i>The instruction pointer.</i></p><p> </p><p>An alternative to a normal function call is to define the function with the   keyword <tt>inline</tt>. In this case, the compiler does not create a real function:   It copies the code from the inline function directly into the calling function.   No jump is made. It is just as if you had written the statements of the called   function right into the calling function.</p><p>Note that inline functions can bring a heavy cost. If the function is called   10 times, the inline code is copied into the calling functions each of those   10 times. The tiny improvement in speed you might achieve is more than swamped   by the increase in size of the executable program. Even the speed increase might   be illusory. First, today's optimizing compilers do a terrific job on their   own, and there is almost never a big gain from declaring a function inline.   More importantly, though, the increased size brings its own performance cost.</p><p>If the function you are calling is very small, it might still make sense to   designate that function as inline. There are two ways to do so. One is to put   the keyword <tt>inline</tt> into the definition of the function, before the   return value:</p><pre><tt>inline int Game::howMany()</tt></pre><p>An alternative syntax for class member methods is just to define the method   right in the declaration of the class itself. Thus, on line 19 you might note   that the destructor's implementation is defined right in the declaration. It   turns out that this destructor does nothing, so the braces are empty. This is   a perfect use of inlining: There is no need to branch out to the destructor,   just to take no action. <a name="_Toc444312802"></a></p><h2> <a name="Heading2">Constant Member Methods</a></h2><p>Take a look at <tt>Display</tt> on lines 11-14. After the argument list is   the keyword <tt>const</tt>. This use of <tt>const</tt> means, "I promise that   this method does not change the object on which you invoke this method," or,   in this case, "I promise that <tt>Display()</tt> won't change the <tt>Game</tt>   object on which you call <tt>Display()</tt>."</p><p><tt>const</tt> methods attempt to enlist the compiler in helping you to enforce   your design decisions. If you believe that a member method ought not change   the object (that is, you want the object treated as if it were read-only), declare   the method constant. If you then change the object as a result of calling the   method, the compiler flags the error, which can save you from having a difficult-to-find   bug.</p><h2> <a name="Heading3">Geek SpeakThis entire section needs to be moved to later   in this chapter. Thanks. -jThe Signature</a></h2><p>On line 20, we see the <i>signature</i> for the member method <tt>Score()</tt>.   The signature of a method is the name (<tt>Score</tt>) and the parameter list.   The declaration of a method consists of its signature and its return value (in   this case, <tt>void</tt>).</p><blockquote>  <hr>  <p><strong> </strong> <b>signature</b>--The name and parameter list of a method.</p>  <hr></blockquote><p>Before we examine this signature in detail, let's talk about what this method   does and what parameters it needs. The responsibility of this method is to examine   the player's guess (an array of characters) and to score it on how many letters   he correctly found, and of those letters, how many were in the right place.</p><p>Let's take a look at how this will be used. Listing 5.2 shows the <tt>Play()</tt>   method, which calls <tt>Score()</tt>.</p><h4> Listing 5.2 The Play Method</h4><pre><tt>0:  void Game::Play()</tt><tt>1:  {</tt><tt>2:      char guess[80];</tt><tt>3:      int correct = 0;</tt><tt>4:      int position = 0;</tt><tt>5:  </tt><tt>6:      //...</tt><tt>7:          cout &lt;&lt; "\nYour guess: ";</tt><tt>8:      Display(guess);</tt><tt>9:  </tt><tt>10:      Score(guess,correct,position);</tt><tt>11:      cout &lt;&lt; "\t\t" &lt;&lt; correct &lt;&lt; " correct, " &lt;&lt; position</tt><tt>12:       &lt;&lt; " in position." &lt;&lt; endl;</tt><tt>13:  }</tt></pre><p>I've elided much of this method (indicated by the <tt>//...</tt> marks), but   the code with which we are concerned is shown. We ask the user for his guess   and store it in the character array <tt>guess</tt>on line 2. We display <tt>guess</tt>   by calling <tt>Dis</tt><tt>play()</tt> on line 8 and passing <tt>guess</tt> in as   a parameter. We then we score<tt> </tt>it by calling <tt>Score() </tt>on line 10   and passing in <tt>guess</tt> and two integer variables: <tt>correct</tt> (declared   on line 3) and <tt>position</tt> (declared on line 4). Finally, we print the values   for <tt>correct</tt> and <tt>position</tt> on lines 11 and 12.</p><p><tt>Score()</tt> adjusts the values of <tt>correct</tt> and <tt>position</tt>. To   accomplish this, we must pass in these two variables <i>by reference</i>.</p><h2> <a name="Heading4">Passing by Reference and by Value</a></h2><p>When you pass an object into a method as a parameter to that method, you can   pass it either by reference or by value. If you pass it by reference, you are   providing that function with access to the object itself. If you pass it by   value, you are actually passing in a copy of the object.</p><blockquote>  <hr>  <p><strong> </strong> <b>passing by reference</b>--Passing an object into a     function.</p>  <p> <b>passing by value</b>--Passing a copy of an object into a function.</p>  <hr></blockquote><p>This distinction is critical. If we pass <tt>correct</tt> and <tt>position</tt>   by value, <tt>Score() </tt>cannot make changes to these variables back in <tt>Play()</tt>.   Listing 5.3 illustrates a very simple program that shows this problem. </p>

⌨️ 快捷键说明

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