WEBVTT

00:00.450 --> 00:06.510
Hello again! In this video, we are going to look at constructors in modern C++. As you know, the

00:06.510 --> 00:12.240
constructor is a special member function. It gets called automatically when an object of the class is

00:12.240 --> 00:12.780
created.

00:13.590 --> 00:19.320
And we can use the constructor to initialize the data members of the class and to perform any set up

00:19.320 --> 00:22.950
that we require before we actually start using the object.

00:26.150 --> 00:30.860
If we do not do anything to initialize the data members of the class, they are default initialized.

00:31.460 --> 00:36.020
So if we have a member which is an object of a class, then the default constructor for that class is

00:36.020 --> 00:36.650
going to be called.

00:37.370 --> 00:41.960
If we have members which are of built-in type, then the initial value is undefined.

00:42.530 --> 00:45.710
The initial value will be whatever happens to be in

00:45.710 --> 00:50.510
that memory, interpreted as an int, or a bool, or whatever the type is.

00:53.360 --> 00:57.830
So who is that class. We have not provided a constructor to initialize the values.

00:58.850 --> 01:03.320
We have a print member, function, which is just going to display the values of the members.

01:03.980 --> 01:10.040
We're using the boolalpha manipulator, so we get "true" or "false" instead of 0 or 1

01:10.040 --> 01:16.850
when we print out the bool members. We create an object of the class and then we call the print

01:16.850 --> 01:18.050
member function of the object.

01:19.010 --> 01:20.540
So what do you think we will get?

01:24.150 --> 01:26.790
Well, that is probably not what you were expecting.

01:27.480 --> 01:33.630
So this memory that is being used by the temperature field obviously had some strange data in it.

01:33.630 --> 01:37.290
Maybe a string or some binary data or something.

01:39.160 --> 01:42.010
And door_open, power_on, that is just 50/50.

01:45.590 --> 01:46.910
So what can you do?

01:47.270 --> 01:51.830
The obvious answer is to write a constructor which will initialize these with sensible values.

01:53.390 --> 01:59.240
We could assume that the caller will provide them, or we could have constructors which take default arguments.

01:59.960 --> 02:07.820
Or we could have default arguments in the constructor. C++ 11 has a much nicer solution. In C++ 11,

02:07.880 --> 02:11.450
You can actually initialize data members in the class definition.

02:11.930 --> 02:18.290
So here we're saying that temperature has a default initial value of 2; door_open is false and power_on

02:18.290 --> 02:18.770
is true.

02:19.190 --> 02:27.020
So you just put the initial value in curly brackets, after the name of the member. And then the rest of

02:27.020 --> 02:28.340
the code is the same.

02:29.210 --> 02:30.500
So let's see if this works.

02:32.680 --> 02:33.200
And there we are.

02:33.220 --> 02:37.390
The temperature is true, the door is not open and the power is on.

02:38.410 --> 02:42.910
And if you have some situation where these are not the values you want, you could always write a

02:42.910 --> 02:46.750
constructor, which will initialize them with the desired values.

02:47.800 --> 02:52.750
But if you do know that you want a particular initial value, or there is some sensible default, then

02:52.750 --> 02:57.760
you should always do this. Because having undefined built-in types is always a big problem.

02:58.510 --> 03:02.930
Some compilers will set them to 0, and as we saw with Visual C++, some do not.

03:03.670 --> 03:11.230
So you can get unpredictable results. When you have a more complicated class, you can have different

03:11.230 --> 03:15.970
constructors and you want to do different things with these constructors. So you may want to set some

03:15.970 --> 03:17.440
of the members and not others.

03:18.160 --> 03:20.710
And then there's also something that you need to do for them.

03:21.370 --> 03:22.980
So, as an example of this,

03:22.990 --> 03:25.150
we have updated our refrigerator.

03:25.510 --> 03:27.130
It is now the 21st century.

03:27.250 --> 03:29.500
The refrigerator can connect to the Internet.

03:30.340 --> 03:34.480
Obviously, this is just an example of constructors, so we are not actually going to connect to the

03:34.480 --> 03:34.900
Internet.

03:35.470 --> 03:36.910
We are just going to pretend to.

03:37.870 --> 03:41.860
So we have a mock Internet class, which is a member of our refrigerator.

03:42.700 --> 03:47.110
We want to arrange things so that the refrigerator always connects to the Internet when it starts up.

03:47.740 --> 03:52.210
So from the constructor, we are going to call the connect() and the login() member functions of the

03:52.430 --> 03:53.800
Internet object.

03:56.190 --> 04:00.540
We have a default username and password, and yes, those really are my username password!

04:02.560 --> 04:10.270
(Not!) So for the default constructor, we just use the default values for these members, like we did before.

04:10.870 --> 04:15.100
And we connect to the Internet using these default credentials.

04:19.370 --> 04:23.930
We may also want to be able to set the temperature of the refrigerator when it comes on.

04:24.440 --> 04:27.260
But still the connect using the default credentials.

04:27.830 --> 04:32.330
So in that case, we have a constructor which sets the temperature and then it connects with the default

04:32.330 --> 04:32.960
credentials.

04:34.610 --> 04:39.530
On the other hand, you may be happy with the default temperature, but you want to choose a particular

04:39.770 --> 04:40.970
username and password.

04:41.420 --> 04:47.070
So in that case, you would have a constructon which will use the defaults again, but it will take the user

04:47.090 --> 04:48.650
name and password and use those.

04:50.490 --> 04:56.160
And then finally, you may want to be able to control everything so you can set the temperature, and

04:56.160 --> 04:57.390
the username, and the password.

04:58.080 --> 05:02.370
So we have four different constructors, which more or less do the same thing.

05:02.970 --> 05:07.500
So that's duplicated code, which is always a sign that you might need to think about your design.

05:09.030 --> 05:16.350
One of the famous axioms of programming is DRY, d-r-y, which stands for "Don't Repeat Yourself!". Do

05:16.350 --> 05:17.220
not repeat yourself.

05:17.640 --> 05:22.650
So if you keep writing repeated codes, then you probably need to think about factoring it.

05:25.820 --> 05:29.870
So in this case, we are connecting to the Internet and logging on in all four cases.

05:30.740 --> 05:32.570
So let's check first that this does work.

05:32.570 --> 05:34.430
The rest of the code is the same.

05:36.890 --> 05:43.250
OK, so we have four constructors where we are connecting to the Internet in the body and logging on,

05:43.700 --> 05:46.160
and we should really refactor that into a single function.

05:46.490 --> 05:47.740
So here is that function.

05:47.750 --> 05:51.200
Perhaps it should be private as it is actually part of the implementation of the class.

05:52.460 --> 05:58.970
So this will just connect to the Internet and log in with a given ID and password. And then, in the default

05:58.970 --> 05:59.480
constructor,

05:59.480 --> 06:05.000
we can call this with the default credentials. In the constructor where we set the temperature and log

06:05.000 --> 06:08.270
on with the defaults, and then we call init() with the defaults.

06:08.810 --> 06:13.520
If we use the default temperature and set the username and password, then we call it with the username

06:13.520 --> 06:14.120
and password.

06:14.990 --> 06:20.390
And finally, if you want to set everything, we set the temperature and call it with the username and

06:20.390 --> 06:22.250
password. And there we are.

06:22.280 --> 06:26.780
So that works exactly the same, but we have factored out all the duplicate code.

06:29.430 --> 06:31.410
But we have added another member function.

06:33.930 --> 06:40.590
So the advantage of this is that, if the details of initializing this Internet object change, or perhaps

06:40.590 --> 06:45.460
you have to call some different function or add another argument, then we only need to change it in this function.

06:45.480 --> 06:47.220
We do not need to change all the constructors.

06:48.510 --> 06:53.460
I have always thought it would be nice if C++ gave you some way for a constructor to call another constructor.

06:53.940 --> 06:55.800
And now you can actually do that in C++11.

06:56.550 --> 06:58.740
It is known as a delegating constructor.

06:59.370 --> 07:00.330
So let's look at that.

07:02.010 --> 07:04.190
So the first part of the code is the same.

07:04.230 --> 07:11.040
We have our Internet class and the refrigerator with a member, which is an Internet object.

07:13.600 --> 07:19.900
And then we have the same constructor which sets everything. So this will set the temperature and the

07:20.590 --> 07:22.840
ID and password for logging onto the internet.

07:23.650 --> 07:26.470
And then in the other constructors, we just delegate to this.

07:27.040 --> 07:33.640
So for example, if we use the default constructor, then we call the constructor with no defaults.

07:34.180 --> 07:39.070
We passed the default temperature, 2, as the argument, and then the ID and the password that we want.

07:39.250 --> 07:44.080
Similarly, if we are using the default login and setting the temperature, then we pass the temperature

07:44.080 --> 07:50.380
and the defaults for the credentials. And for the default constructor, we pass all the defaults.

07:54.710 --> 07:59.570
And the rest of the code is the same, and the result is the same.

08:04.320 --> 08:09.300
So the advantage of this is, if you have lots of combinations of constructors with default and non-default

08:09.300 --> 08:11.580
arguments, this makes it a lot easier.

08:12.210 --> 08:16.170
Instead of writing lots of different constructors, you can just delegate to one constructor that

08:16.170 --> 08:16.860
sets everything.

08:19.050 --> 08:20.790
OK, so that is it for this video.

08:21.300 --> 08:24.510
I'll see you next time, but until then, keep coding!
