BIT 143: In-Class Exercises Lecture 8 Page 1 / 4 Enums ; More Inheritance Note: Please keep the programs that you create today, in case you have a dispute about your grades for the ICEs at the end of the quarter. When working with a partner, make sure that each of saves your own copy. Part 1: Enumerations You should practice using enums by creating an enumeration to list out the following classes that students might take: BIT 115, BIT 116, BIT 142, and BIT 143. Create a variable (whose type is the enumeration you just created), and assign it one of those options. Try using it (Can you see if the variable is BIT 142? Can you use a switch on the variable? Can you print out the variable? Can you create a function to print out the text "BIT 142", if the variables stores the BIT 142 option?) Part 2: Enumerations (optional) Given the code below, create (in main) several local variables that are Grades. Make sure that at least one represents a numeric grade, and at least one represents an audit. Do whatever exercises you feel you need to in order to understand enums, including such things as adding members to the enum, creating new enums, or re-writing this example from memory. enum GradeType { GT_NUMERIC, GT_AUDIT, GT_WITHDRAWAL, } ; class Grade { GradeType m_which; float m_numericGrade; public: Grade(GradeType type, float num) { m_which=type ; m_numericGrade=num; } PrintGrade() { switch(m_which) { case GT_AUDIT: cout << "Audit!" << endl; break; case GT_WITHDRAWAL: cout << "Withdrew!" << endl; BIT 143 © 2002, Mike Panitz, ® 2002, Mike Panitz Page 1 / 4 BIT 143: In-Class Exercises Lecture 8 Page 2 / 4 break; case GT_NUMERIC: cout << "Student got " << m_numericGrade << endl; break; } } ; Part 3: Basic Inheritance Imagine that you're trying to create a video game. The player will control a character within the video game, and direct the character to talk around and pick things up. You need to create a collection of classes that represent things that characters can pick up. Create a new class, named Item. This will serve as the base class for all the other things that can be picked up. Think of some properties that physical items have, such as weight, volume, and color, and include instance variables that will model these properties. Make sure to include appropriate methods, such as accessor methods to get the values of these fields, and maybe something like a Print method to print the object's description out to the screen. Next, create a subclass to model something that a character might pick up, like a Flashlight. Think up some properties that the subclass might have, and include instance variables to model them, as well. For example, a Flashlight, in addition to having weight, volume, and color, will also have batteries. The longer the flashlight is left on, the less energy the batteries have. Thus, you might model the amount of energy left as a float, which holds the percentage of power left. Create a test program which will instantiate both types of objects (use the new operator!), and call their methods. Part 4: Pointers and Inheritance Modify your test program so that you create 2 pointers of type Item *, and use this to call all of the Item's methods on both instances. Part 5: Inheritance: Constructors Last part you created a base class named Item to model things in a game, and then created more specific classes that were derived from Item. For this ICE, you should make sure that your derived class(es) calls a constructor (other than the default constructor) on the Item portion of the object. Part 6: Virtual Functions BIT 143 © 2002, Mike Panitz, ® 2002, Mike Panitz Page 2 / 4 BIT 143: In-Class Exercises Lecture 8 Page 3 / 4 Create a method, named Print, in both the base and subclasses. First try calling the method using both pointers, and observe the results they give. Then override the Print method in the subclass by adding the virtual keyword to BOTH method declarations, and try calling them again. Part 7: Virtual Functions : GetType One way to figure out which type of object you're dealing with is to add a virtual method named GetType to the base class, and then override it for each subclass. The return type should be an enum, which lists the possible types. In this case, you might have an enum item for FLASHLIGHT, and others for other items. By first checking the GetType method, you'll be able to safely typecast the pointer (of type Item *) to a pointer of another type, such as Flashlight *. Part 8: Virtual Destructors In your Item class, create a destructor and mark it virtual, even if it doesn't do anything. I.e., even if the destructor has an empty body, make sure to mark it virtual so that all classes that derive from it will also be virtual. Override the destructor in a derived class, and make sure that the correct destructor is called when you delete the object. Then try removing the virtual modifier from the Item, and try it again. Make sure to try deleteing the object via a pointer that's the same type as the derived class, and then again, via a pointer of type Item. Part 9: Abstract Base Class While Items serve as a useful base class for all the items in your game, you clearly shouldn't be allowed to instantiate one directly. A player's character might hold a broom, or a key, or a book, but never a generic "item". Make the Item class abstract by making one of it's methods pure virtual. I'd suggest the Print method, although any reasonable method would be fine. Part 10: Interface-Only Base Class We want our Item class to be abstract since it doesn't make sense to carry around generic "items". However, we do want to inherit some implementation from it – namely the weight, volume, and color fields, so we can't make it into an interface. (An interface is an informal term to describe a class that has no fields, and only public, pure-virtual methods). However it would be useful to have it derive from an interface, so that we could have a linked list of Things that are located at a given spot ("In this room, you see a Flashlight, a Sandwich, a Dragon, and the Dragon's Lackey…"). Create an interface named Thing, that has the following (pure virtual) methods: // Print a description onto the console virtual void Print() = 0; BIT 143 © 2002, Mike Panitz, ® 2002, Mike Panitz Page 3 / 4 BIT 143: In-Class Exercises Lecture 8 Page 4 / 4 // EnumType is an enum which has an entry for each class that's // derived from Thing. virtual EnumType GetType() = 0; // Return -1, 0, or 1, like strcmp. Each derived class, such as // Flashlight, should use the GetType method to make sure that the // Thing that it's being compared to is the same type as itself, // and if not, the method should return -9999. // If the types are the same, then you should downcast pOther, like so: // // Flashlight otherFlashlight = (FlashLight*)pOther; // virtual int Compare(Thing *pOther); Make sure to test each of the above methods with each class that you can instantiate. BIT 143 © 2002, Mike Panitz, ® 2002, Mike Panitz Page 4 / 4