Hello,
We are really very happy
and impressed with boost’s smart_pointers, and we found the section
"Smart Pointer Programming Techniques" (http://www.boost.org/libs/smart_ptr/sp_techniques.html)
in boost smart_pointer documentation very useful, but we are having
this problem:
We have two classes X and
Y, and each object of class X holds an object of class Y, and we need
to implement a method in class X to get a shared_ptr<Y> so we can
access Y instance inside X, and we need that X objects (that are too
referenced by shared_ptr<X>) don’t be deleted until all
references to the Y object are destroyed. See the
problem in this code:
class Y {};
class X : public
enable_shared_from_this<X> {
Y y;
public:
shared_ptr<Y> ptr_y(); // Oops, how do we do here???
};
Our
first approach was “Using a shared_ptr to hold a pointer to a
statically allocated object” (http://www.boost.org/libs/smart_ptr/sp_techniques.html#static), but this doesn’t work
because X objects can be destroyed and we still have pointers to
contained Y object, so we try a custom deletor like this:
template <typename Z>
class delegator_deletor {
shared_ptr<Z> ptr; //
Internal pointer to father X, wich contains Y
public:
delegator_deletor(
shared_ptr<Z> const & ptrz ) : ptr( ptrz ) {}
template <typename T> void
operator()( T* ) { ptr.reset(); } // Null
deletor, only resets pointer to father X object
};
template <typename Z>
delegator_deletor<Z>
make_delegator_deletor( shared_ptr<Z> ptrz ) { return
delegator_deletor<Z>( ptrz ); }
class X : public
enable_shared_from_this<X> {
Y y;
public:
shared_ptr<Y>
ptr_y() { return shared_ptr<Y>( &y, make_delegator_deletor(
shared_from_this() ) ); }
};
And now the problem was
resolved but with one little drawback, we are not sharing the same
counter between shared_ptr<X> and shared_ptr<Y>, so start
looking boost’s code to shange it in a way that it satisfies our needs,
and we added this
constructor to shared_ptr class:
template<class Y,class
Z>
shared_ptr(Y* y,
shared_ptr<Z> const & z): px(z.px ? y : 0), pn( y ? z.pn :
detail::shared_count() ) // never throws
{
detail::sp_enable_shared_from_this(y,
y, pn);
}
then we change X::ptr_y()
this way:
shared_ptr<Y>
X::ptr_y() {
return
shared_ptr<Y>( &y, shared_from_this() );
}
This new constructor instructs
to create a shared_ptr<> that uses the same counter that the
second’s shared_ptr<> parameter, but point’s to the first raw
pointer paramenter.
With this change everithing worked fine.
Finally our question is:
Is there an easyer way to solve our problem?
If the answer is yes we
want to know it and
if the answer is no we want
to know if you can enhace shared_ptr to solve this kind of problem.
Thank you very much
Ricardo