1 00:00:05,600 --> 00:00:09,600 In this video, we'll learn about constructor initialization lists, 2 00:00:09,600 --> 00:00:13,280 which are very useful for efficiently initializing our object's data members. 3 00:00:14,080 --> 00:00:18,180 So far we've written our codes so that we initialize our data member values 4 00:00:18,480 --> 00:00:22,080 in the constructor body by assigning values to them. 5 00:00:22,080 --> 00:00:25,680 While this works, it technically isn't initialization 6 00:00:25,680 --> 00:00:28,680 because by the time the constructor body is executed, 7 00:00:28,680 --> 00:00:31,340 these member attributes have already been created. 8 00:00:31,640 --> 00:00:35,300 So we're really just assigning values to already created attributes. 9 00:00:35,300 --> 00:00:39,400 I'll show you exactly what's happening when we head over to the IDE in just a bit. 10 00:00:40,000 --> 00:00:41,400 What we really want to do is 11 00:00:41,400 --> 00:00:46,390 have the member data values initialized to our values before the constructor body executes. 12 00:00:46,640 --> 00:00:50,040 This is much more efficient since it's true initialization. 13 00:00:50,840 --> 00:00:54,990 C++ allows us to do this using constructor initialization lists, 14 00:00:55,490 --> 00:00:59,750 which is basically just a list of initializers immediately following the constructor 15 00:00:59,750 --> 00:01:03,350 parameter list. It sounds complicated, but it's not, let me show you. 16 00:01:05,500 --> 00:01:09,380 Here we have the same player class that we've been using in previous examples. 17 00:01:09,380 --> 00:01:13,530 It has three overloaded constructors. And if you recall from the previous videos, 18 00:01:13,530 --> 00:01:17,530 we implemented them using assignment statements in the constructor body. 19 00:01:19,230 --> 00:01:21,480 You can see in the top section of this slide, 20 00:01:21,480 --> 00:01:24,580 how we previously implemented the no args constructor. 21 00:01:25,180 --> 00:01:28,180 In the body of the constructor, we use three assignment 22 00:01:28,180 --> 00:01:30,380 statements to set the attributes to the values we want. 23 00:01:31,370 --> 00:01:34,370 While this works, it can be inefficient in many cases. 24 00:01:34,370 --> 00:01:38,570 For example, by the time that we get to the statement name equals none, 25 00:01:38,870 --> 00:01:43,530 the name string object has already been constructed and initialized to an empty string. 26 00:01:43,830 --> 00:01:48,430 So we're really just assigning a new string to it, in this case, to an existing object. 27 00:01:48,430 --> 00:01:50,530 That's very different from initialization. 28 00:01:51,190 --> 00:01:54,990 What we really want is to initialize the data members to our data values 29 00:01:54,990 --> 00:01:56,190 as they're created. 30 00:01:57,380 --> 00:02:00,370 That's what constructor initialization lists allow us to do. 31 00:02:01,030 --> 00:02:02,630 The bottom section of the slide 32 00:02:02,630 --> 00:02:06,030 shows how we could implement the same constructor in a more efficient way. 33 00:02:06,430 --> 00:02:10,090 Notice that immediately after the parameter list, we provide a colon 34 00:02:10,090 --> 00:02:12,090 followed by a list of initializers. 35 00:02:12,990 --> 00:02:16,990 In this case, we're telling the c plus compiler to initialize name to none 36 00:02:17,240 --> 00:02:19,040 health and xp to 0. 37 00:02:19,700 --> 00:02:23,300 This happens before the body of the constructor is ever executed. 38 00:02:23,700 --> 00:02:27,580 One thing to keep in mind, the order in which the members are initialized 39 00:02:27,580 --> 00:02:31,240 is not necessarily the order we provide in the initialization list. 40 00:02:31,640 --> 00:02:36,000 The data members will be initialized in the order that they were declared in the class declaration. 41 00:02:36,990 --> 00:02:40,990 So let's implement the rest of the constructors using initialization lists. 42 00:02:42,180 --> 00:02:45,180 Here we're implementing the single string constructor. 43 00:02:45,180 --> 00:02:47,780 Notice the previous way on the top section of the slide 44 00:02:47,780 --> 00:02:50,680 and the better way using an initialization list below. 45 00:02:51,080 --> 00:02:53,440 In this case, we provide name value 46 00:02:53,440 --> 00:02:57,430 to initialize name and still use 0 for health and 0 for xp. 47 00:02:57,930 --> 00:03:00,930 You could probably guess how the three args constructor will look. 48 00:03:01,920 --> 00:03:05,720 Here's the three args constructor at the bottom using the initializer list. 49 00:03:05,720 --> 00:03:09,820 We're providing name val, health val and xp val to the initializers 50 00:03:10,420 --> 00:03:13,120 and the complete refactoring looks something like this. 51 00:03:14,320 --> 00:03:17,920 Notice how in the constructor, there's no code in the constructor body. 52 00:03:17,920 --> 00:03:20,920 We can still write any code we want in the constructor body. 53 00:03:20,920 --> 00:03:25,280 But now we can be sure that our data members have been initialized to our own values 54 00:03:25,280 --> 00:03:28,080 before any code in the constructor body is executed. 55 00:03:28,630 --> 00:03:32,230 Let's head over to the IDE, and we'll step through a few examples so you can see 56 00:03:32,230 --> 00:03:35,830 how much more efficient constructor initialization lists can be. 57 00:03:36,820 --> 00:03:38,820 Okay. So I'm in the ide, 58 00:03:38,820 --> 00:03:43,810 and I'm in the section 13 workspace in the ConstructorInitializationList project. 59 00:03:44,410 --> 00:03:48,210 And I've just got a simple main here that has our player class as 60 00:03:48,210 --> 00:03:52,210 I've discussed previously with three overloaded constructors: 61 00:03:52,210 --> 00:03:55,410 no args, a single string and the one that supplies 62 00:03:55,410 --> 00:03:56,910 the string and the two integers. 63 00:03:56,910 --> 00:04:00,470 Okay. And I've implemented the constructors that we've done 64 00:04:00,470 --> 00:04:04,770 previously using these assignment statements inside the body of the constructor. 65 00:04:04,770 --> 00:04:09,430 I've got some break points in here that we'll walk through so that we can see exactly what's going on, 66 00:04:09,430 --> 00:04:13,790 and then I'm creating three objects: I'm creating empty using no arguments, 67 00:04:13,790 --> 00:04:17,089 I'm creating frank which is a play -- they're all player objects. 68 00:04:17,089 --> 00:04:20,190 Frank with the single string, and then villain 69 00:04:20,190 --> 00:04:23,390 is going to use this constructor here with the three arguments. 70 00:04:23,390 --> 00:04:26,940 Okay. So let's walk through this, and we'll be real 71 00:04:26,940 --> 00:04:29,380 careful to look at that name 72 00:04:29,380 --> 00:04:32,680 attribute because that's really the important one because it's an object. 73 00:04:32,680 --> 00:04:34,180 So let's walk through this. 74 00:04:36,180 --> 00:04:40,180 And right now we are on line 41 right about here, 75 00:04:40,180 --> 00:04:42,080 and I'm going to step through this, 76 00:04:42,080 --> 00:04:45,680 and that will call the no args constructor, that's this one right up here 77 00:04:45,680 --> 00:04:49,880 on line 21 since we're providing no information for initialization. 78 00:04:49,880 --> 00:04:51,480 So I'm going to step through it. 79 00:04:51,480 --> 00:04:55,840 And you can see now the arrow here the little green arrow is on line 22, that's where I'm at. 80 00:04:56,740 --> 00:05:00,640 Now we can't really see empty here because empty is out of scope. 81 00:05:00,640 --> 00:05:04,240 We're now within the scope of this constructor right here. 82 00:05:04,240 --> 00:05:08,740 And I'll talk about a variable called this a little bit later in the course, 83 00:05:08,740 --> 00:05:10,740 probably a few videos from now. 84 00:05:10,740 --> 00:05:14,340 This represents the current object. Okay. 85 00:05:14,340 --> 00:05:15,940 So if I expand this, 86 00:05:15,940 --> 00:05:19,840 you can see that this is this current object that I'm building right here. 87 00:05:19,840 --> 00:05:24,340 And you'll notice something interesting, you'll notice that name is set to the empty string. 88 00:05:24,490 --> 00:05:28,850 What does that tell you? Well, that tells you that that was already initialized. In other words, 89 00:05:28,850 --> 00:05:33,650 that string object name its constructor was already called 90 00:05:33,650 --> 00:05:37,650 with no information, and we initialized it to an empty string. 91 00:05:37,650 --> 00:05:41,450 So this line right here that says name equals none, 92 00:05:41,450 --> 00:05:45,450 that's really not initializing anything. All it's doing is assigning 93 00:05:45,450 --> 00:05:49,450 none to an already created object name right here. 94 00:05:50,750 --> 00:05:52,750 That's really not what we'd like, 95 00:05:52,750 --> 00:05:55,950 we'd like to initialize that object name 96 00:05:55,950 --> 00:05:59,630 immediately without having to initialize and then assign to it. 97 00:05:59,630 --> 00:06:02,290 Okay. That can be very inefficient. 98 00:06:02,290 --> 00:06:06,690 In the case of a very complex class, you might have to create some sort of a 99 00:06:06,690 --> 00:06:11,460 default constructor for it and it's setting a lot of fields, it may be allocating things 100 00:06:11,460 --> 00:06:14,760 and then you're just going to deallocate all that stuff and assign to it again. 101 00:06:14,760 --> 00:06:17,640 It really doesn't make sense things become very inefficient. 102 00:06:17,640 --> 00:06:20,940 So you can see in this case, I'll keep walking through this. 103 00:06:20,940 --> 00:06:25,340 And now we're going to set name to none, health to 0. You can see I'm right here on line 24 104 00:06:25,740 --> 00:06:28,940 and xp to 0. Then I come back down to main. 105 00:06:28,940 --> 00:06:32,540 At this point, my player object -- I'll refresh over here, 106 00:06:32,900 --> 00:06:38,390 my empty player object is set to none 0 0, just like we expected but. 107 00:06:38,690 --> 00:06:41,690 Now let's create the frank objects. So what do we do? 108 00:06:41,690 --> 00:06:46,190 We're going to call the constructor that expects a single string, which is this one right here on line 27. 109 00:06:46,190 --> 00:06:50,190 And I'm going to go to that. Now I'm here online on line 28. 110 00:06:50,190 --> 00:06:53,990 Again notice, this represents the object that I'm creating right now 111 00:06:54,650 --> 00:06:58,250 and an empty string again. So I just created another object. 112 00:06:58,250 --> 00:07:00,610 In this case, I'll step through it really quickly 113 00:07:01,490 --> 00:07:05,850 and now I'm back here to player villain, which is going to call this constructor right here, 114 00:07:05,850 --> 00:07:07,350 the three args constructor. 115 00:07:07,710 --> 00:07:13,610 And I'll do that. And again, here's this another object that was created. 116 00:07:13,610 --> 00:07:17,210 So we've just created three string objects 117 00:07:17,210 --> 00:07:21,810 and then get rid of basically the string, the empty string they pointed to and replaced it with 118 00:07:21,810 --> 00:07:26,410 frank villan and none. So really really an inefficient thing to do. 119 00:07:26,410 --> 00:07:30,810 And what I'll do is I'll make one little change that hopefully will really 120 00:07:30,810 --> 00:07:34,010 help you understand this. Right now, we're just using that empty string. 121 00:07:34,010 --> 00:07:37,370 But suppose that I initialize this here to some 122 00:07:37,730 --> 00:07:40,730 string that's really obvious, like a bunch of x's. 123 00:07:42,930 --> 00:07:46,290 Okay. And let's let's run this again and we'll walk through it one more time. 124 00:07:46,690 --> 00:07:49,690 And hopefully, this time it'll really be obvious what's going on. 125 00:07:49,690 --> 00:07:51,890 Okay. So again, I'm here on line 41, 126 00:07:52,290 --> 00:07:57,190 and I'm creating an empty player object so it's going to call the no args constructor, this one here. 127 00:07:57,790 --> 00:08:01,790 So when I step through it, you can see I'm now in line 22. 128 00:08:01,790 --> 00:08:06,450 But if you look at the object, take a look at name right there, see all the x's, 129 00:08:07,250 --> 00:08:11,250 so that tells you that some constructor for that string class is already executed 130 00:08:11,250 --> 00:08:15,050 and initialized that string object. Again, that's not what we want to do. 131 00:08:16,040 --> 00:08:19,190 Okay. So hopefully, this this is really clear as to what's going on. 132 00:08:19,190 --> 00:08:23,190 What we want to do is, we want to use the initializer lists for the constructors. 133 00:08:23,190 --> 00:08:25,690 And it's really simple to do. 134 00:08:25,690 --> 00:08:28,690 What you do is immediately after the parameter list, 135 00:08:28,690 --> 00:08:30,990 right, there you just put a colon 136 00:08:30,990 --> 00:08:35,650 and you can follow it by the initializer list, just like we did in the slides. 137 00:08:35,650 --> 00:08:40,010 Okay. So in this case, I'll do it on the next slide just so it's a little clearer there. 138 00:08:40,010 --> 00:08:44,370 What we can do is we can tell it which attribute do we want to initialize. 139 00:08:44,370 --> 00:08:48,970 Well, in this case, I want to initialize name and we provide the initializer,which is the 140 00:08:49,570 --> 00:08:51,870 initialization value, I should say, which is none, 141 00:08:52,870 --> 00:08:54,070 health 142 00:08:56,370 --> 00:08:59,370 to 0. All of these would be comma separated, 143 00:08:59,370 --> 00:09:01,970 and xp also to 0. 144 00:09:03,670 --> 00:09:06,370 That's it, and then we don't need the body of the constructor 145 00:09:06,370 --> 00:09:08,670 anymore because we've already done the initialization. 146 00:09:08,670 --> 00:09:11,030 We could certainly write any code we need here, 147 00:09:11,030 --> 00:09:14,030 but we're sure that when we're in the body of the constructor, 148 00:09:14,030 --> 00:09:17,930 those three attributes have now been initialized, initialized correctly, 149 00:09:17,930 --> 00:09:20,530 not initialized and then assigned to, but initialized. 150 00:09:21,130 --> 00:09:23,530 Okay. So that takes care of that one. 151 00:09:23,930 --> 00:09:28,180 We can also do the same for these here, and I'll just do them really quickly. 152 00:09:28,780 --> 00:09:31,780 And let me just copy this bit here. 153 00:09:34,780 --> 00:09:39,380 And what we'll do here is we'll set name. In this case, we have the value to set it to, 154 00:09:39,380 --> 00:09:41,180 it's going to be named val, 155 00:09:42,060 --> 00:09:46,460 and we'll still keep health and xp at 0, and we'll get rid of the constructor body. 156 00:09:47,460 --> 00:09:50,560 We'll get rid of some of those break points as well and clean up the code. 157 00:09:50,560 --> 00:09:54,160 And you can see when you do it this way you end up with empty 158 00:09:54,160 --> 00:09:55,720 bodies for the constructors. 159 00:09:55,720 --> 00:10:00,380 And that's okay because obviously we want to put something else in there once our variables are created. 160 00:10:00,380 --> 00:10:05,180 And this last one, again, I'll copy this one just to save a little time here. 161 00:10:06,170 --> 00:10:07,970 We'll get rid of that, and 162 00:10:10,970 --> 00:10:15,630 I'll indent that in. There's my initializer name val. In this case, I've got health valve, 163 00:10:18,990 --> 00:10:20,490 and I've got xp val. 164 00:10:23,290 --> 00:10:25,650 And that's pretty much it. I'll get rid of this. 165 00:10:29,010 --> 00:10:31,900 And there you go. That's the final refactoring. 166 00:10:31,900 --> 00:10:34,700 You can see now we're using the initializer lists 167 00:10:34,700 --> 00:10:38,000 to initialize our objects, which is exactly what we want to do. 168 00:10:38,000 --> 00:10:40,300 Let me get rid of that extra colon right there. 169 00:10:41,200 --> 00:10:44,000 And that should do it. Other thing is 170 00:10:44,600 --> 00:10:47,960 i put the order in here as name, health and xp. 171 00:10:48,760 --> 00:10:52,860 That order doesn't really matter. It's going to be initialized in this order 172 00:10:53,160 --> 00:10:57,820 name health xp whatever order you declare these guys in right here 173 00:10:57,820 --> 00:11:01,820 in your class, that's the order that the initialization will take place. 174 00:11:01,820 --> 00:11:04,820 It just happens to be the same order that I've written here, 175 00:11:04,820 --> 00:11:08,320 and that's pretty much best practice is to keep the order the same. 176 00:11:08,320 --> 00:11:10,820 But don't rely on order here. 177 00:11:10,820 --> 00:11:13,820 The order is going to be the order that you declared these things in. 178 00:11:14,810 --> 00:11:19,170 Okay. So there you go. That's initialization list now you'll do you will notice a few things. 179 00:11:20,470 --> 00:11:24,670 We're going to talk about delegating constructors soon so we can get rid of some of this 180 00:11:24,670 --> 00:11:28,670 extra code because if you think about this, this is really the same as this it's the same as that 181 00:11:28,870 --> 00:11:30,170 and it's the same as that. 182 00:11:30,170 --> 00:11:33,470 So we'll have a little bit even more efficient way of doing this.