|
Boost : |
From: Andy Glew (glew_at_[hidden])
Date: 1999-11-10 10:13:25
> I very much do like being able to say
> a = b.
> Oh, yeah, you already get that with shared_ptr<T> assignment
> (one of my smart_ptrs is a degenerate pointer that always allocates
> on assignment - I call it coa_ptr<T>, copy on access.)
Excuse me, I misspoke.
With Boost's shared_ptr<T>,
a = b
has pointer semantics:
a->some_field = x
=> b->some_field = x.
To get value semantics, you need to do copy-on-write
on any potentially writeable dereference.
With manual proxies, the user may know of all writing methods.
With oblivious proxies in a library, your only choice is to
do the copy on write on any non-const lvalue producing
method. I.e.
smart_ptr<T>::operator smart_ptr<T>& () {
...break sharing, copying object pointed to
}
Unfortunately, this seems to have several problems:
(1) it doesn't work (at least with GCC 2.95)
(2) even if it did, there are a heck of a lot of places
where a non-const ref is needed
(often due to insufficient use of const)
(3) since even a const ref may be cast and written to,
it is not 100% safe.
These last two considerations motivated me to define
a non-shared coa_ptr<T>, where "coa" means "copy on
access". Such a coa_ptr always has value semantics;
whenever assigned to, it does something like
coa_ptr<T>& coa_ptr<T>::operator= ( const T& that ) {
if( this->ptr == that.ptr ) return *this;
if( this->ptr != 0 ) delete this->ptr;
this->ptr = that.ptr->clone();
return *this;
}
I.e. I gave up on copy-on-write, since there seem to be
too many potentially writeable places.
I.e. a coa_ptr<T> is the antithesis of a shared_ptr<T>.
All that a coa_ptr<T> does is provide a convenient
place for holding run-time polymorphic values, with
proper scopiing and ownership - and it dos this without
any of the funny ownership semantics of auto_ptr<T>.
STL containers of coa_ptr<T> are safe.
--- coa_ptr<T> don't have any of the sharing advantages of shared_ptr<T> or auto_ptr<T>. But, for polymorphic objects where each of the polymorphs is fairly simple, copying on each access yields a very convenient holder for polymorphic values. Thus, as described earlier, I start down the slippery slope. Vanilla coa_ptr<T> has pointer semantics and syntax, even though what it points to is unshared. You must say *a == *b rather than a = b But, if you want to put coa_ptr's in STL containers and use STL algorithms on it, it is very convenient to make a == b have value semantics. And so, for a < b, ...
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk