[Home]Tips - Smart Ptr Library

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

This page is for tips/helpful hints in using the Boost Smart_ptr Library

Back to smart ptr library pages


Circular references

Suppose I have a cyclic dependency between A and B, which are implemented with the pimpl idiom:

    #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
    }

OK, so we want to solve the problem that A and B keep eachother alive.

A weak_ptr can't be used, without breaking the whole way I'm using A and B -- see get_A() and get_B().

I came up with a way that did what I wanted, though, using intrusive_ptr<>. What I do is to have a "master" object (possibly A or B, or a 3rd object). I use intrusive_ptr_add_ref(A,B *) and intrusive_ptr_release(A,B *) to increment/decrment the master object's ref count.

In general, the abstraction is: you have a group of intra-referential objects. When any of the group is constructed, they are all constructed (so that the master count is temporarily > 1), and the master count is reset to 1. When the master count goes to 0, the group is destructed. Hence, the group only remains alive as long as there are any external references (and as long as the intra-group references remain static).

Could a standard smart pointer be designed to encapsulate this abstraction? Hmmm....

    - People/Chuck Messenger

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited August 31, 2004 8:23 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers