1 00:00:05,200 --> 00:00:09,800 In this video, we'll learn about static class members and how to use them in c++. 2 00:00:10,680 --> 00:00:13,880 In a c++ class, we can have both static data 3 00:00:13,880 --> 00:00:15,180 and function members. 4 00:00:15,680 --> 00:00:18,280 When we declare class data members as static, 5 00:00:18,280 --> 00:00:21,280 we're telling the c++ compiler that these data members 6 00:00:21,280 --> 00:00:24,480 belong to the class, not to any specific object. 7 00:00:24,780 --> 00:00:28,030 So they're extremely useful to create class-wide information. 8 00:00:28,630 --> 00:00:31,730 For example, suppose we wanted to know how many player objects 9 00:00:31,730 --> 00:00:34,730 we have active in our application at any point in time. 10 00:00:35,390 --> 00:00:39,390 We could create a global variable and then increment it and decrement it in the code 11 00:00:39,390 --> 00:00:41,690 whenever we create an object or delete an object. 12 00:00:42,190 --> 00:00:44,850 This is really hard to do though since we really can't be sure when 13 00:00:44,850 --> 00:00:47,550 constructors are called and when the structures are being called. 14 00:00:47,550 --> 00:00:52,450 So a better solution is to create a static variable that's part of the player class, 15 00:00:52,450 --> 00:00:56,450 and then we can manipulate that variable directly within the player class. 16 00:00:56,450 --> 00:00:59,350 And then whenever we need to know how many player objects there are, 17 00:00:59,350 --> 00:01:01,150 we can simply ask the player class. 18 00:01:01,950 --> 00:01:05,830 We don't even need any objects. In fact, if the player count is 0, 19 00:01:05,830 --> 00:01:08,330 this means that there are no active player objects at all. 20 00:01:09,690 --> 00:01:12,690 So how could we modify our player class to support this. 21 00:01:13,190 --> 00:01:14,990 Let's start with the player class. 22 00:01:14,990 --> 00:01:18,190 We'll create a player.h file with the class specification. 23 00:01:18,550 --> 00:01:21,550 In a player cpp file with the class definition. 24 00:01:21,800 --> 00:01:24,500 Now we need to add a static data member to the class. 25 00:01:24,500 --> 00:01:29,300 We can do this very easily by adding a private static int named num players. 26 00:01:30,000 --> 00:01:34,150 We'll initialize this to 0 a little bit later since we can't initialize it right here. 27 00:01:35,400 --> 00:01:39,400 We also would need to declare a static class function that returns an integer. 28 00:01:39,900 --> 00:01:42,780 It will return the static integer we just declared. 29 00:01:42,780 --> 00:01:45,280 And you can see that at the bottom, it's called get num players. 30 00:01:47,880 --> 00:01:50,240 Now let's head over to player.cpp. 31 00:01:50,240 --> 00:01:54,240 This is where we want to initialize the static integer num players to 0. 32 00:01:54,840 --> 00:01:57,340 Notice that the syntax might look a little strange. 33 00:01:57,890 --> 00:02:01,490 This is where you define that variable and assign it to 0 in this case. 34 00:02:01,490 --> 00:02:04,480 This must happen exactly once and it typically happens 35 00:02:04,480 --> 00:02:06,780 in the .cpp file for the class. 36 00:02:08,479 --> 00:02:11,680 Finally, we implement the static function get num players. 37 00:02:11,680 --> 00:02:16,280 Since this function is static, it only has access to static data members. 38 00:02:16,430 --> 00:02:19,730 It does not have access to non-static class data members. 39 00:02:19,980 --> 00:02:22,480 So in this function, we simply return num players. 40 00:02:22,840 --> 00:02:23,600 Pretty easy. 41 00:02:24,200 --> 00:02:26,000 There's only one part left to do. 42 00:02:26,000 --> 00:02:30,990 We need to increment and decrement the number of players whenever we create and destroy objects. 43 00:02:31,870 --> 00:02:35,230 The best place to increment the player count is in the constructor. 44 00:02:35,590 --> 00:02:38,590 In this case, we simply increment num players by 1. 45 00:02:39,090 --> 00:02:42,090 Be careful though if you have many overloaded constructors 46 00:02:42,090 --> 00:02:45,090 since you might have to increment num players in more than one place. 47 00:02:45,450 --> 00:02:47,750 Basically, anywhere you create an object. 48 00:02:47,750 --> 00:02:51,110 We only have one constructor in the player class and we're delegating to it 49 00:02:51,110 --> 00:02:52,610 from our copy constructor, 50 00:02:52,610 --> 00:02:56,110 so this is the only place we want to increment num players in this example. 51 00:02:57,670 --> 00:03:00,170 Our original player class didn't have a destructor. 52 00:03:00,530 --> 00:03:04,430 It used the compiler provided default destructor since it was all we needed. 53 00:03:04,680 --> 00:03:08,980 However, now we need to define our own destructor and decrement the number of players count 54 00:03:08,980 --> 00:03:10,480 when the object is destroyed. 55 00:03:11,780 --> 00:03:13,280 That's it. We're all set. 56 00:03:13,280 --> 00:03:16,980 Now we can use our player class and simply call player get num players, 57 00:03:16,980 --> 00:03:19,240 and it will return the number of active player objects. 58 00:03:20,140 --> 00:03:23,440 I created a simple helper function named display active players. 59 00:03:23,440 --> 00:03:26,800 And anytime, I need to display the number of active players I simply call it. 60 00:03:27,680 --> 00:03:32,180 Now look at the main. The first statement is display active players, and it will display 0. 61 00:03:32,580 --> 00:03:36,080 As we add and remove player objects, we'll call display active players. 62 00:03:36,080 --> 00:03:39,080 And it will display the current number of active player objects. 63 00:03:39,480 --> 00:03:43,780 Let's head over to the ide, and we'll take the existing player class through the process 64 00:03:43,780 --> 00:03:45,280 of providing this behavior. 65 00:03:46,780 --> 00:03:51,080 Okay. So I'm in the ide, and I'm in the section 13 workspace in the Static 66 00:03:51,080 --> 00:03:52,680 ClassMembers project. 67 00:03:53,580 --> 00:03:57,080 And what I've done is I've created a basic player class, 68 00:03:57,080 --> 00:03:58,980 and you can see here I've got three files: 69 00:03:58,980 --> 00:04:02,340 player.h, player.cpp and main.cpp. 70 00:04:02,340 --> 00:04:04,330 And right now we're looking at player.h. 71 00:04:04,330 --> 00:04:06,930 You can see we've got our our include guard here. 72 00:04:06,930 --> 00:04:10,730 We're included string because we're using strings inside the player class. 73 00:04:10,980 --> 00:04:14,780 And it's a basic player class that we've been using all along. It's got the string 74 00:04:14,780 --> 00:04:17,779 name, the integer health and integer xp. 75 00:04:17,779 --> 00:04:20,380 And we've got a getter here and some 76 00:04:20,740 --> 00:04:23,340 constructor that uses default parameters, 77 00:04:23,340 --> 00:04:27,240 a copy constructor and a d structure that does nothing right now 78 00:04:27,240 --> 00:04:29,440 and the cpp file 79 00:04:29,800 --> 00:04:33,790 implements the constructor, the copy constructor and it's got a 80 00:04:33,790 --> 00:04:35,590 an empty destructor right now. 81 00:04:36,140 --> 00:04:38,940 So what we want to do is we want to go to the player.h file, 82 00:04:38,940 --> 00:04:42,240 and what we want to do as I said in the previous slides is to 83 00:04:42,600 --> 00:04:47,400 know how many players are active at any time. So we need a counter type variable. 84 00:04:47,760 --> 00:04:51,420 We can't add that to objects because then each object would have their own copy. 85 00:04:52,020 --> 00:04:56,620 So we want to use static variable at the class level so that we now have 86 00:04:56,620 --> 00:04:59,180 a variable that applies to the entire class. 87 00:04:59,180 --> 00:05:04,170 So we'll define that right here. We'll make it private, and we'll just say static int, 88 00:05:04,470 --> 00:05:06,470 and we'll call it num players. 89 00:05:07,370 --> 00:05:08,360 Simple as that. 90 00:05:08,360 --> 00:05:12,360 Now you'd you'd think that you could initialize it right here. 91 00:05:12,360 --> 00:05:15,960 But if you try that and try to compile, you'll get a compiler error that says 92 00:05:15,960 --> 00:05:20,560 that c++ forbids in class initialization of non-constant members. 93 00:05:20,560 --> 00:05:21,760 And you can't do that. 94 00:05:21,760 --> 00:05:26,420 So we'll get rid of that, and we'll initialize it in a second in the cpp file. 95 00:05:26,420 --> 00:05:27,720 So that's my 96 00:05:28,220 --> 00:05:30,820 static variable that -- remember, 97 00:05:30,820 --> 00:05:34,120 now this does not belong to any object, this belongs to the class. 98 00:05:34,780 --> 00:05:36,780 And then we need to implement a static 99 00:05:37,280 --> 00:05:40,080 class function. And we'll do that down here. 100 00:05:40,080 --> 00:05:43,680 And we'll just say I call it static. It's going to return an int, 101 00:05:43,880 --> 00:05:46,180 and it's going to be called get num players, 102 00:05:48,680 --> 00:05:49,580 simple as that. 103 00:05:49,580 --> 00:05:54,000 Now one thing to remember, because this function is static, 104 00:05:54,000 --> 00:05:56,800 it only has access to static variables. 105 00:05:57,160 --> 00:05:58,150 That makes sense. 106 00:05:58,550 --> 00:06:02,910 It doesn't have access to any object variables, any of these guys name, health, xp. 107 00:06:03,160 --> 00:06:05,410 Those belong to specific objects. 108 00:06:05,410 --> 00:06:08,910 Static only belongs to the class. So this is a class function, 109 00:06:08,910 --> 00:06:12,570 and it only has access to that static num players in this example. 110 00:06:12,570 --> 00:06:17,070 Okay. We could have a lot of other static functions if we like but we only need the one in this example. 111 00:06:17,070 --> 00:06:20,270 So that takes care of the header file. I'll save that 112 00:06:20,270 --> 00:06:23,270 and now we'll go over to the .cpp file. 113 00:06:23,820 --> 00:06:28,220 Now first thing we want to do is we want to initialize that static variable here. 114 00:06:28,220 --> 00:06:30,820 And the syntax looks something like this int, 115 00:06:31,180 --> 00:06:32,480 the class name 116 00:06:32,980 --> 00:06:37,280 and the name of the variable, num players. And here we can initialize it to 0. 117 00:06:39,080 --> 00:06:42,580 And now you can see that if I compile and run now I get a clean run from that. 118 00:06:43,080 --> 00:06:45,180 So that's initialized. It only happens once. 119 00:06:45,180 --> 00:06:49,780 And the best place to do that is in the cpp file for the class that you're defining. 120 00:06:50,100 --> 00:06:54,700 Okay. And then the last thing we'll do is -- well, not the last thing but do the next thing we'll do is 121 00:06:54,700 --> 00:06:58,700 we'll implement the int player 122 00:06:58,700 --> 00:07:00,700 get num players function. 123 00:07:02,500 --> 00:07:05,500 And it's, let me do that, again get num players, 124 00:07:07,300 --> 00:07:08,900 it's that function right here. 125 00:07:09,150 --> 00:07:12,650 And we're going to implement that function so that it returns 126 00:07:13,450 --> 00:07:14,950 the number of players. 127 00:07:14,950 --> 00:07:17,310 It has access to that. It's a static variable. 128 00:07:17,810 --> 00:07:19,410 And that's really all we care about. 129 00:07:19,770 --> 00:07:24,130 Now remember,we already defined that as a static method right here in player h, 130 00:07:24,130 --> 00:07:28,030 you can see it's right here. So we don't have to say static again down here. 131 00:07:29,430 --> 00:07:30,230 That's it. 132 00:07:30,230 --> 00:07:32,230 Now what do we need to do?Well, 133 00:07:32,230 --> 00:07:35,350 we need to increment and decrement the number of players 134 00:07:35,350 --> 00:07:38,350 depending on when we construct or destruct things. 135 00:07:38,350 --> 00:07:41,010 So this is the only constructor I have. 136 00:07:41,010 --> 00:07:44,110 Even when we've got a copy constructor that we create a copy of an object, 137 00:07:44,110 --> 00:07:45,910 we're still delegating to player. 138 00:07:45,910 --> 00:07:47,790 So right here, 139 00:07:47,790 --> 00:07:50,390 I want to increment the number of players. 140 00:07:53,590 --> 00:07:57,590 And in the destructor, I want to decrement the number of players. 141 00:07:58,990 --> 00:08:01,980 So that will take care of the semantics that I want. 142 00:08:02,530 --> 00:08:05,890 So at that point, this cpp class is done. 143 00:08:05,890 --> 00:08:09,890 And we can now head over to the main class and test some of this. 144 00:08:09,890 --> 00:08:13,790 So the first thing we'll do in the main class is we'll write a real simple function. 145 00:08:13,790 --> 00:08:17,590 And we'll just keep calling that function whenever we want to display active 146 00:08:17,590 --> 00:08:19,390 players. It'll just save us a lot of typing. 147 00:08:19,390 --> 00:08:22,390 So we'll call it void display 148 00:08:24,590 --> 00:08:26,090 active players. 149 00:08:28,690 --> 00:08:30,590 It doesn't expect anything 150 00:08:30,590 --> 00:08:34,090 and all we're going to do in here is we're just going to do an output statement 151 00:08:34,090 --> 00:08:37,390 and we'll say something like active players 152 00:08:38,190 --> 00:08:38,990 colon. 153 00:08:38,990 --> 00:08:42,980 And so now how do I know how many active players there are? 154 00:08:42,980 --> 00:08:45,860 I don't have any objects to call. That's the whole point. 155 00:08:45,860 --> 00:08:47,360 I can simply say player, 156 00:08:48,020 --> 00:08:52,020 and we need a scope resolution operator. And now we can call the static method 157 00:08:52,020 --> 00:08:53,520 get, num players right here. 158 00:08:54,120 --> 00:08:56,520 That's going to return the integer that represents 159 00:08:56,520 --> 00:08:59,400 that static data member that we had in the class. 160 00:08:59,650 --> 00:09:01,650 And we'll just supply an endline here. 161 00:09:02,150 --> 00:09:05,950 Okay. So now let's go to main, and let's call that method. 162 00:09:05,950 --> 00:09:08,150 Let's just call display active players. 163 00:09:15,350 --> 00:09:18,230 All right. We'll put a break point in here 164 00:09:18,930 --> 00:09:22,530 so that we can walk through this. And let's run this, 165 00:09:24,520 --> 00:09:27,880 and we have an error display active players that can't find it players. 166 00:09:28,870 --> 00:09:31,370 I spelled it wrong, let me put an s up here. 167 00:09:31,920 --> 00:09:33,520 And now we should be good to go. 168 00:09:34,120 --> 00:09:36,220 So let's step through it through the debugger, 169 00:09:36,770 --> 00:09:40,070 and I'll move this output window here over to the right again. 170 00:09:41,570 --> 00:09:43,450 And so what do we expect here. 171 00:09:43,450 --> 00:09:47,650 Well, we're going to call display active players and display active players is simply going to ask 172 00:09:47,650 --> 00:09:51,010 the player class to get the number of players. At this point, we have none. 173 00:09:51,310 --> 00:09:54,670 There's no way we could have done this if we had an object, right. 174 00:09:54,670 --> 00:09:57,870 Because there are no objects. So in this case, we're calling player 175 00:09:57,870 --> 00:10:00,570 and asking the player class to give us the number of players. 176 00:10:00,570 --> 00:10:03,670 And we expect this to display 0. When we walk through it, 177 00:10:03,670 --> 00:10:07,270 we get active player 0 just exactly what we expect. 178 00:10:07,270 --> 00:10:08,770 Now let's create an object. 179 00:10:09,570 --> 00:10:11,570 And let's create a player, 180 00:10:12,170 --> 00:10:13,870 and we'll just call it hero. 181 00:10:15,750 --> 00:10:19,750 And we'll give it the name hero, and we'll default everything else. 182 00:10:20,410 --> 00:10:23,110 And then we'll call display active players again. 183 00:10:26,110 --> 00:10:30,370 So at this point, we have one active player. So let's debug this. 184 00:10:30,370 --> 00:10:31,870 We'll step through it again. 185 00:10:36,640 --> 00:10:40,520 And right now, again, we're displaying active players we're. Going to get back to 0. 186 00:10:40,520 --> 00:10:44,320 I'm going to create my player object. It exists. You can see it right here. 187 00:10:44,820 --> 00:10:48,820 So we expect that we've got number of players is one. 188 00:10:49,270 --> 00:10:51,270 And if you look right here in your local variables pane, you can 189 00:10:51,270 --> 00:10:54,570 see that we've got that num players static variable right here. 190 00:10:55,120 --> 00:10:59,220 And we have access to it here. So it's nice because you can actually see it. So at this point, 191 00:10:59,220 --> 00:11:01,220 we run it we get back the one, 192 00:11:01,220 --> 00:11:04,220 which is exactly what we expect since we do have one object. 193 00:11:04,220 --> 00:11:08,720 Okay. So now let's do another example here. Let's create a local block here. 194 00:11:09,220 --> 00:11:11,220 And we'll create another player, 195 00:11:11,720 --> 00:11:13,520 and we'll call that player frank, 196 00:11:14,120 --> 00:11:16,120 and again we'll default it to frank. 197 00:11:19,220 --> 00:11:21,720 And then we'll display active players right in here. 198 00:11:24,220 --> 00:11:28,580 And then we'll display it again when we leave the block. Now what we expect to happen here 199 00:11:29,080 --> 00:11:30,980 is we expect that 200 00:11:30,980 --> 00:11:33,980 this frank object will be created in this local block 201 00:11:34,780 --> 00:11:38,780 will display. Now we'll have two objects, right. We'll display two objects. 202 00:11:38,780 --> 00:11:41,220 Then it's going to go out of scope and be destroyed. 203 00:11:41,220 --> 00:11:45,580 So when we get back to here, it's going to display one less again. So let's do that one more time. 204 00:11:46,080 --> 00:11:49,740 We'll run through the debugger. And we'll step through this one line at a time. 205 00:11:51,240 --> 00:11:55,140 Here we go, display active players. We expect I'll expand this here.We expect it to 206 00:11:55,140 --> 00:11:58,340 display 0, which it does. I just created the hero. 207 00:11:58,340 --> 00:12:00,840 And I want to display the active players, I have one. 208 00:12:01,340 --> 00:12:03,340 Now I'm here. I'm creating frank. 209 00:12:03,840 --> 00:12:05,840 And I'm displaying active players. 210 00:12:06,500 --> 00:12:09,400 I've got two. And obviously, I can refresh over here. 211 00:12:09,700 --> 00:12:13,360 And I can see in both places that I've got two players. 212 00:12:13,360 --> 00:12:15,610 That's that static data member right there. 213 00:12:17,210 --> 00:12:20,710 Now we expect frank to go out of scope, so the destructor will be called, 214 00:12:21,910 --> 00:12:24,510 right. It just got called. So if we refresh now, 215 00:12:25,410 --> 00:12:28,710 we've got hero, and we're back down to one. And we display 216 00:12:29,510 --> 00:12:30,510 back down to one. 217 00:12:31,210 --> 00:12:34,810 Eventually, we'll destroy hero, again, as well. 218 00:12:34,810 --> 00:12:38,810 And we'll get down to 0. Now let's do just one more little piece of code here. 219 00:12:38,810 --> 00:12:41,310 And what we'll do is we'll do it right here at the bottom. 220 00:12:41,810 --> 00:12:43,810 Again, we'll say player. 221 00:12:43,810 --> 00:12:47,010 We'll create an enemy, which is a pointer to a player. 222 00:12:48,910 --> 00:12:50,810 And we'll create a new enemy, 223 00:12:52,410 --> 00:12:53,910 and we'll just call him enemy 224 00:12:54,810 --> 00:12:56,610 and make him pretty strong. 225 00:13:00,610 --> 00:13:01,210 Okay. 226 00:13:02,010 --> 00:13:06,010 And right now what we'll do is we'll display active players 227 00:13:14,710 --> 00:13:16,710 and then we'll delete enemy. 228 00:13:17,510 --> 00:13:20,110 And we'll display the active players one more time. 229 00:13:22,610 --> 00:13:25,210 Okay. So let's walk through this one last time. 230 00:13:29,010 --> 00:13:32,370 And you can see how useful using these static data members is. 231 00:13:32,370 --> 00:13:33,970 So I'm displaying active players, 232 00:13:34,470 --> 00:13:37,670 I get back a 0, I create player, I display that to players again, 233 00:13:37,670 --> 00:13:41,030 I get back a one, which is what I expect. I create frank, 234 00:13:41,030 --> 00:13:44,530 so that gives me two objects. And when I display them, I get the two. 235 00:13:44,530 --> 00:13:48,130 Frank just got destroyed. So I'm going to display one again. 236 00:13:48,790 --> 00:13:51,790 Now here I'm going to create that enemy 237 00:13:51,790 --> 00:13:54,290 object on the heap since it's a dynamic allocation. 238 00:13:55,190 --> 00:13:57,790 And I display active. I've got two again. 239 00:13:58,040 --> 00:14:01,240 I'm going to delete enemy. I'm back down to one. 240 00:14:01,840 --> 00:14:05,170 And at this point, the hero will be deleted, and I'll go back to 0. 241 00:14:05,470 --> 00:14:09,570 Okay. So there you go. There's a real simple example that's using the multiple files here 242 00:14:09,570 --> 00:14:12,570 to declare some static data members, a static 243 00:14:12,570 --> 00:14:16,570 class function and we've got a pretty useful little um 244 00:14:16,570 --> 00:14:18,170 technique that's used a lot. 245 00:14:18,530 --> 00:14:22,330 Sometimes you really need to know how many of your objects are out there, and this is 246 00:14:22,330 --> 00:14:23,430 really easy way to do it.