Boost logo

Boost :

From: Hervé Brönnimann (hervebronnimann_at_[hidden])
Date: 2007-03-02 00:50:40


Michael: This is exactly what aliasing is for. I don't use
boost::shared_ptr, but just looking at it I can't find any mention of
aliasing. Maybe the library authors will reply to you. Meanwhile, I
believe that aliasing is much more general than sharing accesses to
members.

The usual examples are about pointer to a temporary buffer (e.g. for
I/O) and various pointers pointing inside the buffer, or a pointer to
buffers in an I/O vec chain, or iterator/node pointers inside a list,
all of which must live at least as long as the buffer / chain / list
to which they're members of.

I know that the shared pointer at my firm supports aliasing and that
is a very useful and widely used feature. I'm surprised it wouldn't
be supported by boost.

Cheers,

--
Herve
On Feb 28, 2007, at 12:22 AM, 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.
>
> Anyway I was wondering whether this is useful to anyone else, and
> whether there was any pitfalls I might have missed....
> Thanks,
> Mike Anderson
>
> Example Usage :
>
> #include <iostream>
> #include "boost/shared_ptr.hpp"
> class Foo
> {
>  public:
>    double m;
>    Foo() : m(1.0)
>    {
>      std::cout<<"creating Foo @ "<<this<<std::endl;
>    }
>
>    ~Foo()
>    {
>      std::cout<<"destroying Foo @ "<<this<<std::endl;
>    }
> };
>
> int main()
> {
>  {
>    boost::shared_ptr<Foo> fooptr( new Foo );
>    {
>        boost::shared_ptr<double> mptr = boost::member_pointer(fooptr,
> &fooptr->m);
>    }
>    // Foo destroyed here...
>  }
>
>  {
>    boost::shared_ptr<double> mptr;
>    {
>      boost::shared_ptr<Foo> fooptr( new Foo );
>      mptr = boost::member_pointer(fooptr, &fooptr->m);
>    }
>    // Foo destroyed here... even though mptr is a pointer to double.
>  }
> }
>
> class Bar {};
> class Foo
> {
>  public:
>     Bar bar;
> };
>
> shared_ptr<Foo> fooptr(new Foo);
> shared_ptr<Bar> barptr = boost::member_ptr(fooptr, &fooptr->bar);
>
> Patch : (not from the recent trunk of boost....)
>
> --- shared_ptr.hpp
> +++ shared_ptr.hpp
> @@ -50,6 +50,7 @@
> struct const_cast_tag {};
> struct dynamic_cast_tag {};
> struct polymorphic_cast_tag {};
> +struct memberpointer_tag {};
>
> template<class T> struct shared_ptr_traits
> {
> @@ -191,6 +192,12 @@
>         }
>     }
>
> +    template<class Y, class M>
> +      shared_ptr(shared_ptr<Y> const & r, M* member_ptr,
> detail::memberpointer_tag) : px( member_ptr ), pn(r.pn)
> +      {
> +     +      }
> +
> #ifndef BOOST_NO_AUTO_PTR
>
>     template<class Y>
> @@ -410,6 +417,11 @@
>     return shared_static_cast<T>(r);
> }
>
> +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() );
> +} +
> // get_pointer() enables boost::mem_fn to recognize shared_ptr
>
> template<class T> inline T * get_pointer(shared_ptr<T> const & p)
>
> -- 
> Michael Anderson
> Chief Technology Officer
> -- 
> p. +61 8 8400 6496 [Adelaide, Australia]
> michael.anderson_at_[hidden]
> -- 
> Rising Sun Research
> p. +61 8 8400 6494 - f. +61 8 8400 6401
> www.risingsunresearch.com
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/ 
> listinfo.cgi/boost

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