Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need a weak_ptr in C++11?

Tags:

c++

c++11

I was reading "The C++ Standard Library" book by Nicolai M. Josuttis for understanding weak pointers. The author has mentioned 2 reasons for the need to have a weak_ptr and I don't get the second reason. Can anyone provide a simple explanation along with example of the below reason (quoted from the book):

Another example occurs when you explicitly want to share but not own an object. Thus, you have the semantics that the lifetime of a reference to an object outlives the object it refers to. Here, shared_ptrs would never release the object, and ordinary pointers might not notice that the object they refer to is not valid anymore, which introduces the risk of accessing released data.

like image 740
Tushar Jadhav Avatar asked Apr 25 '16 23:04

Tushar Jadhav


2 Answers

The second half of that statement should be clear: if a pointer is not an owning pointer then the object it is pointing at might be deleted by whatever software is the owner - and then you'd have the standard dangling reference.

So this issue is: you've got objects owned by some piece of software which is letting other software have access to it - but the other software won't share the ownership. So the owner can delete it at any time and the other software needs to know its pointer is no longer valid.

Maybe an example would help:

You've got some piece of software watching a camera pointing out your window to a bird feeder and it is identifying birds at the feeder, which come and go. Each bird at the feeder has an object created by this software when it arrives at the feeder, and the object is deleted when the bird flies away.

Meanwhile, some other software it taking a census. Every 10 seconds it grabs from the feeder-watching software a collection of the birds at the feeder. Every 100 seconds it emits a report of which birds were at the feeder for the entire 100 seconds.

Because the data for a bird is big the census-taker doesn't copy the data. It merely gets, every 10 seconds, a collection of pointers from the feeder-watcher.

To make it necessary to use weak pointers, let's say the feeder-watcher only provides pointers to birds which have arrived in the last ten seconds, not the ones which have been there. That is, there is no notification that birds have disappeared.

By using weak pointers it can know, at report time, which of the birds are still there, and when they arrived (but not when they left).

(Maybe I'll think of a better example later.)

like image 67
davidbak Avatar answered Sep 28 '22 05:09

davidbak


e.g.:

struct node
{
   std::shared_ptr<node> left_child;
   std::shared_ptr<node> right_child;
   std::weak_ptr<node> parent;
   foo data;   
};

In this example, deleting the node will erase the left_child and right_child, but not the parent. If for some reason the node sticks around longer than the parent, and the parent is deleted, you have a way of knowing that the parent is no longer valid. (assuming you don't reference left_child or right_child with another shared_ptr)

like image 39
Exaeta Avatar answered Sep 28 '22 05:09

Exaeta