The document discusses enumerated constants and enumerated types in C++. It introduces enumerated constants as a way to assign codes or values to a set of items. It then discusses enumerated types which declare a type whose values can only be those enumerated. Enumerated types avoid errors from assigning invalid values. The document also covers using enumerated types with constructors, arrays of pointers, dynamic memory allocation, destructors, and virtual destructors.
The document discusses enumerated constants and enumerated types in C++. It introduces enumerated constants as a way to assign codes or values to a set of items. It then discusses enumerated types which declare a type whose values can only be those enumerated. Enumerated types avoid errors from assigning invalid values. The document also covers using enumerated types with constructors, arrays of pointers, dynamic memory allocation, destructors, and virtual destructors.
const int box_code = 0; Intro to C++ part 4 const int tank_code = 1; const int flat_code = 2; Marge Coahran Some material from: • Even easier: Winstohn, P.H., “On to C++” enum {box_code, tank_code, flat_code}; ISBN: 0-201-58043-8 enum {ftp = 21, ssh = 23, http = 80 };
Using enumerated constants Enumerated types
int type_code; • declare an enumerated type: … enum car_code {box_code, tank_code, flat_code}; switch (type_code) { case box_code: train[i] = new BoxCar; break; case tank_code: train[i] = new TankCar; break; • declare a variable of that type: case flat_code: train[i] = new FlatCar; break; enum car_code type_code; default: cerr << “Invalid type code ” << type_code << endl; }; • now we can only assign valid types: type_code = box_code; • Can we avoid this error? type_code = 0; /* ERROR */
More Constructors More Constructors (II)
class TankCar { class Plant { public: public: //constructor with default parameters values enum color_code {green, red, white}; TankCar(int h = 10, int w = 5, int l = 10) { height = h, width = w, length = l}; Plant(color_code c = green); private: … double height, width, length; }; }; class Raspberry : public Plant { main() { public: TankCar x; //constructor that calls its parent’s constructor TankCar x(12, 7,12); Raspberry() : Plant(red) {…}; TankCar x(12); … } } Freeing dynamic memory Freeing dynamic memory (II) • Recall -- allocating dynamic memory: • To delete (free) objects pointed to by an array of Plant* p1 = new Plant; pointers: Plant* p2 = new Plant[100]; main() { • To delete (free) a single object pointed to by p1: Plant* forest[100]; delete p1; forest[0] = new Plant; forest[1] = new Plant; • To delete (free) an array pointed to by p2: … delete [ ] p2; for (int i=0; i<100; i++) • “Different implementations will react differently to delete forest[i]; incorrect uses of delete and delete [].” (Stroustrup, 1997) }
Dynamic memory in class objects Destructors
• When an object goes out of scope, its local memory is • The class destructor runs when an object goes out of reclaimed. But what about dynamic memory? scope. Free dynamically allocated memory there.
class BoxCar : public RailCar { class BoxCar :public RailCar {
Public: Public: BoxCar(char* snum); BoxCar(char* snum); Private: ~BoxCar(); //destructor (only one!) char* serial_num; Private: }; char* serial_num; BoxCar::BoxCar(char * snum) { }; //dynamically allocate space for serial number BoxCar::~BoxCar() { serial_num = new char[strlen(snum)+1]; // free dynamically allocated memory strcpy(serial_num, snum); delete [ ] serial_num; } };
Destructors (II) Virtual Destructors
• When a dynamically allocated object is deleted • If a base class has any virtual functions, it should also (freed), its destructor automatically runs. have a virtual destructor (even if empty) to ensure the subclass destructor runs in this case.
main() { class RailCar {
RailCar* ptr = new BoxCar(“46520”); Public: RailCar (); delete ptr; virtual ~RailCar () { }; //virtual destructor } … Private: • But which destructor runs: ~BoxCar() or … ~RailCar()? };