$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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, ...