Enumerated constants can we make "codes" for a set of items? enum car_code box_code, tank_code, flat_code; declare a variable of that type: type_code type_code; type_code = 0; / error / can we avoid this error? dynamic memory in class objects when an object goes out of scope, its local memory is reclaimed.
Enumerated constants can we make "codes" for a set of items? enum car_code box_code, tank_code, flat_code; declare a variable of that type: type_code type_code; type_code = 0; / error / can we avoid this error? dynamic memory in class objects when an object goes out of scope, its local memory is reclaimed.
Enumerated constants can we make "codes" for a set of items? enum car_code box_code, tank_code, flat_code; declare a variable of that type: type_code type_code; type_code = 0; / error / can we avoid this error? dynamic memory in class objects when an object goes out of scope, its local memory is reclaimed.
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()? };