Bound-Checked Array Template Class
#ifndef _SAFEARR_H_ #define _SAFEARR_H_ #include <iostream> #include <string> #include <algorithm> using namespace std; template <typename T> class SafeArr { public: // Create a new array of the given size. SafeArr(int asize) { m_size = asize; m_space = new T[asize]; } // Create an array as a copy of another. SafeArr(const SafeArr &other) { copyin(other); } // Clean up. ~SafeArr() { delete [] m_space; } // Find out how large this is. int size() const { return m_size; } // Perform an array assignment. Delete our space, then make us a // copy of other. SafeArr & operator=(const SafeArr &other) { delete [] m_space; copyin(other); return *this; } // Store into the array, or print an error message and don't // change the aray. void store(int pos, const T &tostore) { if(pos < m_size && pos >= 0) { m_space[pos] = tostore; } else { cerr << pos << " out of bounds on store" << endl; } } // Fetch from pos, or, if pos is out of bounds, print a message // and return T(). T fetch(int pos) const { if(pos < m_size && pos >= 0) { return m_space[pos]; } else { cerr << pos << " out of bounds on fetch" << endl; return T(); } } // Alternate version of fetch that works when there is no T() // (No default constructor for T.) Fills in the result through // the parameter void fetch(int pos, T &fetched) const { if(pos < m_size && pos >= 0) { fetched = m_space[pos]; } else { cerr << pos << " out of bounds on fetch" << endl; } } // Array printer. Works if T can be printed with <<. void print(ostream &out, string sep = " ") const { for(int n = 0; n < m_size; ++n) { out << m_space[n]; if(n < m_size-1) out << " "; } } private: T *m_space; // Actual storage space for the array. int m_size; // Size of the array. // Make us a copy of the other array. Allocates m_space of // the same size, then copies the contents of other.m_size into it, // and copies m_size. void copyin(const SafeArr &other) { m_space = new T[other.m_size]; m_size = other.m_size; copy(other.m_space, other.m_space + other.m_size, m_space); } }; /* * This allows the array to be printed with <<, assuming T can be. */ template <typename T> ostream & operator<<(ostream & strm, const SafeArr<T> &arr) { arr.print(strm); return strm; } #endif

Other times when a class needs to provide memory management automatically are copying (e.g. parameter passing), and assignment. C++ allows classes to specialize these operations using a copy constructor or assignment overload.