1

I have two types: A & B. A 'smartly' points B and B 'smartly' points A. In the main scope I have a smart pointer to A.

class A;
class B;
typedef shared_ptr<A> pA;
typedef shared_ptr<B> pB;

class B {
public:
    B() {}
    pA a;
    virtual ~B() {cout << "delete b" << endl;}
};

class A {
public:
    A() : b(new B()) {}
    pB b;
    virtual ~A() {cout << "delete a" << endl;}
};

int main(int argc, char **argv)
{
    {
        pA pa(new A());
        pa->b->a = pa;
    }
    cout << "here" << endl;

}

I want the two objects to be deleted in the end of the scope. None of the objects is deleted, because A has two pointers to itself (one in b and one in the main scoop).enter image description here

This is a simple example. Actually I have more than two types and more pointers inside them. One can imagine a big structure of objects points to each other floating in the RAM, with only one pointer to this structure from the main scope. I want this structure to be deleted once this pointer is freed.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521

2 Answers2

7

For places where circular dependency is possible but architectural refactoring is not, the best is to use weak_ptr along with shared_ptr.

struct A {
    std::shared_ptr<B> b;
};

struct B {
    std::weak_ptr<A> a;

};
bobah
  • 18,364
  • 2
  • 37
  • 70
6

Use a weak pointer somewhere to break the loop - it's designed for exactly this situation.

In addition, std::weak_ptr is used to break circular references of std::shared_ptr

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Graham Griffiths
  • 2,196
  • 1
  • 12
  • 15