mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			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>
 |