|
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