#include #include // Provides size_t #include // Provides assert class Bag { public: enum { DEFAULT_SIZE = 30 }; // Or static const size_t DEF... = 30; typedef int Item; Bag(size_t init_size = DEFAULT_SIZE ); Bag(const Bag& source); // for copy constructor ~Bag(); // destructor, see page 166 void resize(size_t new_size); void insert(const Item& entry); void remove(const Item& target); void operator +=(const Bag& addend); void operator =(const Bag& source); // assignment op size_t size( ) const { return used; } size_t occurrences(const Item& target) const; friend void operator >> (istream& ins, Bag& b); friend void operator << (ostream& outs, Bag& b); friend Bag operator +(const Bag& b1, const Bag& b2); private: Item *data; // The array to store items size_t used; // How much of array is used size_t bsize; // current size of the bag }; Bag::Bag(size_t init_size) { data = new Item[init_size]; bsize = init_size; used = 0; } Bag::Bag(const Bag& source) // copy constructor { size_t i; data = new Item[source.bsize]; bsize = source.bsize; used = source.used; for(i = 0; i < used; i++) data[i] = source.data[i]; } Bag::~Bag() // destructor: releasing dynamic memory { delete [] data; } void Bag::resize(size_t new_bsize) { size_t i; Item *larger_array; if (new_bsize == bsize) return; // The allocated memory is already the right size if (new_bsize < used) new_bsize = used; // Can't allocate less than we are using larger_array = new Item[new_bsize]; for (i = 0; i < used; i++) larger_array[i] = data[i]; delete [ ] data; data = larger_array; bsize = new_bsize; } void Bag::insert(const Item& entry) { if (used == bsize) resize(used+1); data[used] = entry; used++; } void Bag::remove(const Item& target) { size_t index; // The location of target in the data array // First, set index to the location of target in the data array, // which could be as small as 0 or as large as used-1. // If target is not in the array, then index will be set equal to used. for (index = 0; (index < used) && (data[index] != target); index++); if (index == used) return; // target isn't in the Bag, so no work to do // When execution reaches here, target is in the Bag at data[index]. // So, reduce used by 1 and copy the last item onto data[index]. used--; data[index] = data[used]; } void Bag::operator +=(const Bag& addend) { size_t i; // An array index size_t other_bag_size = addend.used; if (used + other_bag_size > bsize) resize(used + other_bag_size); for (i = 0; i < other_bag_size; i++) { data[used] = addend.data[i]; used++; } } void Bag::operator =(const Bag& source) { size_t i; Item *new_data; if (bsize != source.bsize) { new_data = new Item[source.bsize]; delete [ ] data; data = new_data; bsize = source.bsize; } used = source.used; for (i = 0; i < used; i++) data[i] = source.data[i]; } Bag operator +(const Bag& b1, const Bag& b2) { Bag answer(b1.bsize + b2.bsize); answer += b1; answer += b2; return answer; } void operator >> (istream& ins, Bag& b) { Bag::Item number; cout << "Enter numbers, a negative number when you are done: "; ins >> number; while (number >= 0) { if (b.size( ) < b.bsize) b.insert(number); else cout << "I have run out of room and can't add that number." << endl; cin >> number; } } void operator << (ostream& outs, Bag& b) { outs << "( "; for(int i = 0; i < b.used; i++) outs << b.data[i] << " "; outs << ")" << endl; } void main( ) { Bag b1, b2, b3; cin >> b1; cout << b1; cin >> b2; cout << b2; b1 += b2; cout << b1; b3 = b1 + b2; cout << b3; /* Not necessary. Destructor will be called twice! b1.~Bag(); b2.~Bag(); b3.~Bag(); */ }