Boost logo

Boost :

From: Fernando Cacciola (fcacciola_at_[hidden])
Date: 2001-07-25 08:42:22


----- 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

I wasn't part of boost while shared_ptr was reviewed, so I don't know what
was considered about this.
What I do know, however, is that using shared_ptr with objects that maintain
their own reference count isn't possible.

I tried this because I had my own intrusive rc scheme, and the first thing I
intended when I got boost for the first time was to replace my rcptr<> class
with shared_ptr<>; but I couldn't for the reasons given above.

I think a proxy scheme could be used to refactor shared_ptr<> to support the
suggested functionality.
If you are intereseted I can post a sample implementation.

> Still, I prefer that shared_dynamic_cast<> be left as an option. More
> focused (less generic) interfaces are less error prone, when genericity is
> not required.

Agreed.

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