Boost logo

Boost :

From: David B. Held (dheld_at_[hidden])
Date: 2002-04-30 18:20:06

"Greg Colvin" <greg_at_[hidden]> wrote in message
> [...]
> The client of a shared_ptr need not be concerned with where
> the reference count is stored, how the referenced object is
> destroyed, or how the memory for the count and object is
> managed, so why should those details get exposed in the name
> of the smart pointer type?

Well, my understanding is that while those details don't make a whit
of difference as to how the pointer is *used*, it does make a
difference as to how the pointer can interoperate with other pointers
that have different implementations. Does it just come down to
writing conversions to shared_ptr and back?

> Using shared_ptr those details are set when the smart pointer
> is constructed, and need not be revealed to the client. Note that
> this means that the creator of a smart pointer can change those
> details without requiring recompilation of its clients, and without
> breaking binary compatibility.

So are you suggesting that I, as a clever user of shared_ptr, could
have one set of "stock" boost::shared_ptr<T>s in one part of my
app, and a different set of boost::shared_ptr<T>s in a different
part of my app, where I re-implement shared_ptr to use, say,
COM ref-counting? Does this violate ODR? Or would I have
to give my version of shared_ptr a different name? Or is it the
case that I can only have one implementation of shared_ptr in a
given app, but it doesn't have to be the "normal" one? I'm really
unclear on the "changing the details" part.

> I don't see why a policy-based smart pointer template cannot
> preserve this feature of shared_ptr.

My understanding is that shared_ptr fixes the Checking policy,
Conversion policy, and Ownership policy to AssertCheck,
DisallowConversion, and external ref-counting. While it is able
to use an intrusive refcount, it only works with one kind of intrusive
count, and to use this count, it must be initialized from a pointer
with a different type name. boost::smart_ptr still divides up
functionality among type names. It just does so with explicit
names, instead of templated names. boost::scoped_ptr is to
boost::shared_ptr as Loki::SmartPtr<DestructiveCopy> is to
Loki::SmartPtr. And you could even typedef the SmartPtrs to
look just like their boost equivalents, no? As far as interoperability
among Ownership types, that's just a matter of writing the
appropriate policies. It should be trivial to write a
BoostRefCounted ownership policy that uses the boost::counted_base
count, provides construction from boost::shared_ptr and
boost::intrusive_ptr, as well as to Loki::SmartPtr<BoostIntrusive>.
Here's a rough outline, with extraneous details removed. It should
demonstrate that it is entirely possible to create a
Loki::SmartPtr<BoostRefCounted> that interoperates with
Loki::SmartPtr<BoostIntrusive> just like boost::shared_ptr<>
interoperates with boost::intrusive_ptr<>.

    template <typename P>
    class boost_ref_counted
        // Borland 5.5.1 specific workarounds
        typedef checked_deleter<T> deleter;
        typedef shared_ptr<T> this_type;

        : count_(0, deleter())

        boost_ref_counted(const boost_intrusive<P>& p)
        : count_(p.get())

        P clone(const P& val)
            return val;

        bool release(const P&)
            // shared_count does the deleting
            return false;

        void swap(ref_counted& rhs)


        // Data
        detail::shared_count count_;

After writing the code, I realized that making Loki::SmartPtr interoperate
with boost::shared_ptr would require cooperation with shared_ptr. But
there is certainly nothing in principle from preventing this.


Boost list run by bdawes at, gregod at, cpdaniel at, john at