WEBVTT

00:00.180 --> 00:03.900
Hello again! In this video, we are going to look at the swap() function.

00:06.620 --> 00:10.400
The C++ Library provides a standard swap() function.

00:10.910 --> 00:12.710
This is a non-member function.

00:13.040 --> 00:20.150
It takes two arguments of the same type, and it exchanges their internal data. swap() is declared as

00:20.150 --> 00:24.410
noexcept, so it provides the "no throw" exception guarantee.

00:27.180 --> 00:30.780
swap() is a generic function, so it knows nothing about the arguments.

00:31.140 --> 00:32.550
It cannot do anything clever.

00:32.910 --> 00:33.810
It just copies them.

00:34.770 --> 00:40.680
However, there are overloads for library types and these do take advantage of the internal structure

00:40.680 --> 00:41.730
of the arguments.

00:42.540 --> 00:49.030
As an example, we looked at the string overload of swap(), earlier on in the course, and this just does

00:49.080 --> 00:54.060
some pointer manipulation. And that is much faster than allocating memory and copying data.

00:57.160 --> 01:01.390
There are some algorithms which exchange object data internally.

01:01.660 --> 01:05.530
The sort() algorithm is one of those. It does that, to put the elements in order.

01:06.430 --> 01:13.300
And there are some implementations which do that by calling the nonmember swap() function. And the function

01:13.300 --> 01:15.460
which gets called depends on the element's type.

01:16.150 --> 01:19.060
If there is an overload for the element, then that gets called.

01:19.510 --> 01:23.260
Otherwise, the generic version is used, and that will copy the elements.

01:24.010 --> 01:27.880
If you are writing your own class, and copying it takes a long time,

01:28.180 --> 01:29.740
then this could be rather inefficient.

01:30.820 --> 01:36.470
So if this is likely to happen, it could be worth implementing an overload of swap for your class.

01:37.330 --> 01:43.030
So that is if the class is expensive to copy and you expect to do a lot of swap operations on it.

01:43.540 --> 01:46.510
For example, if you have a container of these objects which get sorted.

01:48.680 --> 01:49.640
So how do we do that?

01:51.940 --> 01:57.220
The algorithm will assume that swap() is very fast, and does not throw any exceptions.

01:58.360 --> 02:02.470
It is going to be a non-member function which will need access to data members.

02:02.980 --> 02:08.320
So we need to make it a friend of the class, or perhaps delegate it to a public member function.

02:09.940 --> 02:14.410
We are going to write it as an inline function, so the compiler can optimize away the function call.

02:14.950 --> 02:20.830
I know that compiler writers say that their compilers are very clever and always do this, but in practice

02:20.830 --> 02:22.030
they sometimes need a hint.

02:23.650 --> 02:25.150
We are going to make it noexcept.

02:25.960 --> 02:29.020
And then we are just going to call swap() for each data member.

02:31.480 --> 02:36.050
We are going to use our String class again. Let's quickly remind ourselves what this does.

02:36.920 --> 02:38.750
So we have two members.

02:39.560 --> 02:41.450
We have a constructor which allocates memory.

02:42.200 --> 02:45.860
We have a copy constructor which allocates memory and copies the data.

02:47.390 --> 02:48.260
Then we have an assignment

02:48.260 --> 02:56.270
operator, destructor, and then we declare our overload of swap as a friend of this class.

02:57.730 --> 03:04.960
And here is our swap() definition is declared as in line and noexcept. We take the arguments by

03:04.960 --> 03:11.050
reference, not by const reference, because we are going to modify them, and then we just call swap() for each

03:11.050 --> 03:12.100
member of the class.

03:14.300 --> 03:18.950
We have a main function, which creates two objects.

03:19.490 --> 03:24.020
We print out their details, then we call swap(). And then we print out the details again.

03:25.070 --> 03:26.240
So let's see if this works.

03:29.250 --> 03:30.090
And there we are.

03:30.720 --> 03:34.230
So we can see that we have the details before and after.

03:34.800 --> 03:38.850
And we have just swapped around the size value and the pointers.

03:42.030 --> 03:45.510
Let's see what happens if we comment out this swap overload.

03:47.250 --> 03:51.900
So let's comment that out and then... this...

03:55.440 --> 03:57.090
So what do you think will happen now?

03:59.100 --> 04:02.130
We're going to call swap(), but there is no overload for this class.

04:02.520 --> 04:06.360
So this is going to call the generic version, and that is going to copy the data.

04:07.140 --> 04:08.520
So let's see what difference that makes.

04:12.130 --> 04:16.210
Right, well, it looks as though this has made quite a bit of difference, we have all these operations

04:16.210 --> 04:17.590
here, which are re-allocating memory.

04:19.090 --> 04:22.660
And also we have different addresses, because they have been reallocated.

04:23.080 --> 04:27.910
So you can see there is quite a lot more work involved in calling the generic version, which does copying.

04:28.420 --> 04:30.610
So the overloaded version is much faster.

04:32.110 --> 04:33.520
Okay, so that is it for this video.

04:33.970 --> 04:34.780
I will see you next time.

04:34.780 --> 04:36.750
But until then, keep coding!
