320 likes | 412 Views
Queues II. Chapter 4. Getting Started. Download Queue Demo as of end of last class. http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_02_14_Queues/ File Queue_Demo_in_class.zip. Implement Clear. template <class T> void Queue<T>::Clear(void) { delete[] data;
E N D
Queues II Chapter 4
Getting Started • Download Queue Demo as of end of last class. • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_02_14_Queues/ • File Queue_Demo_in_class.zip
Implement Clear template <class T> void Queue<T>::Clear(void) { delete[] data; data = new T[size]; assert(data != 0); putter = 0; taker = 0; }
Add Test Code • Download test code: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_02_16_Queues_2/ • File Queue_Test.cpp • Replace stub Queue_Test.cpp in project.
Queue_Test.cpp #include <iostream> #include "Queue.h" #include <cassert> using namespace std; const int QUEUE_CAPACITY = 10; int main() { Queue<int> q(QUEUE_CAPACITY); assert (q.IsEmpty()); cout << "Newly created queue is empty\n"; printf ("Enqueueing 0 - %d \n", QUEUE_CAPACITY - 1); for (int i = 0; i < QUEUE_CAPACITY; ++i) { q.Enqueue(i); }
Queue_Test.cpp cout << "Initial queue:\n"; q.Display(cout); assert(!q.IsEmpty()); cout << "Now the queue is not empty\n"; cout << "Adding one more element, which should cause overflow. " << endl; try { q.Enqueue(1); cout << "ERROR\n"; // Should have thrown exception } catch (const char* msg) { cout << "Attempt to overfill queue threw exception as expected\n"; cout << "Message: " << msg << endl; } cout << "Queue should be unchanged\n" << endl; q.Display(cout);
Queue_Test.cpp cout << "Now removing elements from the queue\n"; while (!q.IsEmpty()) { int front = q.Front(); cout << "queue head: " << front << endl; int next_item = q.Dequeue(); assert (next_item == front); } cout << "Queue is now empty\n";
Queue_Test.cpp cout << "Getting front of empty queue. This should fail\n"; try { int x = q.Front(); cout << "ERROR\n"; // Should have thrown exception } catch (const char* msg) { cout << "Attempt to get front of empty queue threw exception as expected\n"; cout << "Message: " << msg << endl; }
Queue_Test.cpp cout << "Doing one more Dequeue. This should fail\n"; try { q.Dequeue(); cout << "ERROR\n"; // Should have thrown exception cin.get(); } catch (char* msg) { cout << "Attempt to Dequeue empty queue threw exception as expected\n"; cout << "Message: " << msg << endl; }
Queue_Test.cpp cout << "Testing dynamic allocation\n"; Queue<int>* q2 = new Queue<int>(QUEUE_CAPACITY); assert(q2 != 0); cout << "Allocation was successful\n"; cout << "Testing delete\n"; delete(q2); q2 = 0; cout << "Delete was successful\n"; cout << "Test complete. Press Enter to exit." << endl; cin.get(); // Hold window open return 0;
Test Clear cout << "Initial queue:\n"; q.Display(cout); cout << "Calling Clear\n"; q.Clear(); cout << "Calling Display again\n"; q.Display(cout); Comment out rest of the test code.
Improve the Display Method template <class T> void Queue<T>::Display(std::ostream& out) const { if (this->IsEmpty()) { out << "The queue is empty\n"; return; } for (int i = taker; i != putter; i = (i+1)%size) { out << data[i] << endl; } }
A Queue of Objects • Now let’s test the Queue template with a class of our own. • Download and add to the project: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_02_16_Queues_2/ Files Cat.h and Cat.cpp
Cat.h #include <iostream> using namespace std; struct Date { int Day; int Month; int Year; };
Cat.h class Cat { private: char* name; Date date_of_birth; double weight; public: Cat(const char* name_, Date dob, double weight_); Cat(const Cat& original); Cat(); Cat& operator=(const Cat& rhs); ~Cat(void); const char* Name() const { return name;}; Date Date_of_Birth() const { return date_of_birth;}; double Weight() const {return weight;}; void Display() const; friend ostream& operator<<(ostream& os, const Cat& cat); };
Cat.cpp #include <cstring> #include <iostream> #include "Cat.h" using namespace std; Cat::Cat(const char* name_, Date dob, double weight_) { size_t len = strlen(name_); name = new char[len + 1]; strcpy(name, name_); this->date_of_birth = dob; this->weight = weight_; }
Default Constructor Cat::Cat(void) { size_t len = 0; name = new char[1]; name[0] = 0; Date dob = {0,0,0}; this->date_of_birth = dob; this->weight = 0; }
Normal Constructor Cat::Cat(const Cat& original) { size_t len = strlen(original.name); name = new char[len + 1]; strcpy(name, original.name); this->date_of_birth = original.date_of_birth; this->weight = original.weight; }
Assignment Operator Cat& Cat::operator=(const Cat& rhs) { if (&rhs == this) { return *this; } delete[] this->name; size_t len = strlen(rhs.name); name = new char[len + 1]; strcpy(name, rhs.name); this->date_of_birth = rhs.date_of_birth; this->weight = rhs.weight; return *this; }
Display Method void Cat::Display() const { cout << "Cat: " << this->name << " "; cout << "DoB: " << this->date_of_birth.Month << "/" << this->date_of_birth.Day << "/" << this->date_of_birth.Year << " "; cout << "Weight: " << this->weight; }
Destructor Cat::~Cat(void) { cout << "Cat::~Cat called for " << this->name << endl; delete[] this->name; }
Insertion Operator ostream& operator<<(ostream& os, const Cat& cat) { os << "Cat: " << cat.name << " "; os << "DoB: " << cat.date_of_birth.Month << "/" << cat.date_of_birth.Day << "/" << cat.date_of_birth.Year << " "; os << "Weight: " << cat.weight; return os; }
New Main • Download: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_02_16_Queues_2/ • File Cat_Queue_Test.cpp
Test Cat Queue #include <iostream> #include "Queue.h" #include "Cat.h" using namespace std; void get_cats(Queue<Cat>& cat_queue) { Date dob = {12,1,2008}; Cat* c = new Cat("Fuzzy", dob, 4.5); cat_queue.Enqueue(*c); delete c; Date dob2 = {2,1,2008}; c = new Cat("Fluffy", dob2, 8.4); cat_queue.Enqueue(*c); delete c; Date dob3 = {4, 4, 2002}; c = new Cat("Savanna", dob3, 12.0); cat_queue.Enqueue(*c); delete c;
Test Cat Queue Date dob4 = {5, 5, 1998}; c = new Cat("Raleigh", dob4, 12.8); cat_queue.Enqueue(*c); delete c; Date dob5 = {10, 12, 2005}; c = new Cat("Tigger", dob5, 8.6); cat_queue.Enqueue(*c); delete c; Date dob6 = {8, 1, 2000}; c = new Cat("Bucky", dob6, 14.9); cat_queue.Enqueue(*c); delete c; }
Test Cat Queue int main(void) { Queue<Cat> my_queue(10); cout << "This is Queue Demo\n"; get_cats(my_queue); cout << "Queue\n"; my_queue.Display(cout); //cout << "Calling Clear\n"; //my_queue.Clear(); //cout << "Queue\n"; //my_queue.Display(cout); cout << "Normal Termination\n"; cin.get(); // Hold the window open return 0; }
Test Clear • Uncomment code that calls Clear and then displays the queue again. int main(void) { Queue<Cat> my_queue(10); cout << "This is Queue Demo\n"; get_cats(my_queue); cout << "Queue\n"; my_queue.Display(cout); cout << "Calling Clear\n"; my_queue.Clear(); cout << "Queue\n"; my_queue.Display(cout); cout << "Normal Termination\n"; cin.get(); // Hold the window open return 0; }
Conclusion • Calling delete for the array invokes the destructor for each element of the array.