mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-28 05:51:04 +00:00
131 lines
4.3 KiB
XML
131 lines
4.3 KiB
XML
<section xmlns="http://docbook.org/ns/docbook" version="5.0"
|
|
xml:id="std.util.memory.auto_ptr" xreflabel="auto_ptr">
|
|
<?dbhtml filename="auto_ptr.html"?>
|
|
|
|
<info><title>auto_ptr</title>
|
|
<keywordset>
|
|
<keyword>ISO C++</keyword>
|
|
<keyword>auto_ptr</keyword>
|
|
</keywordset>
|
|
</info>
|
|
|
|
|
|
|
|
<section xml:id="auto_ptr.limitations"><info><title>Limitations</title></info>
|
|
|
|
|
|
<para>Explaining all of the fun and delicious things that can
|
|
happen with misuse of the <classname>auto_ptr</classname> class
|
|
template (called <acronym>AP</acronym> here) would take some
|
|
time. Suffice it to say that the use of <acronym>AP</acronym>
|
|
safely in the presence of copying has some subtleties.
|
|
</para>
|
|
<para>
|
|
The AP class is a really
|
|
nifty idea for a smart pointer, but it is one of the dumbest of
|
|
all the smart pointers -- and that's fine.
|
|
</para>
|
|
<para>
|
|
AP is not meant to be a supersmart solution to all resource
|
|
leaks everywhere. Neither is it meant to be an effective form
|
|
of garbage collection (although it can help, a little bit).
|
|
And it can <emphasis>not</emphasis>be used for arrays!
|
|
</para>
|
|
<para>
|
|
<acronym>AP</acronym> is meant to prevent nasty leaks in the
|
|
presence of exceptions. That's <emphasis>all</emphasis>. This
|
|
code is AP-friendly:
|
|
</para>
|
|
<programlisting>
|
|
// Not a recommend naming scheme, but good for web-based FAQs.
|
|
typedef std::auto_ptr<MyClass> APMC;
|
|
|
|
extern function_taking_MyClass_pointer (MyClass*);
|
|
extern some_throwable_function ();
|
|
|
|
void func (int data)
|
|
{
|
|
APMC ap (new MyClass(data));
|
|
|
|
some_throwable_function(); // this will throw an exception
|
|
|
|
function_taking_MyClass_pointer (ap.get());
|
|
}
|
|
</programlisting>
|
|
<para>When an exception gets thrown, the instance of MyClass that's
|
|
been created on the heap will be <function>delete</function>'d as the stack is
|
|
unwound past <function>func()</function>.
|
|
</para>
|
|
<para>Changing that code as follows is not <acronym>AP</acronym>-friendly:
|
|
</para>
|
|
<programlisting>
|
|
APMC ap (new MyClass[22]);
|
|
</programlisting>
|
|
<para>You will get the same problems as you would without the use
|
|
of <acronym>AP</acronym>:
|
|
</para>
|
|
<programlisting>
|
|
char* array = new char[10]; // array new...
|
|
...
|
|
delete array; // ...but single-object delete
|
|
</programlisting>
|
|
<para>
|
|
AP cannot tell whether the pointer you've passed at creation points
|
|
to one or many things. If it points to many things, you are about
|
|
to die. AP is trivial to write, however, so you could write your
|
|
own <code>auto_array_ptr</code> for that situation (in fact, this has
|
|
been done many times; check the mailing lists, Usenet, Boost, etc).
|
|
</para>
|
|
</section>
|
|
|
|
<section xml:id="auto_ptr.using"><info><title>Use in Containers</title></info>
|
|
|
|
|
|
<para>
|
|
</para>
|
|
<para>All of the <link linkend="std.containers">containers</link>
|
|
described in the standard library require their contained types
|
|
to have, among other things, a copy constructor like this:
|
|
</para>
|
|
<programlisting>
|
|
struct My_Type
|
|
{
|
|
My_Type (My_Type const&);
|
|
};
|
|
</programlisting>
|
|
<para>
|
|
Note the const keyword; the object being copied shouldn't change.
|
|
The template class <code>auto_ptr</code> (called AP here) does not
|
|
meet this requirement. Creating a new AP by copying an existing
|
|
one transfers ownership of the pointed-to object, which means that
|
|
the AP being copied must change, which in turn means that the
|
|
copy ctors of AP do not take const objects.
|
|
</para>
|
|
<para>
|
|
The resulting rule is simple: <emphasis>Never ever use a
|
|
container of auto_ptr objects</emphasis>. The standard says that
|
|
<quote>undefined</quote> behavior is the result, but it is
|
|
guaranteed to be messy.
|
|
</para>
|
|
<para>
|
|
To prevent you from doing this to yourself, the
|
|
<link linkend="manual.ext.compile_checks">concept checks</link> built
|
|
in to this implementation will issue an error if you try to
|
|
compile code like this:
|
|
</para>
|
|
<programlisting>
|
|
#include <vector>
|
|
#include <memory>
|
|
|
|
void f()
|
|
{
|
|
std::vector< std::auto_ptr<int> > vec_ap_int;
|
|
}
|
|
</programlisting>
|
|
<para>
|
|
Should you try this with the checks enabled, you will see an error.
|
|
</para>
|
|
</section>
|
|
|
|
</section>
|