🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #3155

Cleaning auto_ptr copy semantics.

#3155
From: Greg Colvin
Date: Fri, 26 Jan 1996 15:47
158 lines
6760 bytes
Our working paper's auto_ptr (20.4.5) specifies a non-const copy constructor 
and assignment operator.  This specification makes functions that return 
auto_ptr less useful than I intended, due to a language restriction on
modifying temporaries.  Since changing the language specification seems not
to be an option, a change to auto_ptr is in order.  

The smallest change I can see that preserves the semantics of strict 
ownership is to separate the concepts of "holding a pointer" and "owning 
an object", so that more than one auto_ptr can hold a pointer to an object,
but only one auto_ptr can own the object.  

Note that only the held pointer is directly accessible; which auto_ptr 
owns an object is observable only via the side effects of destructor calls.
Thus providing const arguments to the copy constructor and assignment 
operator and making release() a const function seem to me a reasonable 
case of "logical constness". 

Note also that reset() must go, since the idiom p.reset(q.release()) 
cannot safely transfer ownership.  I would happily remove get() as well, 
since its primary use may turn out to be leaking pointers.

A simple implementation makes the semantics clear:

   template<class X> class auto_ptr {
      X* px;
      mutable bool owner;
   public:
      explicit auto_ptr(X* p=0) : px(p), owner(true) {}
      template<class Y>
         auto_ptr(const auto_ptr<Y>& r) : px(r.release()), owner(true) {}
      template<class Y>
         auto_ptr& operator=(const auto_ptr<Y>& r) {
            if (&r != this) {
               if (owner) delete px; else owner = true;
               px = r.release();
            }
            return *this;
         }
      ~auto_ptr() { if (owner) delete px; }

      X& operator*()  const { return *px; }
      X* operator->() const { return px; }
      X* get()        const { return px; }
      X* release()    const { owner = false; return px; }
   };

This implementation is slightly bigger (one bool) and slightly slower
(two extra tests and two and one-half extra assignments across eight
functions) than the comparable implementation of the WP semantics.  On
some hardware it might make sense to save space at the cost of masking 
off the ownership bit or trapping memory hardware interrupts.

The changed Working Paper text I plan to propose at Scotts Valley is:


20.4.5  Template class auto_ptr                          [lib.auto.ptr]

Template auto_ptr holds onto a pointer to an object obtained via new 
and deletes that object when it is the owner of that object and it 
itself is destroyed (such as when leaving block scope 6.7).

namespace std {
  template<class X> class auto_ptr {
  public:
  // 20.4.5.1 construct/copy/destroy:
    explicit auto_ptr(X* p=0);
    template<class Y> auto_ptr(const auto_ptr<Y>&);                     |
    template<class Y> auto_ptr& operator=(const auto_ptr<Y>&);          |
    ~auto_ptr();
  // 20.4.5.2 members:
    X& operator*() const;
    X* operator->() const;
    X* get() const;                                                      ?
    X* release() const;                                                 | 
                                                                        |
  };
}

The auto_ptr provides a semantics of strict ownership.  After initial   |
construction an auto_ptr owns the object it holds a pointer to.  An     |
object may be safely owned by only one auto_ptr, so copying an auto_ptr |
copies the pointer and transfers ownership to the destination.          |


20.4.5.1  auto_ptr constructors                     [lib.auto.ptr.cons]

explicit auto_ptr(X* p = 0);

  Requires:  
    p points to an object of type X or a class derived from X for which 
    delete p is defined and accessible, or else p is a null pointer.
  Postconditions:
    *this holds the pointer p.                                          |
    *this is the owner of the object **this.                            |

template<class Y> auto_ptr(const auto_ptr<Y>& a);                       |

  Requires:  
    Y is type X or a class derived from X for which delete(Y*) is 
    defined and accessible.
  Effects:  
    Calls a.release().
  Postconditions:  
    *this holds the pointer returned from a.release().                  |
    *this is the owner of the object **this.                            |

template<class Y> auto_ptr<X>& operator=(const auto_ptr<Y>& a);         |

  Requires:
    Y is type X or a class derived from X for which delete(Y*) is 
    defined and accessible.
  Effects:  
    If *this is the owner of **this and this != &a then delete &**this. |
    Calls a.release().
  Returns: 
    *this.
  Postconditions: 
    *this holds the pointer returned from a.release().                  |
    *this is the owner of the object **this.                            |

~auto_ptr();

  Effects:
    If *this is the owner of **this then delete &**this.                |


20.4.5.2  auto_ptr members                       [lib.auto.ptr.members]

X& operator*() const;

  Requires:
    get() != 0
  Returns:
    A reference to the object pointed to by the pointer held by *this.  |

X* operator->() const;

  Returns:
    The pointer held by *this.                                          |

X* get() const;                                                          ?
                                                                         ?
  Returns:                                                               ?
    The pointer held by *this.                                          |?

X* release() const;                                                     |

  Returns:
    The pointer held by *this.                                          |
  Postcondition:
    *this is not the owner of the object **this.                        |


                                                                        |

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <gregorDLrrun.K2x@netcom.com>
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage
From: gregor@netcom.com (Greg Colvin)
Newsgroups: comp.std.c++
Subject: Cleaning auto_ptr copy semantics.
Date: 26 Jan 1996 15:47:28 GMT
Organization: Netcom Online Communications Services (408-241-9760 login: guest)
Approved: clamage@eng.sun.com (comp.std.c++)
Message-ID: <gregorDLrrun.K2x@netcom.com>
NNTP-Posting-Host: taumet.eng.sun.com
Content-Type: text
Apparently-To: comp-std-c++@uunet.uu.net
Content-Length: 5863
X-Lines: 154
Originator: clamage@taumet