Hello again!
In this video, we are going to look at weak_ptrs and cycle prevention.
This is the other main reason why weak_ptrs were added in C++11.
With shared_ptrs, it is possible to create cyclic references. So we can have two shared pointers which
refer to each other, and the reference count can never go down to zero.
So that means that the shared memory is never released, and the destructors of the object are never called.
As a very simple example, we have a Father class, which has a member which is a shared_ptr to its
Son and the Son class, which has a member which is a shared_ptr to its Father.
Then we create shared_ptrs to the Father and to the Son, and then we bind the shared_ptrs to
each other.
So this shared_ptr is pointing to a Father object, which has a shared_ptr to the Son, which
has a shared_ptr back to the Father.
So the reference counter for this Father object will be 2.
And similarly, for the Son, the shared_ptr is a shared_ptr to a Father object, which has a shared_ptr
back to the Son.
So the reference counter for the Son's shared_ptr will be 2 as well.
So let's look at this.
I've added destructors for the Father and the Son, so we can see when they get called. The function
which sets the Son's shared_ptr
will take its arguments by const reference, so that will not affect the shared_ptr reference count.
But when we do the assignment, that will increment the reference count for the Son's shared_ptr.
So that will increase the reference count from 1 to 2.
Similarly, with the Son constructor, that takes the argument by const reference, but then
we copy the Father's shared_ptr.
So that will increment
the Father's reference count from 1 to 2.
In the main() function, we create the objects and point them at each other, inside a scope.
So when we get to the end of this scope, the destructor will be called for the two shared_ptrs.
So the reference count is currently 2.
That will decrement it down to 1.
But the important point is, the reference count does not go down to zero.
So the shared_ptr does not release its memory, and it does not calle the destructor of the Son and
the Father objects.
So there we are.
The destructors do not get called.
We can solve that by making the Son's shared_ptr a weak_ptr.
So when we do this copy, we are then copying a shared_ptr into a weak_ptr, and that will not affect
the reference count of the Father shared_ptr.
So now the Father's reference count is 1. When the Father's shared_ptr is destroyed, the reference
count will go down to zero.
So that will release the Father's memory, and call the destructor for the Father.
And then the destructor will be called again, for the Son's shared_ptrs that will decrements the reference
count down to zero. That will call the destructor for the Son object and release the memory.
So it all works out.
And there we are.
Okay, so that is it for this video.
I will see you next time.
Until then, keep coding!