WEBVTT

00:00.150 --> 00:00.690
Hello again!

00:01.020 --> 00:04.530
In this video, we are going to look at weak_ptrs and cycle prevention.

00:04.890 --> 00:09.870
This is the other main reason why weak_ptrs were added in C++11.

00:12.270 --> 00:19.170
With shared_ptrs, it is possible to create cyclic references. So we can have two shared pointers which

00:19.170 --> 00:22.890
refer to each other, and the reference count can never go down to zero.

00:23.460 --> 00:29.280
So that means that the shared memory is never released, and the destructors of the object are never called.

00:30.450 --> 00:36.660
As a very simple example, we have a Father class, which has a member which is a shared_ptr to its

00:36.660 --> 00:42.120
Son and the Son class, which has a member which is a shared_ptr to its Father.

00:43.230 --> 00:49.020
Then we create shared_ptrs to the Father and to the Son, and then we bind the shared_ptrs to

00:49.020 --> 00:49.410
each other.

00:50.370 --> 00:56.670
So this shared_ptr is pointing to a Father object, which has a shared_ptr to the Son, which

00:56.670 --> 00:58.170
has a shared_ptr back to the Father.

00:58.710 --> 01:01.530
So the reference counter for this Father object will be 2.

01:02.280 --> 01:08.880
And similarly, for the Son, the shared_ptr is a shared_ptr to a Father object, which has a shared_ptr

01:08.880 --> 01:09.930
back to the Son.

01:10.470 --> 01:13.590
So the reference counter for the Son's shared_ptr will be 2 as well.

01:16.720 --> 01:17.800
So let's look at this.

01:18.250 --> 01:25.090
I've added destructors for the Father and the Son, so we can see when they get called. The function

01:25.090 --> 01:26.950
which sets the Son's shared_ptr

01:26.950 --> 01:32.950
will take its arguments by const reference, so that will not affect the shared_ptr reference count.

01:33.670 --> 01:38.920
But when we do the assignment, that will increment the reference count for the Son's shared_ptr.

01:39.310 --> 01:42.490
So that will increase the reference count from 1 to 2.

01:43.450 --> 01:48.910
Similarly, with the Son constructor, that takes the argument by const reference, but then

01:48.910 --> 01:50.770
we copy the Father's shared_ptr.

01:51.280 --> 01:52.270
So that will increment

01:52.270 --> 01:55.720
the Father's reference count from 1 to 2.

01:57.900 --> 02:02.850
In the main() function, we create the objects and point them at each other, inside a scope.

02:03.540 --> 02:08.610
So when we get to the end of this scope, the destructor will be called for the two shared_ptrs.

02:09.450 --> 02:11.820
So the reference count is currently 2.

02:11.850 --> 02:13.230
That will decrement it down to 1.

02:13.740 --> 02:17.010
But the important point is, the reference count does not go down to zero.

02:17.640 --> 02:22.800
So the shared_ptr does not release its memory, and it does not calle the destructor of the Son and

02:22.800 --> 02:23.670
the Father objects.

02:26.690 --> 02:27.320
So there we are.

02:27.560 --> 02:29.030
The destructors do not get called.

02:30.660 --> 02:34.890
We can solve that by making the Son's shared_ptr a weak_ptr.

02:37.080 --> 02:42.930
So when we do this copy, we are then copying a shared_ptr into a weak_ptr, and that will not affect

02:42.930 --> 02:45.690
the reference count of the Father shared_ptr.

02:46.590 --> 02:52.230
So now the Father's reference count is 1. When the Father's shared_ptr is destroyed, the reference

02:52.230 --> 02:53.370
count will go down to zero.

02:53.730 --> 02:58.140
So that will release the Father's memory, and call the destructor for the Father.

02:58.530 --> 03:04.650
And then the destructor will be called again, for the Son's shared_ptrs that will decrements the reference

03:04.650 --> 03:10.830
count down to zero. That will call the destructor for the Son object and release the memory.

03:11.790 --> 03:12.780
So it all works out.

03:16.200 --> 03:16.800
And there we are.

03:17.370 --> 03:18.750
Okay, so that is it for this video.

03:19.290 --> 03:20.160
I will see you next time.

03:20.340 --> 03:22.200
Until then, keep coding!
