1

I think my question is similar to shared_ptr and weak_ptr differences, but I'm interested in seeing how they work together rather than a list of differences.

Wikipedia's page on shared_ptr and weak_ptr state a weak_pointer can be used to solve a circular dependency problem, and it gives an example:

std::shared_ptr<int> p1(new int(5));
std::weak_ptr<int> wp1 = p1; //p1 owns the memory.

{
  std::shared_ptr<int> p2 = wp1.lock(); //Now p1 and p2 own the memory.
  if(p2) //Always check to see if the memory still exists
  { 
    //Do something with p2
  }
} //p2 is destroyed. Memory is owned by p1.

p1.reset(); //Memory is deleted.

std::shared_ptr<int> p3 = wp1.lock(); //Memory is gone, so we get an empty shared_ptr.
if(p3)
{
  //Will not execute this.
}

But I don't see a circular dependency, so I don't understand how weak_pointer solves the problem.

I would have expected to see some object a pointing to an object b, and b somehow pointing back to a (with a weak_ptr shimmed in between one of the directed graph edges to break the chain).

Is the example good and my thinking bad? Or is there a better example of the problem and solution?

Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • "_state a weak_pointer can be used to solve a circular dependency problem_" and both are completely wrong; weak references have few uses, and circular dependency is not one – curiousguy Dec 28 '16 at 23:00

1 Answers1

1

In the current version of the wikipedia page, the example purports to demonstrate the use of std::weak_ptr in general, not eliminating strong circular references in particular. (The circular references are only mentioned after the example has been presented.)

What the example shows is that wp1, despite its lifetime, doesn't own the memory pointed to by p1, and that wp1 correctly detects the deletion of that memory once p1 is reset. In other words, wp1 neither interfered with the deletion of the dynamically allocated object, nor caused undefined behavior when the deleted object was (correctly) accessed through the weak pointer.

Because they don't interfere with deallocation, weak pointers are useful not only for avoid reference cycles, but for implementing associative arrays that store additional properties or cache calculated properties of existing objects. As such caches don't interfere with deallocation, they can rely on the primary objects getting deleted when no longer in use without the need for a cache-specific eviction policy.

user4815162342
  • 141,790
  • 18
  • 296
  • 355