230 likes | 477 Views
B Smith: New lecture for 05. Use this for evolving to Java. B Smith: IS this too long? Should it be shortened?. Destructors. B Smith: Save this for later or use in Fa06, or is this redundant?. Math 130 Lecture # xx Mo/Da/Yr. B Smith: Covering derived classes more important. Overview.
E N D
B Smith: New lecture for 05. Use this for evolving to Java B Smith: IS this too long? Should it be shortened? Destructors B Smith: Save this for later or use in Fa06, or is this redundant? Math 130Lecture # xxMo/Da/Yr B Smith: Covering derived classes more important
Destructors • When a class object goes out of scope, Destructors “clean house” • When a function is called, it may work with temporary variables • A linked-list class might use a constructor to build nodes (malloc() ), and a destructor to free nodes (free() ) • It’s good practice to clean up after your objects and free any allocated memory • Use the name of the class, preceded by a tilde (~) • Destructors receive no arguments and return no values
Default Destructor • All objects have been destroyed automatically by the default destructor • In the examples where we’ve not explicitly defined a destructor, the compiler creates one • Note that the default destructor does not automatically delete/free objects that have been allocated on the system heap (free store)!
B Smith: Should really be focused on using references int main() { Box Boxes[5]; // Array of Box objects declared Box Cigar(8.0, 5.0, 1.0); // Declare Cigar box Box Match(2.2, 1.1, 0.5); // Declare Match box // Initialize pointer to Cigar object address Box* pB1 = &Cigar; Box* pB2 = 0; // Pointer initialized to null cout << endl << "Volume of Cigar is " << pB1->Volume(); // Volume of obj. pointed to pB2 = Boxes; // Set to address of array Boxes[2] = Match; // Set 3rd element to Match cout << endl // Now access thru pointer << "Volume of Boxes[2] is " << (pB2 + 2)->Volume(); cout << endl; return 0; }
A Simple Destructor // Ex7_01.cpp // Class with an explicit destructor #include <iostream> using namespace std; class Box// Class definition at global scope { public: // Destructor definition ~Box() { cout << "Destructor called." << endl; } // Constructor definition Box(double lv=1.0, double bv=1.0, double hv=1.0) { cout << endl << "Constructor called."; length = lv; // Set values of breadth = bv; // data members height = hv; } // Function to calculate the volume of a box double Volume() { return length * breadth * height; } // Function to compare two boxes which // returns true if the first is greater // than the second, and false otherwise int compare(Box* pBox) { return Volume() > pBox->Volume(); } private: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches }; int main() { Box Boxes[5]; // Array of Box objects declared Box Cigar(8.0, 5.0, 1.0); // Declare Cigar box Box Match(2.2, 1.1, 0.5); // Declare Match box // Initialize pointer to Cigar object address Box* pB1 = &Cigar; Box* pB2 = 0; // Pointer initialized to null cout << endl << "Volume of Cigar is " << pB1->Volume(); // Volume of obj. pointed to pB2 = Boxes; // Set to address of array Boxes[2] = Match; // Set 3rd element to Match cout << endl // Now access thru pointer << "Volume of Boxes[2] is " << (pB2 + 2)->Volume(); cout << endl; return 0; } B Smith: only useful in that it shows what happens with an array. Student had a great question regarding which Constructor is called. Better explanation needed. ….. Uhhh, here, there is only one constructor B Smith: Use colors and provide as a basic handout. Put online as a separate file.
Box Class // Ex6_03.cpp // Using a constructor #include <iostream> using namespace std; class Box // Class definition at global scope { private: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches public: // Constructor definition Box(double lv, double bv, double hv) { cout << endl << "Constructor called."; length = lv; // Set values of breadth = bv; // data members height = hv; } // Function to calculate the volume of a box double Volume() { return length * breadth * height; } };
Box Class Client int main(void) { Box Box1(78.0,24.0,18.0); // Declare and initialize Box1 Box CigarBox(8.0,5.0,1.0); // Declare and initialize CigarBox double volume = 0.0; // Store the volume of a box here volume = Box1.Volume(); // Calculate volume of Box1 cout << endl << "Volume of Box1 = " << volume; cout << endl << "Volume of CigarBox = " << CigarBox.Volume(); cout << endl; return 0; }
The Default Constructor • Try modifying the last example by adding the declaration for Box2 that we had previously: • Box Box2; // Declare Box2 of type Box • Here, we've left Box2 without initializing values. When you rebuild this version of the program, you'll get the error message: • error C2512: 'Box': no appropriate default constructor available
Supply a Default Constructor // Ex6_04.cpp // Supplying and using a default constructor #include <iostream > using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv, double bv, double hv) { cout << endl << "Constructor called."; length = lv; // Set values of breadth = bv; // data members height = hv; } // Default constructor definition Box() { cout << endl << "Default constructor called."; } // Function to calculate the volume of a box double Volume() { return length * breadth * height; } };
Box Class Client int main(void) { Box Box1(78.0,24.0,18.0); // Declare and initialize Box1 Box Box2; // Declare Box2 - no initial values Box CigarBox(8.0,5.0,1.0); // Declare and initialize CigarBox double volume = 0.0; // Store the volume of a box here volume = Box1.Volume(); // Calculate volume of Box1 cout << endl << "Volume of Box1 = " << volume; Box2.height = Box1.height - 10; // Define Box2 Box2.length = Box1.length/2.0; // members in Box2.breadth = 0.25*Box1.length; // terms of Box1 cout << endl << "Volume of Box2 = " << Box2.Volume(); cout << endl << "Volume of CigarBox = " << CigarBox.Volume(); cout << endl; return 0; }
Problems? class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv = 1.0, double bv = 1.0, double hv = 1.0) { cout << endl << "Constructor called."; length = lv; // Set values of breadth = bv; // data members height = hv; } // Default constructor definition Box() { cout << endl << "Default constructor called."; } // Function to calculate the volume of a box double Volume() { return length * breadth * height; } };
The Fix // Ex6_05.cpp // Supplying default values for constructor arguments #include <iostream> using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv=1.0, double bv=1.0, double hv=1.0) { cout << endl << "Constructor called."; length = lv; // Set values of breadth = bv; // data members height = hv; } // Function to calculate the volume of a box double Volume() { return length * breadth * height; } };
int main(void) { Box Box2; // Declare Box2 - no initial values cout << endl << "Volume of Box2 = " << Box2.Volume(); cout << endl; return 0; }
B Smith: Discuss malloc/free and new/delete! Use linked-list as an example?? Or Josephus?? Destructors and malloc()/free() • Allocate memory for class data members dynamically with new or malloc • Memory requested is subseqently free’d with free() • Destructors enable a type of “garbage collection” • they’re automatically run when an object goes out of scope • With a suitable destructor, memory is automatically cleaned up
Destructor using delete[] //Listing 02_01 class Message { private: char* pmessage; //Pointer to object text string public: // Function to display a message void ShowIt(void) { cout << endl << pmessage; } // Constructor definition Message(const char* text = "Default message") { // Allocate space for text pmessage = new char[strlen(text)+1]; // Copy text to new memory strcpy(pmessage, text); } ~Message(); // Destructor prototype }; // Listing 02_02 // Destructor to free memory allocated by new Message::~Message() { cout << "Destructor called." // track what happens << endl; delete[] pmessage; // Free memory assigned to ptr // Ex7_02.cpp // Using a destructor to free memory #include <iostream> // For stream I/O #include <string> // For strlen() and strcpy() using namespace std; // Put the Message class definition here (Listing 02_01) // Put the destructor definition here (Listing 02_02) int main() { // Declare object Message Motto("A miss is as good as a mile."); // Dynamic object Message* pM = new Message("A cat can look at a queen."); Motto.ShowIt(); // Display 1st message pM->ShowIt(); // Display 2nd message cout << endl; // delete pM; // Manually delete object created with new return 0; }
class Message //Listing 02_01 class Message { private: char* pmessage; //Pointer to object text string public: // Function to display a messageoid ShowIt(void) { cout << endl << pmessage; } // Constructor definition Message(const char* text = "Default message") { // Allocate space for text pmessage = new char[strlen(text)+1]; // Copy text to new memory strcpy(pmessage, text); } ~Message(); // Destructor prototype };
Message Destructor // Listing 02_02 // Destructor to free memory allocated by new Message::~Message() { cout << "Destructor called." // track what happens << endl; delete[] pmessage; // Free the memory assigned to ptr }
Message Class driver function // Using a destructor to free memory #include <iostream> // For stream I/O #include <string> // For strlen() and strcpy() using namespace std; // Put the Message class definition here (Listing 02_01) // Put the destructor definition here (Listing 02_02) int main() { // Declare object Message Motto("A miss is as good as a mile."); // Dynamic object Message* pM = new Message("A cat can look at a queen."); Motto.ShowIt(); // Display 1st message pM->ShowIt(); // Display 2nd message cout << endl; // delete pM; // Manually delete object created with new return 0; }