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

📄 mc2.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
📖 第 1 页 / 共 5 页
字号:
</UL><A NAME="64754"></A>
<P><A NAME="dingp83"></A>
Here <CODE>operator</CODE> <CODE>new</CODE> will return a pointer to a chunk of memory large enough to hold a <CODE>string</CODE> <NOBR>object.<SCRIPT>create_link(83);</SCRIPT>

</NOBR></p><A NAME="34195"></A>
<P><A NAME="dingp84"></A>
Like <CODE>malloc</CODE>, <CODE>operator</CODE> <CODE>new</CODE>'s only responsibility is to allocate memory. It knows nothing about constructors. All <CODE>operator</CODE> <CODE>new</CODE> understands is memory allocation. It is the job of the <CODE>new</CODE> operator to take the raw memory that <CODE>operator</CODE> <CODE>new</CODE> returns and transform it into an object. When your compilers see a statement <NOBR>like<SCRIPT>create_link(84);</SCRIPT>

</NOBR></P>
<A NAME="34209"></A>
<UL><PRE>string *ps = new string("Memory Management");
</PRE>
</UL><A NAME="34207"></A><P><A NAME="dingp85"></A>they must generate code that more or less corresponds to this (see Items <A HREF="../EC/EC2_FR.HTM#120851" TARGET="_top" onMouseOver = "self.status = 'Link to EC++ Item 8'; return true" onMouseOut = "self.status = self.defaultStatus">E8</A> and <A HREF="../EC/EC2_FR.HTM#1986" TARGET="_top" onMouseOver = "self.status = 'Link to EC++ Item 10'; return true" onMouseOut = "self.status = self.defaultStatus">E10</A>, as well as <A HREF="../MAGAZINE/CO_FRAME.HTM#sidebar" TARGET="_top" onMouseOver = "self.status = 'Link to the sidebar'; return true" onMouseOut = "self.status = self.defaultStatus">the sidebar</A> to <A HREF="../MAGAZINE/CO_FRAME.HTM" TARGET="_top" onMouseOver = "self.status = 'Link to my article on counting objects'; return true" onMouseOut = "self.status = self.defaultStatus">my article on counting objects</A>, for a more detailed treatment of this <NOBR>point):<SCRIPT>create_link(85);</SCRIPT>

</NOBR></p><A NAME="34212"></A>
<UL><PRE>
void *memory =                              // get raw memory
  operator new(sizeof(string));             // for a string
                                            // object
</PRE>
</UL><A NAME="34213"></A>
<UL><PRE>
<i>call string::string("Memory Management")</i>    // initialize the
<i>on *memory;</i>                                 // object in the
                                            // memory
</PRE>
</UL><A NAME="34214"></A>
<UL><PRE>
string *ps =                                // make ps point to
  static_cast&lt;string*&gt;(memory);             // the new object
</PRE>
</UL><A NAME="34239"></A>
<P><A NAME="dingp86"></A>
Notice that the second step above involves calling a constructor, something you, a mere programmer, are prohibited from doing. Your compilers are unconstrained by mortal limits, however, and they can do whatever they like. That's why you must use the <CODE>new</CODE> operator if you want to conjure up a heap-based object: you can't directly call the constructor necessary to initialize the object (including such crucial components as its vtbl &#151; see <A HREF="./MC4_FR.HTM#41284" TARGET="_top" onMouseOver = "self.status = 'Link to MEC++ Item 24'; return true" onMouseOut = "self.status = self.defaultStatus">Item 24</A>).<SCRIPT>create_link(86);</SCRIPT>

</p>

<P><A NAME="dingp87"></A><font ID="mhtitle">Placement New</font><SCRIPT>create_link(87);</SCRIPT>

</P>

<A NAME="40577"></A>
<P><A NAME="dingp88"></A>
There are times when you really <I>want</I> to call a constructor directly. Invoking a constructor on an existing object makes no sense, because constructors initialize objects, and an object can only be initialized &#151; given its first value &#151; once. But occasionally you have some raw memory that's already been allocated, and you need to construct an object in the memory you have. A special version of <CODE>operator</CODE> <CODE>new</CODE> called <I>placement</I> <CODE><I>new</I></CODE> allows you to do <NOBR>it.<SCRIPT>create_link(88);</SCRIPT>

</NOBR></p><A NAME="40747"></A>
<P><A NAME="dingp89"></A>
As an example of how placement <CODE>new</CODE> might be used, consider <NOBR>this:<SCRIPT>create_link(89);</SCRIPT>

</NOBR></p><A NAME="40580"></A>
<A NAME="p40"></A><UL><PRE>class Widget {
public:
  Widget(int widgetSize);
  ...
};
</PRE>
</UL><A NAME="79219"></A>
<UL><PRE>Widget * constructWidgetInBuffer(void *buffer,
                                 int widgetSize)
{
  return new (buffer) Widget(widgetSize);
}
</PRE>
</UL><A NAME="40622"></A>
<P><A NAME="dingp90"></A>
This function returns a pointer to a <CODE>Widget</CODE> object that's constructed <I>within</I> the buffer passed to the function. Such a function might be useful for applications using shared memory or memory-mapped I/O, because objects in such applications must be placed at specific addresses or in memory allocated by special routines. (For a different example of how placement <CODE>new</CODE> can be used, see <A HREF="./MC1_FR.HTM#5218" TARGET="_top" onMouseOver = "self.status = 'Link to MEC++ Item 4'; return true" onMouseOut = "self.status = self.defaultStatus">Item 4</A>.)<SCRIPT>create_link(90);</SCRIPT>

</p><A NAME="40641"></A>
<P><A NAME="dingp91"></A>
Inside <CODE>constructWidgetInBuffer</CODE>, the expression being returned <NOBR>is<SCRIPT>create_link(91);</SCRIPT>

</NOBR></p><A NAME="40598"></A>
<UL><PRE>new (buffer) Widget(widgetSize)
</PRE>
</UL><A NAME="40603"></A>
<P><A NAME="dingp92"></A>
This looks a little strange at first, but it's just a use of the <CODE>new</CODE> operator in which an additional argument (<CODE>buffer</CODE>) is being specified for the implicit call that the <CODE>new</CODE> operator makes to <CODE>operator</CODE> <CODE>new</CODE>. The <CODE>operator</CODE> <CODE>new</CODE> thus called must, in addition to the mandatory <CODE>size_t</CODE> argument, accept a <CODE>void*</CODE> parameter that points to the memory the object being constructed is to occupy. That <CODE>operator</CODE> <CODE>new</CODE> <I>is</I> placement <CODE>new</CODE>, and it looks like <NOBR>this:<SCRIPT>create_link(92);</SCRIPT>

</NOBR></p><A NAME="40666"></A>
<UL><PRE>void * operator new(size_t, void *location)
{
  return location;
}
</PRE>
</UL><A NAME="10060"></A>
<P><A NAME="dingp93"></A>
This is probably simpler than you expected, but this is all placement <CODE>new</CODE> needs to do. After all, the purpose of <CODE>operator</CODE> <CODE>new</CODE> is to find memory for an object and return a pointer to that memory. In the case of placement <CODE>new</CODE>, the caller already knows what the pointer to the memory should be, because the caller knows where the object is supposed to be placed. All placement <CODE>new</CODE> has to do, then, is return the pointer that's passed into it. (The unused (but mandatory) <CODE>size_t</CODE> parameter has no name to keep compilers from complaining about its not being used; see <A HREF="./MC2_FR.HTM#5262" TARGET="_top" onMouseOver = "self.status = 'Link to MEC++ Item 6'; return true" onMouseOut = "self.status = self.defaultStatus">Item 6</A>.) Placement <CODE>new</CODE> is part of the standard C++ library (see <A HREF="../EC/EC7_FR.HTM#8392" TARGET="_top" onMouseOver = "self.status = 'Link to EC++ Item 49'; return true" onMouseOut = "self.status = self.defaultStatus">Item E49</A>). To use placement <CODE>new</CODE>, all you have to do is <CODE>#include</CODE> <CODE>&lt;new&gt;</CODE> (or, if your compilers don't yet support the new-style header names (again, see <A HREF="../EC/EC7_FR.HTM#8392" TARGET="_top" onMouseOver = "self.status = 'Link to EC++ Item 49'; return true" onMouseOut = "self.status = self.defaultStatus">Item E49</A>), <CODE>&lt;new.h&gt;</CODE>).<SCRIPT>create_link(93);</SCRIPT>

</p><A NAME="10068"></A>
<P><A NAME="dingp94"></A>
If we step back from placement <CODE>new</CODE> for a moment, we'll see that the relationship between the <CODE>new</CODE> operator and <CODE>operator</CODE> <CODE>new</CODE>, though
<A NAME="12055"></A><A NAME="p41"></A>you want to create an object on the heap, use the <CODE>new</CODE> operator. It both allocates memory and calls a constructor for the object. If you only want to allocate memory, call <CODE>operator</CODE> <CODE>new</CODE>; no constructor will be called. If you want to customize the memory allocation that takes place when heap objects are created, write your own version of <CODE>operator</CODE> <CODE>new</CODE> and use the <CODE>new</CODE> operator; it will automatically invoke your custom version of <CODE>operator</CODE> <CODE>new</CODE>. If you want to construct an object in memory you've already got a pointer to, use placement <CODE>new</CODE>.<SCRIPT>create_link(94);</SCRIPT>

</p><A NAME="11516"></A>
<P><A NAME="dingp95"></A>
(For additional insights into variants of <CODE>new</CODE> and <CODE>delete</CODE>, see <A HREF="../EC/EC2_FR.HTM#1894" TARGET="_top" onMouseOver = "self.status = 'Link to EC++ Item 7'; return true" onMouseOut = "self.status = self.defaultStatus">Item E7</A> and <A HREF="../MAGAZINE/CO_FRAME.HTM" TARGET="_top" onMouseOver = "self.status = 'Link to my article on counting objects'; return true" onMouseOut = "self.status = self.defaultStatus">my article on counting objects</A>.)<SCRIPT>create_link(95);</SCRIPT>

</p>

<P><A NAME="dingp96"></A><font ID="mhtitle">Deletion and Memory Deallocation</font><SCRIPT>create_link(96);</SCRIPT>

</P>

<A NAME="34292"></A>
<P><A NAME="dingp97"></A>
To avoid resource leaks, every dynamic allocation must be matched by an equal and opposite deallocation. The function <CODE>operator</CODE> <CODE>delete</CODE> is to the built-in <CODE>delete</CODE> operator as <CODE>operator</CODE> <CODE>new</CODE> is to the <CODE>new</CODE> operator. When you say something like <NOBR>this,<SCRIPT>create_link(97);</SCRIPT>

</NOBR></P>
<A NAME="34296"></A>
<UL><PRE>string *ps;
...
delete ps;                          // use the delete operator
</PRE>
</UL><A NAME="83299"></A><P><A NAME="dingp98"></A>
your compilers must generate code both to destruct the object <CODE>ps</CODE> points to and to deallocate the memory occupied by that <NOBR>object.<SCRIPT>create_link(98);</SCRIPT>

</NOBR></p><A NAME="74762"></A>
<P><A NAME="dingp99"></A>
The memory deallocation is performed by the <CODE>operator</CODE> <CODE>delete</CODE> function, which is usually declared like <NOBR>this:<SCRIPT>create_link(99);</SCRIPT>

</NOBR></p><A NAME="34304"></A>
<UL><PRE>void operator delete(void *memoryToBeDeallocated);
</PRE>
</UL><A NAME="34305"></A>
<P><A NAME="dingp100"></A>
<NOBR>Hence,<SCRIPT>create_link(100);</SCRIPT>

</NOBR></P>
<A NAME="34316"></A>
<UL><PRE>delete ps;
</PRE>
</UL><A NAME="34317"></A><P><A NAME="dingp101"></A>causes compilers to generate code that approximately corresponds to <NOBR>this:<SCRIPT>create_link(101);</SCRIPT>

</NOBR></P>
<A NAME="34318"></A>
<UL><PRE>
ps-&gt;~string();                      // call the object's dtor
</PRE>
</UL><A NAME="34319"></A>
<UL><PRE>
operator delete(ps);                // deallocate the memory
                                    // the object occupied
</PRE>
</UL><A NAME="11540"></A>
<P><A NAME="dingp102"></A>
One implication of this is that if you want to deal only with raw, uninitialized memory, you should bypass the <CODE>new</CODE> and <CODE>delete</CODE> operators entirely. Instead, you should call <CODE>operator</CODE> <CODE>new</CODE> to get the memory and <CODE>operator</CODE> <CODE>delete</CODE> to return it to the <NOBR>system:<SCRIPT>create_link(102);</SCRIPT>

</NOBR></p><A NAME="34551"></A>
<UL><PRE>
void *buffer =                      // allocate enough
  operator new(50*sizeof(char));    // memory to hold 50
                                    // chars; call no ctors
</PRE>
</UL><A NAME="34554"></A>
<UL><PRE>...
</PRE>
</UL><A NAME="34555"></A>
<UL><PRE>
operator delete(buffer);            // deallocate the memory;
                                    // call no dtors
</PRE>
</UL><A NAME="34561"></A>
<A NAME="p42"></A><P><A NAME="dingp103"></A>
This is the C++ equivalent of calling <CODE>malloc</CODE> and <CODE>free</CODE>.<SCRIPT>create_link(103);</SCRIPT>

</p><A NAME="40822"></A>
<P><A NAME="dingp104"></A>
If you use placement <CODE>new</CODE> to create an object in some memory, you should avoid using the <CODE>delete</CODE> o

⌨️ 快捷键说明

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