1 00:00:00,243 --> 00:00:02,910 (upbeat music) 2 00:00:05,370 --> 00:00:07,380 Narrator: In this video, we'll look at the structure 3 00:00:07,380 --> 00:00:09,633 or syntax of an enumeration. 4 00:00:10,740 --> 00:00:12,960 If you've ever seen an enumeration before, 5 00:00:12,960 --> 00:00:15,870 you may be confused by the structure shown here. 6 00:00:15,870 --> 00:00:19,290 That's because many elements of an enumeration are optional. 7 00:00:19,290 --> 00:00:22,020 So often you'll see enumerations without names, 8 00:00:22,020 --> 00:00:23,583 types, or attributes. 9 00:00:24,420 --> 00:00:26,490 You'll notice that we have also omitted attributes 10 00:00:26,490 --> 00:00:27,630 from this structure. 11 00:00:27,630 --> 00:00:30,690 That's because attributes are a separate topic altogether 12 00:00:30,690 --> 00:00:33,300 and apply to more than just enumerations. 13 00:00:33,300 --> 00:00:34,890 In this section we'll only be covering 14 00:00:34,890 --> 00:00:36,660 the basics of enumerations 15 00:00:36,660 --> 00:00:39,810 so topics such as attributes won't be included. 16 00:00:39,810 --> 00:00:41,340 With that being said, let's take a look 17 00:00:41,340 --> 00:00:44,283 at the elements of an enumeration that we'll be using. 18 00:00:45,840 --> 00:00:48,090 First, we have the enumeration key. 19 00:00:48,090 --> 00:00:50,310 This defines the beginning of the enumeration 20 00:00:50,310 --> 00:00:51,840 as well as its scope. 21 00:00:51,840 --> 00:00:54,270 We'll cover the different types of enumeration scopes 22 00:00:54,270 --> 00:00:55,410 in detail soon, 23 00:00:55,410 --> 00:00:57,690 but for now just know that the enumeration 24 00:00:57,690 --> 00:01:00,060 can be either scoped or unscoped. 25 00:01:00,060 --> 00:01:01,470 Regardless of the scope, 26 00:01:01,470 --> 00:01:04,683 an enumeration will always start with the key word enum. 27 00:01:05,519 --> 00:01:08,160 The next part of an enumeration is its name. 28 00:01:08,160 --> 00:01:11,250 Naming is optional for unscoped enumerations, 29 00:01:11,250 --> 00:01:13,710 but can be useful for imposing type restrictions 30 00:01:13,710 --> 00:01:17,100 on variables that you want to be of an enumeration type. 31 00:01:17,100 --> 00:01:19,590 This is similar to what we saw in the last video 32 00:01:19,590 --> 00:01:22,650 where we imposed a type restriction on the state variable 33 00:01:22,650 --> 00:01:25,440 by declaring it as a state enumeration type. 34 00:01:25,440 --> 00:01:27,720 If we had not named the state enumeration, 35 00:01:27,720 --> 00:01:28,677 we would not have been able to do that 36 00:01:28,677 --> 00:01:31,590 and we'll see soon why this is the case. 37 00:01:31,590 --> 00:01:35,128 Next we have a colon followed by a type specifier. 38 00:01:35,128 --> 00:01:38,310 The specified type serves as the fixed underlying type 39 00:01:38,310 --> 00:01:40,860 of the enumeration's enumerators. 40 00:01:40,860 --> 00:01:43,560 Specifying the underlying type is optional, 41 00:01:43,560 --> 00:01:45,630 but can be used to reduce the amount of space 42 00:01:45,630 --> 00:01:47,760 an enumeration takes up in memory 43 00:01:47,760 --> 00:01:50,670 or to increase the accuracy of any calculations 44 00:01:50,670 --> 00:01:53,160 involving the enumerator values. 45 00:01:53,160 --> 00:01:56,700 The last part of the enumeration is a set of curly braces 46 00:01:56,700 --> 00:01:59,520 and this is the enumeration's enumerator list. 47 00:01:59,520 --> 00:02:02,370 This is where we define the names and integral values 48 00:02:02,370 --> 00:02:05,250 of the enumerators belonging to the enumeration. 49 00:02:05,250 --> 00:02:08,250 This can be done explicitly or implicitly. 50 00:02:08,250 --> 00:02:10,530 That's it, now let's look at a simple enumeration 51 00:02:10,530 --> 00:02:12,130 to see these elements in action. 52 00:02:13,620 --> 00:02:16,980 This is about as simple of an enumeration as we can get. 53 00:02:16,980 --> 00:02:20,250 It has no name, no fixed underlying type, 54 00:02:20,250 --> 00:02:23,610 and has three enumerators, red, green, and blue. 55 00:02:23,610 --> 00:02:25,410 You'll notice that none of the enumerators 56 00:02:25,410 --> 00:02:26,820 have been initialized. 57 00:02:26,820 --> 00:02:29,580 This is because the compiler could do this for us. 58 00:02:29,580 --> 00:02:32,400 If the first enumerator has no initializer, 59 00:02:32,400 --> 00:02:35,160 the compiler will assign it a value of zero. 60 00:02:35,160 --> 00:02:37,980 For all other enumerators without initializers, 61 00:02:37,980 --> 00:02:39,540 the compiler will assign the value 62 00:02:39,540 --> 00:02:41,970 of the previous enumerator plus one. 63 00:02:41,970 --> 00:02:45,330 This is known as implicit initialization. 64 00:02:45,330 --> 00:02:48,090 Of course we might not always want the integral values 65 00:02:48,090 --> 00:02:49,620 assigned by the compiler 66 00:02:49,620 --> 00:02:53,010 so we can always explicitly assign them ourselves. 67 00:02:53,010 --> 00:02:56,280 In some cases, we may want to assign certain enumerators 68 00:02:56,280 --> 00:02:59,550 specific values and not care what the others are assigned. 69 00:02:59,550 --> 00:03:02,310 In cases like these, we can explicitly assign 70 00:03:02,310 --> 00:03:04,590 certain enumerators the values we want 71 00:03:04,590 --> 00:03:05,520 and have the compiler 72 00:03:05,520 --> 00:03:07,950 implicitly assign values to the others. 73 00:03:07,950 --> 00:03:12,300 This is known as explicit/implicit initialization. 74 00:03:12,300 --> 00:03:14,190 Now let's take a look at the enumeration's 75 00:03:14,190 --> 00:03:16,083 underlying type in more detail. 76 00:03:18,060 --> 00:03:21,480 If the underlying type of an enumeration is not fixed, 77 00:03:21,480 --> 00:03:23,910 the compiler assigns the first integral type 78 00:03:23,910 --> 00:03:27,480 that it's able to hold the enumeration's entire value range. 79 00:03:27,480 --> 00:03:30,750 These integral types are listed on the right in rank order 80 00:03:30,750 --> 00:03:34,110 with signed given preference over unsigned. 81 00:03:34,110 --> 00:03:36,510 The sizes or widths of these integral types 82 00:03:36,510 --> 00:03:38,640 depends on the system being used, 83 00:03:38,640 --> 00:03:39,930 but for this example, 84 00:03:39,930 --> 00:03:42,330 we'll use the C++ minimum standard 85 00:03:42,330 --> 00:03:45,060 which are reflected by the values listed. 86 00:03:45,060 --> 00:03:46,110 Now with this knowledge, 87 00:03:46,110 --> 00:03:47,700 can you tell what underlying type 88 00:03:47,700 --> 00:03:50,250 the compiler will assign to our simple enumeration? 89 00:03:51,270 --> 00:03:54,180 It might help to look at the minimum binary representation 90 00:03:54,180 --> 00:03:55,710 of our enumerator values 91 00:03:55,710 --> 00:03:58,230 assuming a signed bit is used. 92 00:03:58,230 --> 00:04:00,030 We can see that each of the enumerators 93 00:04:00,030 --> 00:04:02,310 can be represented by three bits 94 00:04:02,310 --> 00:04:03,930 and so the first integral type 95 00:04:03,930 --> 00:04:06,480 that is able to hold all three bits is int 96 00:04:06,480 --> 00:04:09,210 since it has a width of 16 bits. 97 00:04:09,210 --> 00:04:12,690 Now what if we explicitly initialize the enumerator blue 98 00:04:12,690 --> 00:04:16,440 with the value -32769? 99 00:04:16,440 --> 00:04:19,529 Obviously the underlying type will need to be signed 100 00:04:19,529 --> 00:04:22,079 since it must be able to hold negative values, 101 00:04:22,079 --> 00:04:23,790 but can we tell whether it will be an int, 102 00:04:23,790 --> 00:04:25,530 a long, or a long long? 103 00:04:25,530 --> 00:04:28,230 Let's take a look at the minimum binary representation 104 00:04:28,230 --> 00:04:30,300 of our enumerator values again. 105 00:04:30,300 --> 00:04:31,890 The ennumerator's red and green 106 00:04:31,890 --> 00:04:34,380 require three bit representation 107 00:04:34,380 --> 00:04:37,290 and blue a 32 bit representation. 108 00:04:37,290 --> 00:04:38,520 Because the underlying type 109 00:04:38,520 --> 00:04:41,130 must be able to hold all the enumerator values, 110 00:04:41,130 --> 00:04:42,840 the compiler will base its selection 111 00:04:42,840 --> 00:04:45,900 on the largest required bit representation. 112 00:04:45,900 --> 00:04:48,300 In this case, blue, and so the compiler 113 00:04:48,300 --> 00:04:51,273 will assign the enumeration the underlying type of long. 114 00:04:52,440 --> 00:04:55,440 In some cases, we may want to fix an enumeration's 115 00:04:55,440 --> 00:04:58,410 underlying type for the purposes of saving memory 116 00:04:58,410 --> 00:05:00,900 or increasing the accuracy of calculations 117 00:05:00,900 --> 00:05:03,240 involving enumerator values. 118 00:05:03,240 --> 00:05:05,340 This can be accomplished by placing a colon 119 00:05:05,340 --> 00:05:07,590 and the fixed underlying data type 120 00:05:07,590 --> 00:05:11,490 directly before the enumerator's enumeration list. 121 00:05:11,490 --> 00:05:16,110 C++ has types such as uint8, uint16 and so forth 122 00:05:16,110 --> 00:05:18,480 that allow us to specify the exact number 123 00:05:18,480 --> 00:05:20,460 of bits that we require. 124 00:05:20,460 --> 00:05:22,590 If we try to fix an underlying type 125 00:05:22,590 --> 00:05:25,380 that cannot hold the enumeration's entire range, 126 00:05:25,380 --> 00:05:27,390 the compiler will throw an error. 127 00:05:27,390 --> 00:05:29,640 Now let's look at the naming of an enumeration 128 00:05:29,640 --> 00:05:30,573 in more detail. 129 00:05:31,890 --> 00:05:34,140 Nameless enumerations are often referred 130 00:05:34,140 --> 00:05:36,690 to as anonymous enumerations. 131 00:05:36,690 --> 00:05:39,210 Because anonymous enumerations have no name, 132 00:05:39,210 --> 00:05:41,310 it's not possible to declare variables 133 00:05:41,310 --> 00:05:43,770 of that enumeration type. 134 00:05:43,770 --> 00:05:45,540 The best we can do is declare a variable 135 00:05:45,540 --> 00:05:48,060 as the underlying type of the enumeration, 136 00:05:48,060 --> 00:05:49,650 but this means that while the variable 137 00:05:49,650 --> 00:05:51,630 can be assigned to the enumerators, 138 00:05:51,630 --> 00:05:53,310 it can also be assigned any value 139 00:05:53,310 --> 00:05:55,530 belonging to the underlying type. 140 00:05:55,530 --> 00:05:58,380 Because of this, we say that anonymous enumerations 141 00:05:58,380 --> 00:06:00,213 provide no type safety. 142 00:06:01,692 --> 00:06:03,450 In the case of the anonymous enumeration 143 00:06:03,450 --> 00:06:06,660 containing the enumerators red, green, and blue, 144 00:06:06,660 --> 00:06:08,880 if we want the variable my_color 145 00:06:08,880 --> 00:06:10,980 to be assigned one of these enumerators, 146 00:06:10,980 --> 00:06:13,200 we must declare it as the underlying type 147 00:06:13,200 --> 00:06:16,500 of the enumeration, in this case int, 148 00:06:16,500 --> 00:06:18,840 but this means that while it can be assigned red, 149 00:06:18,840 --> 00:06:22,233 green and blue, it can also be assigned any integer value. 150 00:06:23,370 --> 00:06:25,530 Oftentimes we want a variable's assignment 151 00:06:25,530 --> 00:06:29,400 to be restricted to only the enumerators of an enumeration. 152 00:06:29,400 --> 00:06:32,070 As we saw earlier with the rocket launch example, 153 00:06:32,070 --> 00:06:33,780 this can be quite important 154 00:06:33,780 --> 00:06:35,040 and so to accomplish this, 155 00:06:35,040 --> 00:06:37,860 we can give an enumeration a meaningful name 156 00:06:37,860 --> 00:06:40,140 that represents its enumerators. 157 00:06:40,140 --> 00:06:42,630 By providing a name, we're defining the enumeration 158 00:06:42,630 --> 00:06:46,800 as a unique type that can only assume its enumerator values. 159 00:06:46,800 --> 00:06:48,930 Because of this, we say that the enumeration 160 00:06:48,930 --> 00:06:50,583 provides type safety. 161 00:06:51,480 --> 00:06:54,300 As good design practice, the name given to an enumeration 162 00:06:54,300 --> 00:06:58,230 should form an is a relationship with its enumerators. 163 00:06:58,230 --> 00:07:01,560 In this case, color is a good name for the enumeration 164 00:07:01,560 --> 00:07:05,310 since red is a color, green is a color, and blue is a color. 165 00:07:05,310 --> 00:07:07,680 By giving the enumeration the name color, 166 00:07:07,680 --> 00:07:10,380 we have defined a unique type of that name 167 00:07:10,380 --> 00:07:14,370 which can only assume the values of red, green, and blue. 168 00:07:14,370 --> 00:07:16,920 As such, we can declare the variable my_color 169 00:07:16,920 --> 00:07:18,420 as a color type, 170 00:07:18,420 --> 00:07:22,260 thus restricting its assignment to only red, green or blue. 171 00:07:22,260 --> 00:07:23,460 And that's it. 172 00:07:23,460 --> 00:07:24,900 Almost everything you need to know 173 00:07:24,900 --> 00:07:27,030 about enumeration structure. 174 00:07:27,030 --> 00:07:29,250 The only thing that's left to cover are their scopes 175 00:07:29,250 --> 00:07:31,050 and all the things we can do with them. 176 00:07:31,050 --> 00:07:32,610 Now let's head over to the next video 177 00:07:32,610 --> 00:07:34,920 to learn what unscoped enumerations are 178 00:07:34,920 --> 00:07:36,120 and how we can use them.