mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			210 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			HTML
		
	
	
	
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 | 
						|
<html>
 | 
						|
<head>
 | 
						|
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 | 
						|
   <meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)">
 | 
						|
   <meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL">
 | 
						|
   <meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 20.">
 | 
						|
   <meta name="GENERATOR" content="vi and eight fingers">
 | 
						|
   <title>libstdc++-v3 HOWTO:  Chapter 20</title>
 | 
						|
<link rel="StyleSheet" href="../lib3styles.css">
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
 | 
						|
<h1 class="centered"><a name="top">Chapter 20:  General Utilities</a></h1>
 | 
						|
 | 
						|
<p>Chapter 20 deals with utility classes and functions, such as
 | 
						|
   the oft-debated <code>auto_ptr<></code>.
 | 
						|
</p>
 | 
						|
 | 
						|
 | 
						|
<!-- ####################################################### -->
 | 
						|
<hr>
 | 
						|
<h1>Contents</h1>
 | 
						|
<ul>
 | 
						|
   <li><a href="#1"><code>auto_ptr</code> is not omnipotent</a>
 | 
						|
   <li><a href="#2"><code>auto_ptr</code> inside container classes</a>
 | 
						|
   <li><a href="#3">Functors</a>
 | 
						|
   <li><a href="#4">Pairs</a>
 | 
						|
</ul>
 | 
						|
 | 
						|
<hr>
 | 
						|
 | 
						|
<!-- ####################################################### -->
 | 
						|
 | 
						|
<h2><a name="1"><code>auto_ptr</code> is not omnipotent</a></h2>
 | 
						|
   <p>I'm not going to try and explain all of the fun and delicious
 | 
						|
      things that can happen with misuse of the auto_ptr class template
 | 
						|
      (called AP here), nor am I going to try and teach you how to use
 | 
						|
      AP safely in the presence of copying.  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.
 | 
						|
   </p>
 | 
						|
   <p>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 <em>not</em> be used for arrays!
 | 
						|
   </p>
 | 
						|
   <p>AP <em>is</em> meant to prevent nasty leaks in the presence of
 | 
						|
      exceptions.  That's <em>all</em>.  This code is AP-friendly:
 | 
						|
      <pre>
 | 
						|
    // 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());
 | 
						|
    }
 | 
						|
      </pre>When an exception gets thrown, the instance of MyClass that's
 | 
						|
      been created on the heap will be <code>delete</code>'d as the stack is
 | 
						|
      unwound past <code>func()</code>.
 | 
						|
   </p>
 | 
						|
   <p>Changing that code as follows is <em>not</em> AP-friendly:
 | 
						|
      <pre>
 | 
						|
        APMC  ap (new MyClass[22]);
 | 
						|
      </pre>You will get the same problems as you would without the use
 | 
						|
      of AP:
 | 
						|
      <pre>
 | 
						|
        char*  array = new char[10];       // array new...
 | 
						|
        ...
 | 
						|
        delete array;                      // ...but single-object delete
 | 
						|
      </pre>
 | 
						|
   </p>
 | 
						|
   <p>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).
 | 
						|
   </p>
 | 
						|
   <p>Return <a href="#top">to top of page</a> or
 | 
						|
      <a href="../faq/index.html">to the FAQ</a>.
 | 
						|
   </p>
 | 
						|
 | 
						|
<hr>
 | 
						|
<h2><a name="2"><code>auto_ptr</code> inside container classes</a></h2>
 | 
						|
   <p>All of the <a href="../23_containers/howto.html">containers</a>
 | 
						|
      described in the standard library require their contained types
 | 
						|
      to have, among other things, a copy constructor like this:
 | 
						|
      <pre>
 | 
						|
    struct My_Type
 | 
						|
    {
 | 
						|
        My_Type (My_Type const&);
 | 
						|
    };
 | 
						|
      </pre>
 | 
						|
      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.
 | 
						|
   </p>
 | 
						|
   <p>The resulting rule is simple:  <em>Never ever use a container of
 | 
						|
      auto_ptr objects.</em>  The standard says that "undefined"
 | 
						|
      behavior is the result, but it is guaranteed to be messy.
 | 
						|
   </p>
 | 
						|
   <p>To prevent you from doing this to yourself, the
 | 
						|
      <a href="../19_diagnostics/howto.html#3">concept checks</a> built
 | 
						|
      in to this implementation will issue an error if you try to
 | 
						|
      compile code like this:
 | 
						|
      <pre>
 | 
						|
    #include <vector>
 | 
						|
    #include <memory>
 | 
						|
    
 | 
						|
    void f()
 | 
						|
    {
 | 
						|
        std::vector< std::auto_ptr<int> >   vec_ap_int;
 | 
						|
    }
 | 
						|
      </pre>
 | 
						|
      Should you try this with the checks enabled, you will see an error.
 | 
						|
   </p>
 | 
						|
   <p>Return <a href="#top">to top of page</a> or
 | 
						|
      <a href="../faq/index.html">to the FAQ</a>.
 | 
						|
   </p>
 | 
						|
 | 
						|
<hr>
 | 
						|
<h2><a name="3">Functors</a></h2>
 | 
						|
   <p>If you don't know what functors are, you're not alone.  Many people
 | 
						|
      get slightly the wrong idea.  In the interest of not reinventing
 | 
						|
      the wheel, we will refer you to the introduction to the functor
 | 
						|
      concept written by SGI as part of their STL, in
 | 
						|
      <a href="http://www.sgi.com/Technology/STL/functors.html">their
 | 
						|
      http://www.sgi.com/Technology/STL/functors.html</a>.
 | 
						|
   </p>
 | 
						|
   <p>Return <a href="#top">to top of page</a> or
 | 
						|
      <a href="../faq/index.html">to the FAQ</a>.
 | 
						|
   </p>
 | 
						|
 | 
						|
<hr>
 | 
						|
<h2><a name="4">Pairs</a></h2>
 | 
						|
   <p>The <code>pair<T1,T2></code> is a simple and handy way to
 | 
						|
      carry around a pair of objects.  One is of type T1, and another of
 | 
						|
      type T2; they may be the same type, but you don't get anything
 | 
						|
      extra if they are.  The two members can be accessed directly, as
 | 
						|
      <code>.first</code> and <code>.second</code>.
 | 
						|
   </p>
 | 
						|
   <p>Construction is simple.  The default ctor initializes each member
 | 
						|
      with its respective default ctor.  The other simple ctor,
 | 
						|
      <pre>
 | 
						|
    pair (const T1& x, const T2& y);
 | 
						|
      </pre>does what you think it does, <code>first</code> getting <code>x</code>
 | 
						|
      and <code>second</code> getting <code>y</code>.
 | 
						|
   </p>
 | 
						|
   <p>There is a copy constructor, but it requires that your compiler
 | 
						|
      handle member function templates:
 | 
						|
      <pre>
 | 
						|
    template <class U, class V> pain (const pair<U,V>& p);
 | 
						|
      </pre>The compiler will convert as necessary from U to T1 and from
 | 
						|
      V to T2 in order to perform the respective initializations.
 | 
						|
   </p>
 | 
						|
   <p>The comparison operators are done for you.  Equality
 | 
						|
      of two <code>pair<T1,T2></code>s is defined as both <code>first</code>
 | 
						|
      members comparing equal and both <code>second</code> members comparing
 | 
						|
      equal; this simply delegates responsibility to the respective
 | 
						|
      <code>operator==</code> functions (for types like MyClass) or builtin
 | 
						|
      comparisons (for types like int, char, etc).
 | 
						|
   </p>
 | 
						|
   <a name="pairlt">
 | 
						|
   <p>The less-than operator is a bit odd the first time you see it.  It
 | 
						|
      is defined as evaluating to:
 | 
						|
      <pre>
 | 
						|
    x.first  <  y.first  ||
 | 
						|
        ( !(y.first  <  x.first)  &&  x.second  <  y.second )
 | 
						|
      </pre>
 | 
						|
      The other operators are not defined using the <code>rel_ops</code>
 | 
						|
      functions above, but their semantics are the same.
 | 
						|
   </p>
 | 
						|
   </a>
 | 
						|
   <p>Finally, there is a template function called <code>make_pair</code>
 | 
						|
      that takes two references-to-const objects and returns an
 | 
						|
      instance of a pair instantiated on their respective types:
 | 
						|
      <pre>
 | 
						|
    pair<int,MyClass> p = make_pair(4,myobject);
 | 
						|
      </pre>
 | 
						|
   </p>
 | 
						|
   <p>Return <a href="#top">to top of page</a> or
 | 
						|
      <a href="../faq/index.html">to the FAQ</a>.
 | 
						|
   </p>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<!-- ####################################################### -->
 | 
						|
 | 
						|
<hr>
 | 
						|
<p class="fineprint"><em>
 | 
						|
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
 | 
						|
Comments and suggestions are welcome, and may be sent to
 | 
						|
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
 | 
						|
</em></p>
 | 
						|
 | 
						|
 | 
						|
</body>
 | 
						|
</html>
 |