Topic: auto_ptr idioms


Author: gnb@bby.com.au (Gregory Bond)
Date: 1996/02/13
Raw View
[Warning: novice comments follow]

Greg's comments are most enlightening, coming as it does on the end of
some pondering of my own on the subject.  I had identified a different
set of three scenarios where an auto_ptr-like functionality was
needed (borrowing some of Greg's nomenclature):

- An automatic variable to hold the return value from new
- An object to return from a source() function or pass to a sink() function
- An object to be placed into an STL container such as vector<>

(The problem with vector<> is that we want the container to "own" the
new'd data, but vector may do a bunch of realloc's and hence object
copies, so AutoPtr is not appropriate.)

It seems to me that the three problems are sufficiently differrent
that to use the same smart pointer template for all three would be
stretching the object design (witness the debate over the standard
auto_ptr<> which attempts to fill the first two roles).  Hence I was
considering three related and similar templates:

- AutoPtr, basically auto_ptr with private op= and copy ctor.
- RetPtr, a pointer+owner class for function calls/returns (with
  mutable owner flag) that can copy and assign, with copy/assignment
  transferring ownership to the new object but not invalidating the
  pointer. Destruction causes a delete only for the owning object. NO
  operator->() function (so that "T*p = source()" will not compile).
  AutoPtr would be a friend of this class and an AutoPtr could be
  constructed from a RetPtr, transferring ownership to the AutoPtr
  (used to return from a source() function).  RetPtr can be contructed
  from an AutoPtr (assuming ownership & hence leaving the AutoPtr
  NULL) to pass to a sink() function.
- ConPtr, a pointer+owner class similar to RetPtr for container
  membership.  Copyable/assignable, which transfers ownership.  NOT
  assignable to an AutoPtr, but DOES have operator->() (so things like
  vec.head()->foo() work).

For completeness, I would add array versions of all three (that did
delete[] instead of delete), and a CopyPtr that did a deep copy on
assignment or copy construction.  An array version of CopyPtr would be
subsumed by vector<> or a simpler fixed array class.  The CopyPtr
would also work as a class member.  A CntPtr (reference counted) class
would be a logical addition.

RetPtr and ConPtr could of course leave dangling pointers, but that is
hardly a new problem in either C or C++.

Member templates would make all this work in the face of inheritance.
(i.e. assigning a RetPtr<Derived> to an AutoPtr<Base>).

[Side question:  Given
 template <class T> class A {
  template <class S> A(const A<S>&);
 }
does that define a valid copy-ctor for pass-by-value or for binding
tempraries to?  Or do you need an explicit "A(const A&)"?
]

The intent is to disallow naked pointers "owning" any memory in a
local style guide, and enfore use of one of these smart pointer
classes.

Am I missing anything here?

Greg.
--
Gregory Bond <gnb@bby.com.au> Burdett Buckeridge & Young Ltd Melbourne Australia
``Efforts to maintain the "purity" of a language only succeed in establishing an
  elite class of people who know the shibboleths.  Ordinary folks know better,
  even if they don't know what "shibboleth" means.'' - Larry Wall

[ 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://reality.sgi.com/employees/austern_mti/std-c++/policy.html
]