> -----Original Message-----
> From: Chuck Messenger [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, May 28, 2003 2:35 PM
> To: [EMAIL PROTECTED]
> Subject: [boost] Cyclic smart pointers (holy grail: the uber-pointer)
> 
> 
> Schoenborn, Oliver wrote:
> >>NoPtr lib -- noptrlib.sourceforge.net
> >>
> >>...I saw no mention of detecting dead cyclic object pools.
> >  
> > Can you give me a short example of how NoPtr would even need to detect
that
> > to work correctly? I suspect that if you end up with cyclic object pool
you
> > are using NoPtr incorrectly (just like passing a pointer to an auto
variable
> > to a shared_ptr is incorrect use), but maybe an example will show me to
be
> > wrong. 
> > 
> > Oliver
> 
> Here's my example (from an earlier thread):
> 
>      #include <boost/shared_ptr.hpp>
>      #include <iostream>
> 
>      using namespace boost;
>      using namespace std;
> 
> 
>      struct B_impl;
> 
>      struct B {
>          shared_ptr<B_impl> pimpl_;
>      };
> 
>      struct A_impl {
>          A_impl() { cout << "new A\n"; }
>          ~A_impl() { cout << "del A\n"; }
>          B b_;
>      };
> 
>      struct A {
>          shared_ptr<A_impl> pimpl_;
>          B get_B() const { return pimpl_->b_; }
>      };
> 
>      struct B_impl {
>          B_impl() { cout << "new B\n"; }
>          ~B_impl() { cout << "del B\n"; }
>          A a_;
>      };
> 
>      A get_A(const B& b) { return b.pimpl_->a_; }
>      B get_B(const A& a) { return a.pimpl_->b_; }
> 
>      A construct_A() {
>          A a;
>          a.pimpl_.reset(new A_impl);  // a refcount is 1
>          B& b = a.pimpl_->b_;
>          b.pimpl_.reset(new B_impl);  // b refcount is 1
>          b.pimpl_->a_ = a;            // a refcount is 2
> 
>          return a;
>      }
> 
>      int main() {
>          {
>              A a = construct_A();
>          }
>          // ex-a's refcount is still 1, so object doesn't die
>      }

The above code does not make sense from a strict ownership point of view.
This is a quality (good or bad depending on what you are looking for) of
strict ownership: it forces you to be clear about who owns and for how long.
In the above code, you would have to decide whether A and B own their pimpl.


     struct B_impl;
     struct B {
         DynObj<B_impl> pimpl_;
     };

     struct A_impl {
         B b_;
     };
     struct A {
         DynObj<A_impl> pimpl_;
     };

     struct B_impl {
         A a_;
     };

     A construct_A() {
         A a;
         a.pimpl_.acquire(new A_impl);  // a owns A_impl
         B& b = a.pimpl_().b_;
         b.pimpl_.acquire(new B_impl);  // b owns B_impl
         b.pimpl_().a_ = a; // compile error, logic wrong 
                            // for strict ownership
         return a;
     }

Indeed because A owns the pimpl_, the line before returning doesn't make
sense for strict ownership. Without knowing more about your problem, there
are two possibilities: 
- You always have A owns A_impl owns B owns B_impl refs A (what your
original code seems to say), in this case B_impl contains an RRef<A> instead
of a DynObj<A> and everything works
- Your program can also have B owns B_impl owns A owns A_impl refs B, i.e.
in some cases you have (indirectly) B owns A, other times A owns B. This one
requires more thought, and strict ownership may not be the solution since
this says that the ownership can have two forms. 

Oliver

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to