1 |
424 |
jeremybenn |
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3 |
|
|
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>auto_ptr</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><meta name="keywords" content=" ISO C++ , auto_ptr " /><meta name="keywords" content=" ISO C++ , library " /><link rel="home" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="memory.html" title="Chapter 11. Memory" /><link rel="prev" href="memory.html" title="Chapter 11. Memory" /><link rel="next" href="shared_ptr.html" title="shared_ptr" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">auto_ptr</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="memory.html">Prev</a> </td><th width="60%" align="center">Chapter 11. Memory</th><td width="20%" align="right"> <a accesskey="n" href="shared_ptr.html">Next</a></td></tr></table><hr /></div><div class="sect1" title="auto_ptr"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.util.memory.auto_ptr"></a>auto_ptr</h2></div></div></div><div class="sect2" title="Limitations"><div class="titlepage"><div><div><h3 class="title"><a id="auto_ptr.limitations"></a>Limitations</h3></div></div></div><p>Explaining all of the fun and delicious things that can
|
4 |
|
|
happen with misuse of the <code class="classname">auto_ptr</code> class
|
5 |
|
|
template (called <acronym class="acronym">AP</acronym> here) would take some
|
6 |
|
|
time. Suffice it to say that the use of <acronym class="acronym">AP</acronym>
|
7 |
|
|
safely in the presence of copying has some subtleties.
|
8 |
|
|
</p><p>
|
9 |
|
|
The AP class is a really
|
10 |
|
|
nifty idea for a smart pointer, but it is one of the dumbest of
|
11 |
|
|
all the smart pointers -- and that's fine.
|
12 |
|
|
</p><p>
|
13 |
|
|
AP is not meant to be a supersmart solution to all resource
|
14 |
|
|
leaks everywhere. Neither is it meant to be an effective form
|
15 |
|
|
of garbage collection (although it can help, a little bit).
|
16 |
|
|
And it can <span class="emphasis"><em>not</em></span>be used for arrays!
|
17 |
|
|
</p><p>
|
18 |
|
|
<acronym class="acronym">AP</acronym> is meant to prevent nasty leaks in the
|
19 |
|
|
presence of exceptions. That's <span class="emphasis"><em>all</em></span>. This
|
20 |
|
|
code is AP-friendly:
|
21 |
|
|
</p><pre class="programlisting">
|
22 |
|
|
// Not a recommend naming scheme, but good for web-based FAQs.
|
23 |
|
|
typedef std::auto_ptr<MyClass> APMC;
|
24 |
|
|
|
25 |
|
|
extern function_taking_MyClass_pointer (MyClass*);
|
26 |
|
|
extern some_throwable_function ();
|
27 |
|
|
|
28 |
|
|
void func (int data)
|
29 |
|
|
{
|
30 |
|
|
APMC ap (new MyClass(data));
|
31 |
|
|
|
32 |
|
|
some_throwable_function(); // this will throw an exception
|
33 |
|
|
|
34 |
|
|
function_taking_MyClass_pointer (ap.get());
|
35 |
|
|
}
|
36 |
|
|
</pre><p>When an exception gets thrown, the instance of MyClass that's
|
37 |
|
|
been created on the heap will be <code class="function">delete</code>'d as the stack is
|
38 |
|
|
unwound past <code class="function">func()</code>.
|
39 |
|
|
</p><p>Changing that code as follows is not <acronym class="acronym">AP</acronym>-friendly:
|
40 |
|
|
</p><pre class="programlisting">
|
41 |
|
|
APMC ap (new MyClass[22]);
|
42 |
|
|
</pre><p>You will get the same problems as you would without the use
|
43 |
|
|
of <acronym class="acronym">AP</acronym>:
|
44 |
|
|
</p><pre class="programlisting">
|
45 |
|
|
char* array = new char[10]; // array new...
|
46 |
|
|
...
|
47 |
|
|
delete array; // ...but single-object delete
|
48 |
|
|
</pre><p>
|
49 |
|
|
AP cannot tell whether the pointer you've passed at creation points
|
50 |
|
|
to one or many things. If it points to many things, you are about
|
51 |
|
|
to die. AP is trivial to write, however, so you could write your
|
52 |
|
|
own <code class="code">auto_array_ptr</code> for that situation (in fact, this has
|
53 |
|
|
been done many times; check the mailing lists, Usenet, Boost, etc).
|
54 |
|
|
</p></div><div class="sect2" title="Use in Containers"><div class="titlepage"><div><div><h3 class="title"><a id="auto_ptr.using"></a>Use in Containers</h3></div></div></div><p>
|
55 |
|
|
</p><p>All of the <a class="link" href="containers.html" title="Part VII. Containers">containers</a>
|
56 |
|
|
described in the standard library require their contained types
|
57 |
|
|
to have, among other things, a copy constructor like this:
|
58 |
|
|
</p><pre class="programlisting">
|
59 |
|
|
struct My_Type
|
60 |
|
|
{
|
61 |
|
|
My_Type (My_Type const&);
|
62 |
|
|
};
|
63 |
|
|
</pre><p>
|
64 |
|
|
Note the const keyword; the object being copied shouldn't change.
|
65 |
|
|
The template class <code class="code">auto_ptr</code> (called AP here) does not
|
66 |
|
|
meet this requirement. Creating a new AP by copying an existing
|
67 |
|
|
one transfers ownership of the pointed-to object, which means that
|
68 |
|
|
the AP being copied must change, which in turn means that the
|
69 |
|
|
copy ctors of AP do not take const objects.
|
70 |
|
|
</p><p>
|
71 |
|
|
The resulting rule is simple: <span class="emphasis"><em>Never ever use a
|
72 |
|
|
container of auto_ptr objects</em></span>. The standard says that
|
73 |
|
|
<span class="quote">“<span class="quote">undefined</span>”</span> behavior is the result, but it is
|
74 |
|
|
guaranteed to be messy.
|
75 |
|
|
</p><p>
|
76 |
|
|
To prevent you from doing this to yourself, the
|
77 |
|
|
<a class="link" href="ext_compile_checks.html" title="Chapter 29. Compile Time Checks">concept checks</a> built
|
78 |
|
|
in to this implementation will issue an error if you try to
|
79 |
|
|
compile code like this:
|
80 |
|
|
</p><pre class="programlisting">
|
81 |
|
|
#include <vector>
|
82 |
|
|
#include <memory>
|
83 |
|
|
|
84 |
|
|
void f()
|
85 |
|
|
{
|
86 |
|
|
std::vector< std::auto_ptr<int> > vec_ap_int;
|
87 |
|
|
}
|
88 |
|
|
</pre><p>
|
89 |
|
|
Should you try this with the checks enabled, you will see an error.
|
90 |
|
|
</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="memory.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="memory.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="shared_ptr.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 11. Memory </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> shared_ptr</td></tr></table></div></body></html>
|