WEBVTT

00:00.120 --> 00:04.620
Hello again! In this video, we are going to look at how virtual member functions are implemented.

00:05.160 --> 00:08.580
You do not actually need to understand this to be a good C++ programmer.

00:08.970 --> 00:13.650
And you can probably get by without even knowing about it, but it is always useful to have some idea

00:13.650 --> 00:14.400
of what is going on.

00:16.320 --> 00:22.590
So first, let's remind ourselves how member functions are implemented. Member functions are not stored

00:22.590 --> 00:25.980
in the object, they are implemented as global functions.

00:26.610 --> 00:31.650
The only difference is that, when we call a member function, the compiler will add an extra argument

00:31.650 --> 00:36.750
with the "this" pointer, which is a pointer to the object that the member function was called on.

00:38.780 --> 00:45.260
So if we have a class which has some non-virtual member functions, it's really not that different from

00:45.260 --> 00:46.730
having a global function.

00:49.110 --> 00:52.090
There is quite a big difference, though, for virtual member functions.

00:52.920 --> 00:58.590
First of all, when the compiler sees that a class has a virtual member function, it will create and

00:58.590 --> 01:04.680
populate a data structure for the class, which is the virtual member function table, or vtable for

01:04.680 --> 01:05.050
short.

01:05.640 --> 01:11.160
And this has information about the class's virtual member functions. When the compiler sees that we are

01:11.160 --> 01:13.140
calling a virtual member function.

01:13.560 --> 01:17.520
It will generate some extra code, which is executed at run-time.

01:18.240 --> 01:24.900
This will check the dynamic type of the object, and then it will use the vtable for that dynamic type,

01:25.230 --> 01:27.420
to call the correct version of the function.

01:29.290 --> 01:35.020
So if we have a class which has virtual member functions, then the calls will go through this intermediate

01:35.350 --> 01:36.040
vtable.

01:38.580 --> 01:45.240
This vtable has the address of all the virtual member functions of the class. The vtable is actually

01:45.240 --> 01:51.180
an array of pointers to the class's virtual member functions, and each virtual member function of the

01:51.180 --> 01:55.200
class is identified by its index into this array.

01:58.140 --> 02:03.720
When a virtual member function is called, the compiler will replace the name of the function. Not

02:03.720 --> 02:06.600
with a pointer like it would for a normal member function,

02:06.840 --> 02:11.310
but with the index into the vtable. And then the run-time code,

02:11.310 --> 02:15.780
once it has found out which vtable to use, it will look up the element in the vtable,

02:15.780 --> 02:20.550
which has that index, and then it will call the member function through that function pointer.

02:24.600 --> 02:30.350
So this is all very clever, but there is a price to be paid. When we call a virtual member function,

02:30.360 --> 02:33.000
we have to go through this vtable, which adds indirection.

02:33.630 --> 02:40.290
So, typically, calling it takes about 25 or 50 percent longer than calling a non-virtual member function.

02:41.380 --> 02:48.040
There is also some memory usage, each class that has a virtual member function will need a vtable, so

02:48.040 --> 02:54.640
that is an array in memory at run-time, and each virtual member function in the class will require a

02:54.640 --> 02:55.930
pointer in this array.

02:56.680 --> 03:02.380
So if you have a very large hierarchy, with lots of classes with virtual member functions, or if you

03:02.380 --> 03:07.480
call virtual functions in a very tight loop, you may find that it affects the performance of your

03:07.480 --> 03:07.870
program.

03:08.560 --> 03:14.050
So the advice is, only use virtual member functions when you really need the extra flexibility.

03:15.130 --> 03:16.600
Okay, so that is it for this video.

03:17.110 --> 03:20.350
I will see you next time, but until then, keep coding!
