Boost logo

Boost :

From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2001-07-25 10:01:28


----- Original Message -----
From: Greg Colvin <gcolvin_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, July 25, 2001 11:40 AM
Subject: Re: [boost] Re: downcasting smart pointers (suggested code)

> From: Fernando Cacciola <fcacciola_at_[hidden]>
> >
> > ----- Original Message -----
> > From: Peter Dimov <pdimov_at_[hidden]>
> > To: <boost_at_[hidden]>
> > Sent: Tuesday, July 24, 2001 5:24 PM
> > Subject: Re: [boost] Re: downcasting smart pointers (suggested code)
> >
> >
> > > From: "Greg Colvin" <gcolvin_at_[hidden]>
> > > [...]
> > >
> > > > template<typename BasePtr, typename DerivedPtr>
> > > > DerivedPtr whatever(BasePtr in) {
> > > > ...
> > > > DerivedPtr p = do_dynamic_cast<DerivedPtr>(in);
> > > > ...
> > > > return p;
> > > > }
> > >
> > > Or something like
> > >
> > > template<class Ptr> void whatever(Ptr p)
> > > {
> > > if(IDrawable q = do_dynamic_cast<IDrawable>(p)) q->draw();
> > > }
> > >
> > > where IDrawable is typedef'ed somewhere to be, say,
shared_ptr<Drawable>.
> > >
> > > (As an aside, people like to implement their own COM-like component
> > systems;
> > > it would be great if shared_ptr<> can be used for this. The two main
> > > obstacles are (1) no 'queryInterface' support - this would hopefully
be
> > > addressed by do_dynamic_cast - and (2) a shared_ptr<> created in a DLL
and
> > > destroyed in the main program causes problems when different heaps are
> > > used.)
> > >
> > shared_ptr<> is a non-intrusive rc smart pointer. It means that the
> > reference count is held in the smart pointer itself, not the object.
> > In COM-like systems, the reference counter is held by the object itself.
> > The problem of using shared_ptr<> with objects that mantain their own
> > reference count is that there are two different, unsyncronized counts
> > managing the same life time. This creates a runtime mess.
> >
> > It might be useful if shared_ptr<> could be either
non-intrusive/intrusive,
> > depending on the interface supported by the contained object.
> > That is:
> >
> > struct RefCountBase { void AddRef() ; etc... /* details ommited*/. } ;
> >
> > struct IFoo : public RefCountBase { ... } ;
> >
> > class Fred {} ;
> >
> > typedef shared_ptr<IFoo> ; // intrusive
> > typedef shared_ptr<Fred> ; // non-intrusive
>
> Are you suggesting that shared_ptr be specialized for RefCountBase?
>
Something like that, yes.

I can imagine a mechanism were you can specialize some traits class to
instruct shared_ptr<> that classes derived from a given base class have
intrusive rc.
It would look like:

(Off the top of my head)

struct intrusive_rc {} ;
struct non_intrusive_rc {} ;

template<class T> struct reference_counting_traits
{
   typedef non_intrusive_rc kind ;
} ;

template<> struct reference_counting_traits<IUnknown>
{
    typedef intrusive_rc kind ;
} ;

Then, shared_ptr<> will use reference_counting_traits<T>::kind to choose
between non-intrusive/intrusive rc implementation.

Fernando Cacciola
Sierra s.r.l.
fcacciola_at_[hidden]
www.gosierra.com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk