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