2

I am currently in a situation like:

struct A {  
  shared_ptr<B> b;  
};  
struct B {  
  shared_ptr<A> a;  
};

//...
shared_ptr<A> a(new A());
shared_ptr<B> b(new B());  
a->b(b);
b->a(a);

I know this won't work, because the references would continue to point to each other. I've also been told that weak_ptr solves this issue.

However, weak_ptr has no get or -> overload. I've heard mentions of 'use lock()', but can anyone give code examples of how to do this correctly?

bitmask
  • 32,434
  • 14
  • 99
  • 159
PrettyPrincessKitty FS
  • 6,117
  • 5
  • 36
  • 51

4 Answers4

6

I think the bigger issue here is one of ambiguous ownership. You'd be better off to decide whether A encapsulates B or the other way around. If that isn't possible then you're still better off introducing another class C that owns both A and B.

Assuming that A owns B, you can write:

classs B;

classs A
{
private:
    boost::scoped_ptr<B> b_;
public:
    A() : b_(new B()) {}
}

class B
{
private:
    A* a_;
public:
    B(A* a) : a_(a) {}
}

And so on. You can even get rid of scoped_ptr by making B a local variable or deleting it manually in the destructor.

The Google C++ Style Guide has more to say on this in the section titled "Smart Pointers."

HTH

Mhmmd
  • 1,483
  • 9
  • 15
  • +1, I nearly choked on seeing someone reference the Google C++ Style Guide... but for once I agree with them, clear ownership is preferable to sprinkling `shared_ptr` here and there. – Matthieu M. Aug 27 '10 at 06:27
  • Thank you for the +1! But I'm curious about your view of the Google C++ Style Guide. Is there any particular reason you find it a bit choke-worthy? – Mhmmd Aug 27 '10 at 07:22
  • +1 "_the bigger issue here is one of ambiguous ownership_" Yes; you need to consider ownership first, and **only when you understand the relations between your objects** you can choose to use a smart pointer. – curiousguy Jul 22 '12 at 02:56
2

Have you checked the boost reference on weak_ptr?

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(shared_ptr<int> r = q.lock())
{
    // use *r
}

The idea is that you lock the weak_ptr thereby obtaining a shared_ptr which does have the operators.

First check, whether the obtained pointer points to something. A weak_ptr does not determine the life-time of the resource, but it lets you check whether the resource has already been destroyed.

UncleBens
  • 40,819
  • 6
  • 57
  • 90
-1
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

struct B;

struct A
{
    boost::weak_ptr< B > b;
};

struct B
{
    boost::weak_ptr< A > a;
};

int
main()
{
    boost::shared_ptr<A> a(new A());
    boost::shared_ptr<B> b(new B());
    a->b = b;
    b->a = a; 
    boost::shared_ptr<A> another_a( b->a.lock() );
}

you can promote a weak_ptr to a shared_ptr using weak_ptr::lock.

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
-1

Come on now.

http://boost.org/doc/libs/1_42_0/libs/smart_ptr/weak_ptr.htm

^^^^^ EXAMPLE IS RIGHT THERE ^^^^^^

DAMN!

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • 7
    -1 While linking to the docs is helpful, SO answers should be useful to future visitors should the link become dead. This answer provides no information at all except a link. – cdhowie Jul 16 '12 at 22:36
  • Bad attitude towards OP – zpon Jan 04 '17 at 11:22