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

📄 miautopr.htm

📁 一个非常适合初学者入门的有关c++的文档
💻 HTM
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">
<HTML LANG="EN">
<HEAD>
<TITLE>More Effective C++ | An auto_ptr Implementation</TITLE>
<LINK REL=STYLESHEET HREF=../INTRO/ECMEC.CSS>
<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/COOKIE.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">var imagemax = 0; setCurrentMax(0);</SCRIPT>
<SCRIPT LANGUAGE="Javascript" SRC="../JAVA/DINGBATS.JS"></SCRIPT>
<SCRIPT LANGUAGE="Javascript">
var dingbase = "MIAUTODR.HTM";
var dingtext = "MEC++ auto_ptr, P";
if (self == top) {
 top.location.replace(dingbase + this.location.hash);
}</SCRIPT>

</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" ONLOAD="setResize()">
<!-- SectionName="MEC++ auto_ptr implementation" -->
<A NAME="74034"></A>
<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MIREADFR.HTM" TARGET="_top">Recommended Reading</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="../BOOKINDX/INDEX.HTM" TARGET="_top">Books' Index</A></FONT></DIV>


<A NAME="p291"></A>
<P><A NAME="dingp1"></A><font ID="mgtitle">An <CODE>auto_ptr</CODE> Implementation</font><SCRIPT>create_link(1);</SCRIPT>
</P>

<P><A NAME="dingp2"></A>
Items <A HREF="./MI9_FR.HTM#5292" TARGET="_top">9</A>, <A HREF="./MI10_FR.HTM#38223" TARGET="_top">10</A>, <A HREF="./MI26_FR.HTM#5350" TARGET="_top">26</A>, <A HREF="./MI31_FR.HTM#34883" TARGET="_top">31</A> and <A HREF="./MI32_FR.HTM#5373" TARGET="_top">32</A> attest to the remarkable utility of the <CODE>auto_ptr</CODE> template. Unfortunately, few compilers currently ship with a "correct" implementation.<A HREF="#74038"><SUP>1</SUP></A> Items <A HREF="./MI9_FR.HTM#5292" TARGET="_top">9</A> and <A HREF="./MI28_FR.HTM#61766" TARGET="_top">28</A> sketch how you might write one yourself, but it's nice to have more than a sketch when embarking on real-world <NOBR>projects.
<SCRIPT>create_link(2);</SCRIPT>
</NOBR></P><A NAME="74052"> </A>
<P><A NAME="dingp3"></A>
Below are two presentations of an implementation for <CODE>auto_ptr</CODE>. The first presentation documents the class interface and implements all the member functions outside the class definition. The second implements each member function within the class definition. Stylistically, the second presentation is inferior to the first, because it fails to separate the class interface from its implementation. However, <CODE>auto_ptr</CODE> yields simple classes, and the second presentation brings that out much more clearly than does the <NOBR>first.
<SCRIPT>create_link(3);</SCRIPT>
</NOBR></P><A NAME="74053"> </A>
<P><A NAME="dingp4"></A>
Here is <CODE>auto_ptr</CODE> with its interface <NOBR>documented:<SCRIPT>create_link(4);</SCRIPT>
</NOBR></P>
<UL><A NAME="73912"> </A>
<PRE>template&lt;class T&gt;
class auto_ptr {
public:
  explicit auto_ptr(T *p = 0);              // see <A HREF="./MI5_FR.HTM#5970" TARGET="_top">Item 5</A> for a
                                            // description of "explicit"
</PRE><A NAME="72770"> </A>
<PRE>  template&lt;class U&gt;                         // copy constructor member
  auto_ptr(auto_ptr&lt;U&gt;&amp; rhs);               // template (see <A HREF="./MI28_FR.HTM#61766" TARGET="_top">Item 28</A>):
                                            // initialize a new auto_ptr
                                            // with any compatible
                                            // auto_ptr
</PRE><A NAME="73311"> </A>
<PRE>  ~auto_ptr();
</PRE><A NAME="73221"> </A>
<PRE>  template&lt;class U&gt;                         // assignment operator
  auto_ptr&lt;T&gt;&amp;                              // member template (see
  operator=(auto_ptr&lt;U&gt;&amp; rhs);              // <A HREF="./MI28_FR.HTM#61766" TARGET="_top">Item 28</A>): assign from any
                                            // compatible auto_ptr
</PRE><A NAME="74008"> </A>
<A NAME="72560"> </A>
<PRE>  <A NAME="p292"></A>T&amp; operator*() const;                     // see <A HREF="./MI28_FR.HTM#61766" TARGET="_top">Item 28</A>
  T* operator-&gt;() const;                    // see <A HREF="./MI28_FR.HTM#61766" TARGET="_top">Item 28</A>
</PRE><A NAME="72562"> </A>
<PRE>  T* get() const;                           // return value of current
                                            // dumb pointer
</PRE><A NAME="72804"> </A>
<PRE>  T* release();                             // relinquish ownership of
                                            // current dumb pointer and
                                            // return its value
</PRE><A NAME="72564"> </A>
<PRE>  void reset(T *p = 0);                     // delete owned pointer;
                                            // assume ownership of p
private:
  T *pointee;
</PRE><A NAME="73994"> </A>
<PRE>template&lt;class U&gt;                           // make all auto_ptr classes
friend class auto_ptr&lt;U&gt;;                   // friends of one another
};
</PRE><A NAME="72951"> </A>
<PRE>template&lt;class T&gt;
inline auto_ptr&lt;T&gt;::auto_ptr(T *p)
: pointee(p)
{}
</PRE><A NAME="72956"> </A>
<PRE>template&lt;class T&gt;
  inline auto_ptr&lt;T&gt;::auto_ptr(auto_ptr&lt;U&gt;&amp; rhs)
  : pointee(rhs.release())
  {}
</PRE><A NAME="73730"> </A>
<PRE>template&lt;class T&gt;
inline auto_ptr&lt;T&gt;::~auto_ptr()
{ delete pointee; }
</PRE><A NAME="72961"> </A>
<PRE>template&lt;class T&gt;
  template&lt;class U&gt;
  inline auto_ptr&lt;T&gt;&amp; auto_ptr&lt;T&gt;::operator=(auto_ptr&lt;U&gt;&amp; rhs)
  {
    if (this != &amp;rhs) reset(rhs.release());
    return *this;
  }
</PRE><A NAME="72968"> </A>
<PRE>template&lt;class T&gt;
inline T&amp; auto_ptr&lt;T&gt;::operator*() const
{ return *pointee; }
</PRE><A NAME="72971"> </A>
<PRE>template&lt;class T&gt;
inline T* auto_ptr&lt;T&gt;::operator-&gt;() const
{ return pointee; }
</PRE><A NAME="72974"> </A>
<PRE>template&lt;class T&gt;
inline T* auto_ptr&lt;T&gt;::get() const
{ return pointee; }
</PRE><A NAME="72977"> </A>
<PRE><A NAME="p293"></A>template&lt;class T&gt;
inline T* auto_ptr&lt;T&gt;::release()
{
  T *oldPointee = pointee;
  pointee = 0;
  return oldPointee;
}
</PRE><A NAME="72985"> </A>
<PRE>template&lt;class T&gt;
inline void auto_ptr&lt;T&gt;::reset(T *p)
{
  if (pointee != p) {
    delete pointee;
    pointee = p;
  }
}
</PRE></UL>
<A NAME="73466"> </A>
<P><A NAME="dingp5"></A>
Here is <CODE>auto_ptr</CODE> with all the functions defined in the class definition. As you can see, there's no brain surgery going on here:<SCRIPT>create_link(5);</SCRIPT>
</P>
<A NAME="73515"> </A>
<UL><PRE>template&lt;class T&gt;
class auto_ptr {
public:
  explicit auto_ptr(T *p = 0): pointee(p) {}
</PRE><A NAME="73552"> </A>
<PRE>  template&lt;class U&gt;
  auto_ptr(auto_ptr&lt;U&gt;&amp; rhs): pointee(rhs.release()) {}
</PRE><A NAME="73524"> </A>
<PRE>  ~auto_ptr() { delete pointee; }
</PRE><A NAME="73479"> </A>
<PRE>  template&lt;class U&gt;
  auto_ptr&lt;T&gt;&amp; operator=(auto_ptr&lt;U&gt;&amp; rhs)
  {
    if (this != &amp;rhs) reset(rhs.release());
    return *this;
  }
</PRE><A NAME="73530"> </A>
<PRE>  T&amp; operator*() const { return *pointee; }
</PRE><A NAME="73536"> </A>
<PRE>  T* operator-&gt;() const { return pointee; }
</PRE><A NAME="73542"> </A>
<PRE>  T* get() const { return pointee; }
</PRE><A NAME="73568"> </A>
<PRE>  T* release()
  {
    T *oldPointee = pointee;
    pointee = 0;
    return oldPointee;
  }
</PRE><A NAME="73512"> </A>
<PRE>  void reset(T *p = 0)
  {
    if (pointee != p) {
      delete pointee;
      pointee = p;
    }
  }
  private:
    T *pointee;

  template&lt;class U&gt; friend class auto_ptr&lt;U&gt;;
  };
</PRE></UL>

<A NAME="p294"></A><A NAME="74014"></A>

<P><A NAME="dingp6"></A>If your compilers don't yet support <CODE>explicit</CODE>, you may safely <CODE>#define</CODE> it out of <NOBR>existence:<SCRIPT>create_link(6);</SCRIPT>
</NOBR></P>

<UL><A NAME="73592"> </A>
<PRE>#define explicit
</PRE></UL><A NAME="73593"> </A>

<P><A NAME="dingp7"></A>This won't make <CODE>auto_ptr</CODE> any less functional, but it will render it slightly less safe. For details, see <A HREF="./MI5_FR.HTM#5970" TARGET="_top">Item 5</A>.<SCRIPT>create_link(7);</SCRIPT>
</P>
<A NAME="73652"> </A>

<P><A NAME="dingp8"></A>If your compilers lack support for member templates, you can use the non-template <CODE>auto_ptr</CODE> copy constructor and assignment operator described in <A HREF="./MI28_FR.HTM#61766" TARGET="_top">Item 28</A>. This will make your <CODE>auto_ptr</CODE>s less convenient to use, but there is, alas, no way to approximate the behavior of member templates. If member templates (or other language features, for that matter) are important to you, let your compiler vendors know. The more customers ask for new language features, the sooner vendors will implement <NOBR>them.
<SCRIPT>create_link(8);</SCRIPT>
</NOBR></P>
<A NAME="73998"> </A>

<DIV ALIGN="CENTER"><FONT SIZE="-1">Back to <A HREF="./MIREADFR.HTM" TARGET="_top">Recommended Reading</A> &nbsp;&nbsp;<BR>&nbsp;&nbsp;Continue to <A HREF="../BOOKINDX/INDEX.HTM" TARGET="_top">Books' Index</A></FONT></DIV>



<A NAME="74038"></A>
<HR WIDTH="100%">
<A NAME="dingp9"></A>
<SUP>1</SUP> This is primarily because the specification for <CODE>auto_ptr</CODE>
as for years been a moving target. The final specification was adopted only in
November 1997. For details, consult <NOBR><FONT COLOR="#FF0000" SIZE="-2"><B>&deg;</B></FONT><A HREF="http://www.awl.com/cseng/cgi-bin/cdquery.pl?name=bookm_auto" ONMOUSEOVER="self.status='Addison Wesley Web Site for this product'; return true" ONMOUSEOUT="self.status=self.defaultStatus" TARGET="_top">the</NOBR> <CODE>auto_ptr</CODE> information at this book's WWW Site</A>.
Note that the <CODE>auto_ptr</CODE> described here omits a few details present in the official version, such as the fact that <CODE>auto_ptr</CODE> is in the <CODE>std</CODE> namespace (see <A HREF="./MI35_FR.HTM#5473" TARGET="_top">Item 35</A>) and that its member functions promise not to throw exceptions.<SCRIPT>create_link(9);</SCRIPT>
<BR>
<A HREF="#74034">Return</A>

</BODY>
</HTML>

⌨️ 快捷键说明

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