Topic: Proposal: Improved `auto_ptr
Author: Carlo Kid <carlo@runaway.xs4all.nl>
Date: 1996/08/12 Raw View
Starting with the `auto_ptr' implementation as originally posted to
comp.std.c++ on March 30, 1996 by Greg Colvin, I did run into a few
problems that could not be solved.
At the bottom of this post you can find my "improved" auto_ptr (please
comment on that ;), but first I'll try to explain when I missed what
functionality.
What has been added:
- A method `freeze()', to freeze ownership to a particular instance.
- A method `unfreeze()', which releases the strict ownership.
- A method `strict_ownership()' which returns wether or not this
instance has been 'frozen' it's ownership.
- Reintroduced `reset()', because it IS needed in certain situations.
The direct reason for me to add the `freeze' method was that I lost
the object (as 'const' as possibly possible) by just *printing* it to
cout... It seemed quite natural to me that at a certain point the
ownership as 'arrived' where you want it to go, after which you should
be able to 'freeze' it there.
Example:
I have two objects, the first is the 'info' part of an STL 'map' and the
second represents a linked list for the same elements because I needed
a second way of ordering. STL doesn't allow one element to be simultaneously
a map and a list, so my second object has its own prev/next pointers etc.
The relation between the objects is as follows:
When the first object is created a corresponding second object must be
created too (they relate one on one). However, after creation the second
object can be deleted again as a result of a certain event, and under other
special circumstances it can happen that the first object is removed without
that you want that the second object is removed.
In order to have all of this flexibility, the first object contains an auto_ptr
to the second object, creating it itself with new:
class Second { /* ... */ };
class First {
auto_ptr SndPtr;
public:
First() : SndPtr(new Second()) {}
};
Although this allows to copy `First' an arbitrary number of times (and believe
me, the STL knows its way with tempories :(, at a certain point - when the
object arrived where it should be: in the `map', I don't want it transfer the
ownership of SndPtr anymore ! And that's the point where I'd call `freeze'.
[ The fact that *even* passing a `const First' object to certain STL functions
(which never heared of the use of references it seems) deletes SndPtr.px (!)
at the destruction of some intermediate temporary of const First is directly
related to the use of 'mutable' infront of the 'bool owner' attribute... And
I wonder if that's Good. But on the other hand, even when we pass a non-const
First object to a function taking a const First, the ownership would be
transfered to the tempory, which is not what we want. ]
Finally a comment on why I think that the `reset' method should be re-added
again (independantly of the freeze stuff).
As I said, I needed to be able to delete the Second object without touching the
First object. That means that I want to do:
if (SndPtr.is_owner())
delete SndPtr.release();
else
SndPtr.release();
But we have no means of accessing `owner' in the original implementation
('is_owner' doesn't exist ;). So I think a function that combines deleting
the object pointed to with obviously resetting the ownership is needed.
Any discussion on improving this first attempt would be appriciated,
Carlo
auto_ptr.h:
// $Header: /usr/src/CVS/libr/support/auto_ptr.h,v 1.1 1996/08/10 18:04:21
carlo
//
// Author : Carlo (carlo@runaway.xs4all.nl)
//
// This implementation of `auto_ptr' was originally posted to comp.std.c++
// on March 30, 1996 by Greg Colvin.
//
// The template member functions have been commented because they are not
// supported by most compilers, yet.
//
// I added the boolean `frozen' and the methods `freeze', `unfreeze'
// and `is_frozen' to allow to freeze ownership.
//
// Re-introduced `reset' to be able to perform a 'destruction' without
// destructing the auto_ptr. Although this can also be done using freeze()
// I think this shortcut is more clear.
//
#ifndef SUPPORT_AUTO_PTR_H
#ifdef __GNUG__
#pragma interface
#endif
#define SUPPORT_AUTO_PTR_H
RCSTAG_H(support_auto_ptr, "$Id: auto_ptr.h,v 1.1 1996/08/10 18:04:21 carlo Exp
template<class X>
class auto_ptr {
mutable bool owner;
bool frozen;
X* px;
// template<class Y> friend class auto_ptr;
public:
explicit auto_ptr(X* p=0) : owner(p), frozen(false), px(p) {}
// template<class Y>
auto_ptr(const auto_ptr<X /*Y*/ >& r) :
owner(r.owner && !r.frozen), frozen(false),
px(r.frozen ? r.get() : r.release()) {}
// template<class Y>
auto_ptr& operator=(const auto_ptr<X /*Y*/ >& r) {
if ((void*)&r != (void*)this)
{
if (owner)
delete px;
owner = r.owner;
px = r.release();
}
return *this;
}
~auto_ptr() { if (owner) delete px; }
void reset() { bool own = owner; owner = 0; if (own) delete px; }
bool freeze() { frozen = true; return owner; }
void unfreeze() { frozen = false; }
X& operator*() const { return *px; }
X* operator->() const { return px; }
X* get() const { return px; }
X* release() const { owner = 0; return px; }
bool strict_owner() const { return frozen; }
};
#endif // SUPPORT_AUTO_PTR_H
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]