Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-03-01 14:09:09


Michael Anderson wrote:
> Howdy everyone.
> I have some code that uses pointers to member variables that I want to
> switch to using boost::shared_ptrs, some of the code looks like this.
>
> class Bar {};
> class Foo
> {
> public:
> Bar bar;
> };
>
> ...
> Foo * fooptr = new Foo;
> Bar * barptr = &Foo.bar;
> ...
>
> So to make this work with shared_ptrs I can do this:
>
> class Bar {}
> class Foo
> {
> public:
> Foo() : bar(new Bar) {}
> shared_ptr<Bar> bar;
> };
>
> ...
> shared_ptr<Foo> fooptr(new Foo);
> shared_ptr<Bar> barptr = fooptr->bar;
> ...
>
> But this means I have to change each of the classes... which is a bit
> ugly. Also it has unlinked the lifetime of the Bar and Foo objects.
>
> So the solution I've come up with means that the Foo object only gets
> destroyed when both the barptr and the fooptr are destroyed.
> Unfortunately this requires additions to the shared_ptr class (the
> patch is below). The changes are _very_ similar to what is used for
> handling the pointer conversions and casts.

There has been a formal proposal to add an "aliasing constructor" (as in
your patch, but public and without the tag) to std::tr1::shared_ptr and I'm
considering adding one for 1.35. In the meantime,

> +template<class T, class M> shared_ptr<M> member_pointer(
> shared_ptr<T> const & t, M* m)
> +{
> + return shared_ptr<M>(t,m, detail::memberpointer_tag() );
> +}

you can use:

template<class T, class M> shared_ptr<M> member_pointer(
shared_ptr<T> const & t, M* m)
{
    return shared_ptr<M>( m, bind( &shared_ptr<T>::reset, t ) );
}

A similar trick is described in:

http://www.boost.org/libs/smart_ptr/sp_techniques.html#another_sp


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