WEBVTT

00:01.630 --> 00:07.480
Hello again! In this video, we're going to look at special member functions. (Yes, it does say special member

00:07.480 --> 00:07.930
functions!)

00:13.900 --> 00:18.080
(Out of the way...) Some functions are special.

00:18.350 --> 00:21.890
These are concerned with the management of objects and their lifetime.

00:22.670 --> 00:25.550
The names are related to the name of the class.

00:27.060 --> 00:31.140
And we don't call these explicitly or we don't usually call them explicitly.

00:31.470 --> 00:37.080
Instead, the compiler will automatically add calls which call these member functions when they're needed.

00:38.370 --> 00:42.900
And we can also, sometimes, get the compiler to create these member functions for us.

00:45.030 --> 00:52.410
So in C++, traditionally, there were four special member functions: the constructor, the copy constructor,

00:52.410 --> 00:55.170
the assignment operator and the destructor.

00:57.610 --> 00:58.690
So let's look at those.

01:01.340 --> 01:07.400
The constructor has the same name as the class, and it'll initialize an object using the arguments.

01:07.400 --> 01:10.430
So the constructor gets called whenever we create a new object.

01:10.790 --> 01:15.320
And the arguments that we pass to the constructor are used to initialize the object.

01:16.280 --> 01:22.370
So for example, if we call the Test constructor, which takes these arguments, this will be called

01:22.370 --> 01:28.790
when the test object is created and it'll initialize the i member with the argument from the function

01:28.790 --> 01:32.240
call and the string member with the string argument.

01:35.220 --> 01:40.980
If we put i equals some argument inside here, then this will be called after the object has been created

01:40.980 --> 01:41.730
and initialized.

01:42.810 --> 01:47.910
So this will create an empty string and then if we assign it in here, that will assign it afterwards.

01:47.940 --> 01:49.230
So that's an extra operation.

01:49.650 --> 01:53.580
So normally you would put it up here instead, which would cause it to be initialized at the point

01:53.580 --> 01:54.750
when the object is created.

01:57.170 --> 02:02.810
In the body of the constructor, you would do things which need to be done after the object has been created.

02:03.290 --> 02:08.030
So if you need to allocate memory for storing some data, you can do that. If you need to connect to

02:08.030 --> 02:11.030
a database or read some information from a file and so on.

02:11.630 --> 02:17.360
The copy constructor is similar to the constructor, but instead of having different arguments, which

02:17.360 --> 02:24.590
represents members of the class, we provide an object of the same class and then the new object is

02:24.590 --> 02:27.950
going to be initialized using the object that we pass to it.

02:29.710 --> 02:35.200
So the copy constructor will always take exactly one argument; it will be passed by reference, and

02:35.200 --> 02:38.530
you might like to think about why that is by reference and not by value.

02:40.750 --> 02:42.040
And it's not to do with efficiency.

02:44.020 --> 02:49.990
The reason is that if you have a copy constructor, which takes its argument by value, that will need

02:49.990 --> 02:53.650
to make a copy of the object and to do that, it will call the copy constructor.

02:53.980 --> 02:58.480
And then that call to the copy constructor will itself need to make a copy and so on.

02:58.900 --> 03:01.570
And you get an infinite recursion of calls to the copy constructor.

03:02.140 --> 03:02.980
So that doesn't work.

03:03.370 --> 03:04.660
So you have to do it by reference.

03:06.400 --> 03:10.720
And normally you would do that by reference to const, because you really don't want to change something

03:10.720 --> 03:11.380
that you are copying.

03:11.590 --> 03:13.120
That's a very bad thing to do.

03:15.460 --> 03:20.490
So again, we can initialize the members in the initializer list.

03:21.070 --> 03:27.130
So this will set i, in the new object, to be equal to i in the object that we pass as argument.

03:27.820 --> 03:29.170
And the same goes for the string.

03:30.070 --> 03:35.200
And then inside the body, we can again perform configuration to set up the object that's just been

03:35.200 --> 03:35.680
created.

03:38.720 --> 03:45.590
The assignment [operator] also takes an existing object, but it is called on an object that already exists.

03:46.250 --> 03:52.790
And it'll assign the object so the values in the target object are the same as the values of the members

03:53.180 --> 03:54.500
in the source object.

03:56.500 --> 04:01.240
Again, it takes one argument, which is a reference to const, usually.

04:03.640 --> 04:10.570
As we said, the most efficient way to pass objects is by reference to const. And it returns a reference

04:10.570 --> 04:11.920
to the assigned object.

04:13.450 --> 04:18.370
And the reason why it does that is that you can chain together assignment statements in C and C++,

04:18.880 --> 04:26.770
So you can say a equals b equals c and that's legal. And returning the assigned-to object is required

04:26.770 --> 04:28.120
to enable that to work.

04:31.340 --> 04:36.980
Some people say that the assignment operator should return a const reference, but that's not actually the

04:36.980 --> 04:37.790
best thing to do.

04:38.300 --> 04:42.830
The built-in types always return a non-contact reference, and you should do this as well.

04:43.400 --> 04:48.350
Generally, whenever you write your own operators, they should work the same way as the ones for built-in

04:48.350 --> 04:48.740
types.

04:49.070 --> 04:50.450
Otherwise, it gets too confusing.

04:53.150 --> 04:59.330
And then when you write your assignment operator, you do whatever is needed to set the members

04:59.330 --> 05:05.220
of your object to have the correct values, so i is going to be the value of i from this source object.

05:05.610 --> 05:06.380
And string.

05:06.800 --> 05:09.080
And then we return this object by reference.

05:09.830 --> 05:14.810
So we have this, which is a pointer to the object that we are called on.

05:14.840 --> 05:15.750
"star this" will dereference it,

05:15.770 --> 05:17.750
so that will be the the actual object.

05:18.530 --> 05:21.890
And then the compiler will return a reference to that.

05:22.460 --> 05:26.060
So it all looks a bit peculiar if you haven't seen it before, but it does work and it is correct.

05:27.740 --> 05:34.280
And it is safe as well, because "this" will always be a valid object for as long as the object exists.

05:34.820 --> 05:38.370
And obviously, the object is not going to be destroyed or deleted.

05:38.420 --> 05:39.620
Well, in the middle of a call.

05:43.750 --> 05:45.390
And then finally, the destructor.

05:45.760 --> 05:51.550
So this is called just before the object is destroyed, before the members of the object are released

05:51.550 --> 05:52.060
in memory.

05:52.600 --> 05:57.130
And you can use this to perform any tidying up which you want to do before the object disappears.

05:58.450 --> 06:03.460
So, for example, if you allocated memory when you created the object, you can release it.

06:03.820 --> 06:06.460
If you have a database connection open, you can close it and so on.

06:06.760 --> 06:13.210
So it's just general tidying up. And it has the same name as the class with this squiggle or tilde

06:13.210 --> 06:15.340
is the technical name in front of it.

06:17.060 --> 06:17.400
OK.

06:17.570 --> 06:18.920
So that's it for this video.

06:19.370 --> 06:22.430
I'll see you next time, but meanwhile, keep coding!
