WEBVTT

00:00.300 --> 00:00.870
Hello again!

00:01.050 --> 00:04.410
And in this video, we are going to look at the default and delete keywords.

00:04.740 --> 00:07.630
And yes, we are still talking about special member functions.

00:07.950 --> 00:10.470
We have not suddenly started doing memory management.

00:12.290 --> 00:18.620
We have seen that the compiler will sometimes synthesize special member functions. In modern C++,

00:18.620 --> 00:23.060
the rules are more complicated, and it can be hard to work out what the compiler is doing.

00:23.450 --> 00:29.930
So now we have the ability to force the compiler to synthesize a special menu function. And the syntax

00:29.930 --> 00:33.680
for doing that is to put "= default" after the function's parameter list.

00:36.060 --> 00:41.190
For example, if we have the default constructor and then we put equals default, that will force

00:41.190 --> 00:46.590
the compiler to synthesize the default constructor, even if there are other constructors or a

00:46.590 --> 00:47.940
copy constructor for the class.

00:49.530 --> 00:55.410
If we put copy constructor equals default, that will force the compiler to synthesize a copy constructor,

00:55.410 --> 00:58.470
which copies all the members. In modern C++, the compiler

00:58.470 --> 01:01.590
may not always synthesize the copy constructor.

01:03.300 --> 01:05.190
And similarly, with the assignment operator.

01:05.550 --> 01:10.890
So we have a synthetic assignment operator which will assign all the members. And there are others. We

01:10.890 --> 01:14.250
could put the destructor in there, but that does nothing anyway.

01:14.260 --> 01:15.960
So it is a bit pointless.

01:19.170 --> 01:25.530
If you can remember the first example in the video on copy elision, we had to provide a default

01:25.530 --> 01:28.380
constructor because the compiler would not synthesize one.

01:28.830 --> 01:33.750
That was because we had a copy constructor. So we actually wrote it out, but we could equally well

01:33.750 --> 01:35.220
have put equals default.

01:37.970 --> 01:42.980
And then the compiler will synthesize a constructor which default initializes all the members.

01:43.640 --> 01:46.100
And that works exactly as it did before.

01:47.780 --> 01:49.280
Why is this useful?

01:49.610 --> 01:54.560
Well, you can look at the class definition and see immediately which special member functions the

01:54.560 --> 01:57.020
class has implemented, or defined for it.

01:58.040 --> 02:02.570
If you just let the compiler synthesize things, then you have to be able to work out what the compiler

02:02.570 --> 02:04.960
has done, and that can take some effort.

02:07.000 --> 02:12.130
It also documents that the programmer who wrote that class did actually want the default behaviour.

02:12.490 --> 02:14.770
And it is not just the case that they forgot to implement it.

02:16.840 --> 02:18.880
It avoids writing tedious code.

02:18.880 --> 02:23.350
If you do have to implement the copying instructor because the compiler will not synthesize one, then

02:23.350 --> 02:27.760
you have to write a member function, which copy initializes or assigns all the members.

02:28.450 --> 02:30.070
With this, the compiler will do it for you.

02:30.550 --> 02:36.550
And also, if the class definition changes, if we add or remove data members, then the compiler will

02:36.550 --> 02:39.820
make sure that the member functions are always up to date.

02:43.800 --> 02:48.660
Sometimes it is useful to have objects which cannot be copied. The traditional way to do this is to

02:48.660 --> 02:52.080
make the copy constructor and the assignment operator private.

02:52.680 --> 02:58.440
So for things like cout or cin, they cannot be copied because presumably the computer only

02:58.440 --> 03:00.750
has one output and one keyboard!

03:03.180 --> 03:12.330
So here is that code. If we do a copy operation, we expect to get a compile error. "Cannot access

03:12.330 --> 03:14.340
private members declared in class Test".

03:19.980 --> 03:22.020
And the same for the assignment operator.

03:22.410 --> 03:24.450
So this works, but it is a bit of a hack, really.

03:24.840 --> 03:28.260
And also, if you are looking through the code, you might miss that these are actually private.

03:29.970 --> 03:36.090
In Modern C++, we can say that the copy constructor and the assignment operator are "= delete", so

03:36.090 --> 03:36.780
they are deleted.

03:40.520 --> 03:42.440
So again, this will give us an error.

03:45.010 --> 03:51.080
But it is a different error this time. "Attempting to reference a deleted function. Function was explicitly

03:51.080 --> 03:56.990
deleted". So you can see from looking at this, that these functions are not meant to be called.

03:57.620 --> 04:04.670
And if we try to do an assignment, then we get the same result as well. Yes, "Attempting to reference

04:04.670 --> 04:05.690
a deleted function".

04:08.300 --> 04:13.160
So what does this actually mean? When we delete a function, it is still actually defined, but it

04:13.160 --> 04:13.940
cannot be called.

04:14.420 --> 04:17.270
And if you do try to call it, the compiler will give an error.

04:17.930 --> 04:24.050
And this is different from default, which only applies to special functions. For a special member function,

04:24.050 --> 04:28.520
it' i pretty easy for the compiler to guess what should be in there. If it is some other function than

04:28.520 --> 04:29.960
the compiler has no idea at all.

04:31.100 --> 04:36.500
With delete, any function can be deleted. So any member function or even non-member functions.

04:38.320 --> 04:43.240
This can be useful sometimes if you want to prevent conversions or overloads from being caught.

04:44.200 --> 04:47.230
But the main use is for copy constructors and assignment operators.

04:47.710 --> 04:53.080
If you delete the default constructor, then you cannot default construct any objects.

04:53.800 --> 04:55.480
And sometimes that can be useful as well.

04:55.660 --> 04:59.740
If you want to force users of your class to call a constructor which takes arguments.

05:02.380 --> 05:09.970
And then finally, one limitation on using the "=default". Sometimes the compiler cannot actually

05:09.970 --> 05:11.920
synthesize the special member function.

05:12.670 --> 05:16.660
The usual reason is that the class has a member which does not support that operation.

05:17.140 --> 05:19.390
So that would be a member, which is another class.

05:19.390 --> 05:21.670
And for example, it cannot be default constructed.

05:22.480 --> 05:28.600
So if the member cannot be default constructed, then the compiler cannot synthesize your own default

05:29.050 --> 05:32.240
constructor. Something that is a bit less obvious.

05:32.770 --> 05:38.590
If the class has a member with a destructor which is deleted or inaccessible. So the destructor for

05:38.590 --> 05:42.940
that class cannot be called, and that means you cannot destroy objects of that class.

05:44.050 --> 05:49.300
And even for C++, creating objects which cannot be destroyed is probably a bit too far!

05:49.450 --> 05:50.410
So that is not allowed.

05:51.970 --> 05:58.360
So the result of all this is, if the compiler cannot synthesize the operation, then it will be synthesized

05:58.360 --> 05:59.320
as "=delete".

06:00.040 --> 06:01.810
So it will still be there, but you cannot call it.

06:03.110 --> 06:05.020
Okay, so that is it for this video.

06:05.590 --> 06:08.710
I will see you next time, but until then, keep coding!
