I am having some trouble understanding how to properly use template functions. This is my first exposure to them and my textbook is not very helpful. Any help would be appreciated. Here is what I have so far...
driver
d_sort.hCode:#include <iostream> #include "d_random.h" #include "d_vector.h" #include "d_sort.h" using namespace std; template <typename T> void writeMiniVector(const miniVector<T> &v) { for (int x=0; x<v.size(); x++) { cout << v[x] << " "; } } template <typename T> sortMiniVector(miniVector<T> &v) { insertionSort(v); } int main() { miniVector<int> v; randomNumber rnd; for(int x=0; x<15; x++) { v.push_back(rnd.random(100)); } writeMiniVector(v); sortMiniVector(v); cout << endl; writeMiniVector(v); system("pause"); return 0; }
d_random.hCode:#include <iostream> template <typename T> void insertionSort(miniVector<T>& v) { int i, j, n = v.size; T target; for (i=1; i<n; i++) { j=i; target=v[i]; while (j>0 && target<v[j-1]) { v[j]=v[j-1]; j--; } v[j]=target; } }
d_vector.hCode:#include <iostream> #include <time.h> using namespace std; // generate random numbers class randomNumber { public: // initialize the random number generator randomNumber(long s = 0); // return a 32-bit random integer m, 1 <= m <= 2^31-2 long random(); // return a 32-bit random integer m, 0 <= m <= n-1, // where n <= 2^31-1 long random(long n); // return a real number x, 0 <= x < 1 double frandom(); private: static const long A; static const long M; static const long Q; static const long R; long seed; }; const long randomNumber::A = 48271; const long randomNumber::M = 2147483647; const long randomNumber::Q = M / A; const long randomNumber::R = M % A; randomNumber::randomNumber(long s) { if (s < 0) s = 0; if (s == 0) { // get time of day in seconds since 12:00 AM, // January 1, 1970 long t_time = time(NULL); // mix-up bits by squaring t_time *= t_time; // result can overflow. handle cases // > 0, < 0, = 0 if (t_time > 0) s = t_time ^ 0x5EECE66DL; else if (t_time < 0) s = (t_time & 0x7fffffff) ^ 0x5EECE66DL; else s = 0x5EECE66DL; } seed = s; } long randomNumber::random() { long tmpSeed = A * ( seed % Q ) - R * ( seed / Q ); if( tmpSeed >= 0 ) seed = tmpSeed; else seed = tmpSeed + M; return seed; } long randomNumber::random(long n) { double fraction = double(random())/double(M); return int(fraction * n); } double randomNumber::frandom() { return double(random())/double(M); }
Code:#ifndef MINI_VECTOR #define MINI_VECTOR #include "d_except.h" // include exception classes using namespace std; template <typename T> class miniVector { public: miniVector(int size = 0); // constructor. // Postconditions: allocates array with size number of elements // and capacity. elements are initialized to T(), the default // value for type T miniVector(const miniVector<T>& obj); // copy constructor // Postcondition: creates current vector as a copy of obj ~miniVector(); // destructor // Postcondition: the dynamic array is destroyed miniVector& operator= (const miniVector<T>& rhs); // assignment operator. // Postcondition: current vector holds the same data // as rhs T& back(); // return the element at the rear of the vector. // Precondition: the vector is not empty. if vector // is empty, throws the underflowError exception const T& back() const; // const version used when miniVector object is a constant T& operator[] (int i); // provides general access to elements using an index. // Precondition: 0 <= i < vSize. if the index is out // of range, throws the indexRangeError exception const T& operator[] (int i) const; // const version used when miniVector object is a constant void push_back(const T& item); // insert item at the rear of the vector. // Postcondition: the vector size is increased by 1 void pop_back(); // remove element at the rear of the vector. // Precondition: vector is not empty. if the vector is // empty, throws the underflowError exception int size() const; // return current list size bool empty() const; // return true if vector is empty and false otherwise int capacity() const; // return the current capacity of the vector private: int vCapacity; // amount of available space int vSize; // number of elements in the list T *vArr; // the dynamic array void reserve(int n, bool copy); // called by public functions only if n > vCapacity. expands // the vector capacity to n elements, copies the existing // elements to the new space if copy == true, and deletes // the old dynamic array. throws the memoryAllocationError // exception if memory allocation fails }; // set the capacity to n elements template <typename T> void miniVector<T>::reserve(int n, bool copy) { T *newArr; int i; // allocate a new dynamic array with n elements newArr = new T[n]; if (newArr == NULL) throw memoryAllocationError( "miniVector reserve(): memory allocation failure"); // if copy is true, copy elements from the old list to the new list if (copy) for(i = 0; i < vSize; i++) newArr[i] = vArr[i]; // delete original dynamic array. if vArr is NULL, the vector was // originally empty and there is no memory to delete if (vArr != NULL) delete [] vArr; // set vArr to the value newArr. update vCapacity vArr = newArr; vCapacity = n; } // constructor. initialize vSize and vCapacity. // allocate a dynamic array of vSize integers // and initialize the array with T() template <typename T> miniVector<T>::miniVector(int size): vSize(0), vCapacity(0), vArr(NULL) { int i; // if size is 0, vSize/vCapacity are 0 and vArr is NULL. // just return if (size == 0) return; // set capacity to size. since we are building the vector, // copy is false reserve(size, false); // assign size to vSize vSize = size; // copy T() into each vector element for (i=0;i < vSize;i++) vArr[i] = T(); } // copy constructor. make the current object a copy of obj. // for starters, use initialization list to create an empty // vector template <typename T> miniVector<T>::miniVector (const miniVector<T>& obj): vSize(0), vCapacity(0), vArr(NULL) { int i; // if size is 0, vSize/vCapacity are 0 and vArr is NULL. // just return if (obj.vSize == 0) return; // set capacity to obj.vSize. since we are building the vector, // copy is false reserve(obj.vSize, false); // assign size to obj.vSize vSize = obj.vSize; // copy items from the obj.vArr to the newly allocated array for (i = 0; i < vSize; i++) vArr[i] = obj.vArr[i]; } // destructor. deallocate the dynamic array template <typename T> miniVector<T>::~miniVector() { if (vArr != NULL) // de-allocate memory for the array delete [] vArr; } // replace existing object (left-hand operand) by // rhs (right-hand operand) template <typename T> miniVector<T>& miniVector<T>::operator= (const miniVector<T>& rhs) { int i; // check vCapacity to see if a new array must be allocated if (vCapacity < rhs.vSize) // make capacity of current object the size of rhs. don't // do a copy, since we will replace the old values reserve(rhs.vSize, false); // assign current object to have same size as rhs vSize = rhs.vSize; // copy items from rhs.vArr to vArr for (i = 0; i < vSize; i++) vArr[i] = rhs.vArr[i]; return *this; } // check vSize and throw an underflowError exception if the // value is 0; otherwise return the element vArr[vSize-1] template <typename T> T& miniVector<T>::back() { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } template <typename T> const T& miniVector<T>::back() const { if (vSize == 0) throw underflowError( "miniVector back(): vector empty"); return vArr[vSize-1]; } // provides general access to array elements template <typename T> T& miniVector<T>::operator[] (int i) { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; } // provides general access to array elements. constant version template <typename T> const T& miniVector<T>::operator[] (int i) const { if (i < 0 || i >= vSize) throw indexRangeError( "miniVector: index range error", i, vSize); return vArr[i]; } // insure that list has sufficient capacity, // add the new item to the list, and increment vSize template <typename T> void miniVector<T>::push_back(const T& item) { // if space is full, allocate more capacity if (vSize == vCapacity) { if (vCapacity == 0) // if capacity is 0, set capacity to 1. // set copy to false because there are // no existing elements reserve(1,false); else // double the capacity reserve(2 * vCapacity, true); } // add item to the list, update vSize vArr[vSize] = item; vSize++; } // if not empty, just decrement the size template <typename T> void miniVector<T>::pop_back() { if (vSize == 0) throw underflowError( "miniVector pop_back(): vector is empty"); vSize--; } template <typename T> int miniVector<T>::size() const { return vSize; } template <typename T> bool miniVector<T>::empty() const { return vSize == 0; } template <typename T> int miniVector<T>:: capacity() const { return vCapacity; } #endif // MINI_VECTOR


Reply With Quote
Bookmarks