WEBVTT

00:00.150 --> 00:04.470
Hello again! In this video, we are going to look at virtual functions in C++11.

00:05.550 --> 00:11.790
So we now know that we can get dynamic binding if we have a virtual member function in the base and

00:11.790 --> 00:16.290
we override that in the child, and we call this member function through a pointer to the base.

00:17.520 --> 00:22.510
For this to work, the function in the child has to have the same signature as the function in the

00:22.510 --> 00:22.980
parent.

00:23.820 --> 00:29.370
So we saw that with the Circle and the Triangle. They had the same signature as the parent's virtual

00:29.430 --> 00:30.600
draw() function.

00:32.280 --> 00:36.120
It's the same function has a different signature, then that is not an override.

00:36.450 --> 00:37.800
It is actually an overload.

00:38.250 --> 00:40.500
So it's actually regarded as a different function.

00:41.010 --> 00:43.680
So dynamic binding does not work in that case.

00:44.880 --> 00:50.250
And also, if we try to call the parent's version of the member function through the child, then we get a

00:50.250 --> 00:55.110
compile error, because the member function has been hidden and we need to put in a "using" directive

00:55.440 --> 01:02.610
to make the parent's member function available again. Unfortunately, it is quite easy to get an override wrong.

01:02.850 --> 01:07.980
If you are adding the member function to the child and you make a mistake when you are defining the function.

01:08.490 --> 01:14.970
Or perhaps someone changes the parent's signature and they forget to change the child. Most of the time

01:14.970 --> 01:19.200
you will not get a compiler error. If you try to call a hidden member function, then you will get compiler

01:19.200 --> 01:19.530
error.

01:19.830 --> 01:24.690
But apart from that, there is no indication. Until you run the program and it does not work properly,

01:25.080 --> 01:26.280
and you are not sure why.

01:28.410 --> 01:32.640
In C++11, we can now get the compiler to check this for us.

01:33.330 --> 01:38.640
We can say that a member function is meant to be an override, and the compiler will check whether

01:38.640 --> 01:40.380
this is actually an override

01:40.380 --> 01:45.390
of a virtual function in the parent's class. And if it is not, then we get a compiler error.

01:47.680 --> 01:49.060
So let's try this out.

01:49.450 --> 01:53.230
So we have our Sheep class again with the virtual draw() member function.

01:54.220 --> 01:59.950
Then we have the child with the override of the parent's draw() with no arguments, returning void.

02:00.340 --> 02:02.920
Although the return value is not part of the signature, of course.

02:03.760 --> 02:05.020
They are both declared const.

02:05.290 --> 02:12.100
So these both have the same signature. If we add another function, which is meant to be an override.

02:12.160 --> 02:16.060
Which takes an argument, because it is useful to have an argument.

02:18.360 --> 02:19.230
Let's see what happens.

02:21.310 --> 02:27.750
And we get a compiler error. Circle::draw() did not override any base class methods.

02:30.360 --> 02:31.680
So that is obviously this one.

02:32.100 --> 02:34.320
If we remove the override key word.

02:37.600 --> 02:38.380
Then it compiles.

02:42.070 --> 02:49.090
And if we comment out, then we get another error. So that is the hiding again.

02:50.590 --> 02:53.470
So, Circle::draw() function does not take zero arguments.

02:54.190 --> 02:57.040
And we could put in a using declaration to...

03:03.020 --> 03:03.680
...fix that.

03:05.530 --> 03:05.890
OK.

03:08.970 --> 03:11.340
So this is actually a very useful feature.

03:11.790 --> 03:18.270
I recommend using the override keyword, every time that you are overriding an inherited virtual

03:18.420 --> 03:19.170
member function.

03:21.770 --> 03:29.450
The other key word in C++11, which is related to virtual member functions, is the "final" key word. And you

03:29.450 --> 03:31.580
may have seen similar concepts in other languages.

03:32.360 --> 03:36.590
If we say that a class is final, that means we cannot inherit from this class.

03:36.590 --> 03:38.570
We cannot create any children of this class.

03:39.020 --> 03:42.680
So a final class represents the end of the class hierarchy.

03:44.000 --> 03:46.520
If we say that a member function is final,

03:46.820 --> 03:50.600
this means that children of the class are not allowed to override it.

03:52.250 --> 03:54.920
This is mostly useful to people who are writing libraries.

03:55.430 --> 04:01.520
If you have a library which provides an inheritance hierarchy to users of the library, or maybe you just want

04:01.640 --> 04:08.930
to use the hierarchy internally, you can use the final key word to prevents uses of your library from extending

04:08.930 --> 04:12.110
your class hierarchy, and that will help you keep things under control.

04:14.640 --> 04:17.460
So we're going to make our Circle class final.

04:18.630 --> 04:25.440
So this means if we try to divide a class from Circle, say, a DeluxeCircle, then that should not

04:25.440 --> 04:29.010
work, because final means you cannot create any children.

04:32.850 --> 04:36.820
And there we are. "Cannot inherit from Circle as it has been declared as final".

04:39.030 --> 04:44.580
If we remove that. OK, there is no main function, but the inheritance bit works.

04:47.490 --> 04:50.910
So let's change this so that the Circle class is not final anymore.

04:52.140 --> 04:54.690
If instead we make the draw() member function final.

04:55.200 --> 05:01.260
So we are allowed to inherit from Circle, but we are not allowed to override the draw() member function.

05:03.630 --> 05:08.230
And there we are. Function declared as final cannot be overridden by DeluxeCircle::draw.

05:09.850 --> 05:16.690
So the final member function in Circle means that children of Circle are not allowed to override the draw()

05:16.690 --> 05:17.350
member function.

05:18.220 --> 05:19.780
Okay, so that is it for this video.

05:20.230 --> 05:23.140
I will see you next time, but until then, keep coding!
