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

📄 ch08.htm

📁 一本好的VC学习书,本人就是使用这本书开始学习的vc,希望能对大家有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>The stack is cleaned automatically when a function returns. All the local variablesgo out of scope, and they are removed from the stack. The free store is not cleaneduntil your program ends, and it is your responsibility to free any memory that you'vereserved when you are done with it.</P><P>The advantage to the free store is that the memory you reserve remains availableuntil you explicitly free it. If you reserve memory on the free store while in afunction, the memory is still available when the function returns.</P><P>The advantage of accessing memory in this way, rather than using global variables,is that only functions with access to the pointer have access to the data. This providesa tightly controlled interface to that data, and it eliminates the problem of onefunction changing that data in unexpected and unanticipated ways.</P><P>For this to work, you must be able to create a pointer to an area on the freestore and to pass that pointer among functions. The following sections describe howto do this.<H4 ALIGN="CENTER"><A NAME="Heading22"></A><FONT COLOR="#000077">new</FONT></H4><P>You allocate memory on the free store in C++ by using the <TT>new</TT> keyword.<TT>new</TT> is followed by the type of the object that you want to allocate so thatthe compiler knows how much memory is required. Therefore, <TT>new unsigned shortint</TT> allocates two bytes in the free store, and <TT>new long</TT> allocates four.</P><P>The return value from <TT>new</TT> is a memory address. It must be assigned toa pointer. To create an <TT>unsigned</TT> <TT>short</TT> on the free store, you mightwrite</P><PRE><FONT COLOR="#0066FF">unsigned short int * pPointer;pPointer = new unsigned short int;</FONT></PRE><P>You can, of course, initialize the pointer at its creation with</P><PRE><FONT COLOR="#0066FF">unsigned short int * pPointer = new unsigned short int;</FONT></PRE><P>In either case, <TT>pPointer</TT> now points to an <TT>unsigned short int</TT>on the free store. You can use this like any other pointer to a variable and assigna value into that area of memory by writing</P><PRE><FONT COLOR="#0066FF">*pPointer = 72;</FONT></PRE><P>This means, &quot;Put 72 at the value in <TT>pPointer</TT>,&quot; or &quot;Assignthe value <TT>72</TT> to the area on the free store to which <TT>pPointer</TT> points.&quot;</P><P>If <TT>new</TT> cannot create memory on the free store (memory is, after all,a limited resource) it returns the null pointer. You must check your pointer fornull each time you request new memory.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>WARNING:</B></FONT><B> </B>Each time you allocate memory	using the <TT>new</TT> keyword, you must check to make sure the pointer is not null.	<HR></BLOCKQUOTE><H4 ALIGN="CENTER"><A NAME="Heading23"></A><FONT COLOR="#000077">delete</FONT></H4><P>When you are finished with your area of memory, you must call <TT>delete</TT>on the pointer. <TT>delete</TT> returns the memory to the free store. Remember thatthe pointer itself--as opposed to the memory to which it points--is a local variable.When the function in which it is declared returns, that pointer goes out of scopeand is lost. The memory allocated with <TT>new</TT> is not freed automatically, however.That memory becomes unavailable--a situation called a memory leak. It's called amemory leak because that memory can't be recovered until the program ends. It isas though the memory has leaked out of your computer.</P><P>To restore the memory to the free store, you use the keyword <TT>delete</TT>.For example,</P><PRE><FONT COLOR="#0066FF">delete pPointer;</FONT></PRE><P>When you delete the pointer, what you are really doing is freeing up the memorywhose address is stored in the pointer. You are saying, &quot;Return to the freestore the memory that this pointer points to.&quot; The pointer is still a pointer,and it can be reassigned. Listing 8.4 demonstrates allocating a variable on the heap,using that variable, and deleting it.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>WARNING:</B></FONT><B> </B>When you call <TT>delete</TT>	on a pointer, the memory it points to is freed. Calling <TT>delete</TT> on that pointer	again will crash your program! When you delete a pointer, set it to zero (null).	Calling <TT>delete</TT> on a null pointer is guaranteed to be safe. For example:</P>	<PRE><FONT COLOR="#0066FF">Animal *pDog = new Animal; delete pDog; //frees the memory    </FONT></PRE>	<BLOCKQUOTE>		<PRE><FONT COLOR="#0066FF">pDog = 0; //sets pointer to null    //... delete pDog; //harmless</FONT></PRE>	</BLOCKQUOTE>	<P><HR></BLOCKQUOTE><PRE></PRE><P><A NAME="Heading24"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 8.4. Allocating,using, and deleting pointers.</B></FONT></P><PRE><FONT COLOR="#0066FF">1:     // Listing 8.42:     // Allocating and deleting a pointer3:4:     #include &lt;iostream.h&gt;5:     int main()6:     {7:        int localVariable = 5;8:        int * pLocal= &amp;localVariable;9:        int * pHeap = new int;10:       if (pHeap == NULL)11:        {12:            cout &lt;&lt; &quot;Error! No memory for pHeap!!&quot;;13:            return 0;14:        }15:       *pHeap = 7;16:       cout &lt;&lt; &quot;localVariable: &quot; &lt;&lt; localVariable &lt;&lt; &quot;\n&quot;;17:       cout &lt;&lt; &quot;*pLocal: &quot; &lt;&lt; *pLocal &lt;&lt; &quot;\n&quot;;18:       cout &lt;&lt; &quot;*pHeap: &quot; &lt;&lt; *pHeap &lt;&lt; &quot;\n&quot;;19:       delete pHeap;20:       pHeap = new int;21:       if (pHeap == NULL)22:       {23:            cout &lt;&lt; &quot;Error! No memory for pHeap!!&quot;;24:            return 0;25:       }26:       *pHeap = 9;27:       cout &lt;&lt; &quot;*pHeap: &quot; &lt;&lt; *pHeap &lt;&lt; &quot;\n&quot;;28:       delete pHeap;29:       return 0;<TT>30: }</TT></FONT><FONT COLOR="#0066FF">Output: localVariable: 5*pLocal: 5*pHeap: 7*pHeap: 9</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis: </B></FONT>Line 7 declares and initializesa local variable. Line 8 declares and initializes a pointer with the address of thelocal variable. Line 9 declares another pointer but initializes it with the resultobtained from calling <TT>new int</TT>. This allocates space on the free store foran <TT>int</TT>. Line 10 verifies that memory was allocated and the pointer is valid(not null). If no memory can be allocated, the pointer is null and an error messageis printed.<BR>To keep things simple, this error checking often won't be reproduced in future programs,but you must include some sort of error checking in your own programs.</P><P>Line 15 assigns the value <TT>7</TT> to the newly allocated memory. Line 16 printsthe value of the local variable, and line 17 prints the value pointed to by <TT>pLocal</TT>.As expected, these are the same. Line 19 prints the value pointed to by <TT>pHeap</TT>.It shows that the value assigned in line 15 is, in fact, accessible.</P><P>In line 19, the memory allocated in line 9 is returned to the free store by acall to <TT>delete</TT>. This frees the memory and disassociates the pointer fromthat memory. <TT>pHeap</TT> is now free to point to other memory. It is reassignedin lines 20 and 26, and line 27 prints the result. Line 28 restores that memory tothe free store.</P><P>Although line 28 is redundant (the end of the program would have returned thatmemory) it is a good idea to free this memory explicitly. If the program changesor is extended, it will be beneficial that this step was already taken care of.<H3 ALIGN="CENTER"><A NAME="Heading25"></A><FONT COLOR="#000077">Memory Leaks</FONT></H3><P>Another way you might inadvertently create a memory leak is by reassigning yourpointer before deleting the memory to which it points. Consider this code fragment:</P><PRE><FONT COLOR="#0066FF">1:   unsigned short int * pPointer = new unsigned short int;2:   *pPointer = 72;3:   pPointer = new unsigned short int;4:   *pPointer = 84;</FONT></PRE><P>Line 1 creates <TT>pPointer</TT> and assigns it the address of an area on thefree store. Line 2 stores the value <TT>72</TT> in that area of memory. Line 3 reassigns<TT>pPointer</TT> to another area of memory. Line 4 places the value <TT>84</TT>in that area. The original area--in which the value <TT>72</TT> is now held--is unavailablebecause the pointer to that area of memory has been reassigned. There is no way toaccess that original area of memory, nor is there any way to free it before the programends.</P><P>The code should have been written like this:</P><PRE><FONT COLOR="#0066FF">1: unsigned short int * pPointer = new unsigned short int;2: *pPointer = 72;3: delete pPointer;4: pPointer = new unsigned short int;5: *pPointer = 84;</FONT></PRE><P>Now the memory originally pointed to by <TT>pPointer</TT> is deleted, and thusfreed, in line 3.<BLOCKQUOTE>	<P><HR><FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>For every time in your program that	you call <TT>new</TT>, there should be a call to <TT>delete</TT>. It is important	to keep track of which pointer owns an area of memory and to ensure that the memory	is returned to the free store when you are done with it. <HR></BLOCKQUOTE><H3 ALIGN="CENTER"><A NAME="Heading26"></A><FONT COLOR="#000077">Creating Objectson the Free Store</FONT></H3><P>Just as you can create a pointer to an integer, you can create a pointer to anyobject. If you have declared an object of type <TT>Cat</TT>, you can declare a pointerto that class and instantiate a <TT>Cat</TT> object on the free store, just as youcan make one on the stack. The syntax is the same as for integers:</P><PRE><FONT COLOR="#0066FF">Cat *pCat = new Cat;</FONT></PRE><P>This calls the default constructor--the constructor that takes no parameters.The constructor is called whenever an object is created (on the stack or on the freestore).<H3 ALIGN="CENTER"><A NAME="Heading27"></A><FONT COLOR="#000077">Deleting Objects</FONT></H3><P>When you call <TT>delete</TT> on a pointer to an object on the free store, thatobject's destructor is called before the memory is released. This gives your classa chance to clean up, just as it does for objects destroyed on the stack. Listing8.5 illustrates creating and deleting objects on the free store.</P><P><A NAME="Heading28"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 8.5. Creatingand deleting objects on the free store.</B></FONT></P><PRE><FONT COLOR="#0066FF">1:    // Listing 8.52:    // Creating objects on the free store3:4:     #include &lt;iostream.h&gt;5:6:     class SimpleCat7:     {8:     public:9:            SimpleCat();10:             ~SimpleCat();11     private:12             int itsAge;13        };1415        SimpleCat::SimpleCat()16        {17               cout &lt;&lt; &quot;Constructor called.\n&quot;;18               itsAge = 1;19        }2021        SimpleCat::~SimpleCat()22        {23               cout &lt;&lt; &quot;Destructor called.\n&quot;;24        }2526        int main()27        {28               cout &lt;&lt; &quot;SimpleCat Frisky...\n&quot;;29               SimpleCat Frisky;30               cout &lt;&lt; &quot;SimpleCat *pRags = new SimpleCat...\n&quot;;31               SimpleCat * pRags = new SimpleCat;32               cout &lt;&lt; &quot;delete pRags...\n&quot;;33               delete pRags;34               cout &lt;&lt; &quot;Exiting, watch Frisky go...\n&quot;;35        return 0;<TT>36 }</TT></FONT><FONT COLOR="#0066FF">Output: SimpleCat Frisky...Constructor called.SimpleCat *pRags = new SimpleCat..Constructor called.delete pRags...Destructor called.Exiting, watch Frisky go...Destructor called.</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>Lines 6-13 declare the stripped-downclass <TT>SimpleCat</TT>. Line 9 declares <TT>SimpleCat</TT>'s constructor, and lines15-19 contain its definition. Line 10 declares <TT>SimpleCat</TT>'s destructor, andlines 21-24 contain its definition.<BR>In line 29, <TT>Frisky</TT> is created on the stack, which causes the constructorto be called. In line 31, the <TT>SimpleCat</TT> pointed to by <TT>pRags</TT> iscreated on the heap; the constructor is called again. In line 33, delete is calledon <TT>pRags</TT>, and the destructor is called. When the function ends, <TT>Frisky</TT>goes out of scope, and the destructor is called.<H3 ALIGN="CENTER"><A NAME="Heading30"></A><FONT COLOR="#000077">Accessing Data Members</FONT></H3><P>You accessed data members and functions by using the dot (<TT>.</TT>) operatorfor <TT>Cat</TT> objects created locally. To access the <TT>Cat</TT> object on thefree store, you must dereference the pointer and call the dot operator on the objectpointed to by the pointer. Therefore, to access the <TT>GetAge</TT> member function,you would write</P><PRE><FONT COLOR="#0066FF"> (*pRags).GetAge();</FONT></PRE><P>Parentheses are used to assure that <TT>pRags</TT> is dereferenced before <TT>GetAge()</TT>is accessed.</P><P>Because this is cumbersome, C++ provides a shorthand operator for indirect access:the <TT>points-to</TT> operator (<TT>-&gt;</TT>), which is created by typing thedash (<TT>-</TT>) immediately followed by the greater-than symbol (<TT>&gt;</TT>).C++ treats this as a single symbol. Listing 8.6 demonstrates accessing member variablesand functions of objects created on the free store.</P><P><A NAME="Heading31"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 8.6. Accessingmember data of objects on the free store.</B></FONT></P><PRE><FONT COLOR="#0066FF">

⌨️ 快捷键说明

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