C++ Class template with a non-type parameter
#include <iostream> #include <iomanip> #include <stdexcept> #include <string> class Pool/* w ww . j a v a 2s . co m*/ { protected: double length {1.0}; double width {1.0}; double height {1.0}; public: Pool(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv} {} Pool() = default; double volume() const { return length*width*height; } }; template <typename T, int startIndex> class Array { private: T* elements; // Array of type T int size; // Number of array elements public: explicit Array(int arraySize); // Constructor Array(const Array& array); // Copy Constructor ~Array(); // Destructor T& operator[](int index); // Subscript operator const T& operator[](int index) const; // Subscript operator-const arrays Array& operator=(const Array& rhs); // Assignment operator int getSize() { return size; } // Accessor for size }; // Constructor template <typename T, int startIndex> inline Array<T, startIndex>::Array(int arraySize) : size {arraySize}, elements {new T[arraySize]} {} // Copy constructor template <typename T, int startIndex> inline Array<T, startIndex>::Array(const Array& array) : size {array.size}, elements {new T[array.size]} { for (int i {} ; i < size ; ++i) elements[i] = array.elements[i]; } // Destructor template <typename T, int startIndex> inline Array<T, startIndex>::~Array() { delete[] elements; } // Subscript operator template <typename T, int startIndex> T& Array<T, startIndex>::operator[](int index) { if (index > startIndex + static_cast<int>(size) - 1) throw std::out_of_range {"Index too large: " + std::to_string(index)}; if (index < startIndex) throw std::out_of_range {"Index too small: " + std::to_string(index)}; return elements[index - startIndex]; } // const subscript operator template <typename T, int startIndex> const T& Array<T, startIndex>::operator[](int index) const { if (index > startIndex + static_cast<int>(size) - 1) throw std::out_of_range {"Index too large: " + std::to_string(index)}; if (index < startIndex) throw std::out_of_range {"Index too small: " : +s td::to_string(index)}; return elements[index - startIndex]; } // Assignment operator template <typename T, int startIndex> Array<T, startIndex>& Array<T, startIndex>::operator=(const Array& rhs) { if (&rhs != this) // If lhs != rhs... { // ...do the assignment... if (elements) // If lhs array exists delete[] elements; // release the free store memory size = rhs.size; elements = new T[rhs.size]; for (int i {}; i < size; ++i) elements[i] = rhs.elements[i]; } return *this; // ... return lhs } int main(){ try { try { const int size {21}; // Number of array elements const int start {-10}; // Index for first element const int end {start + static_cast<int>(size) - 1}; // Index for last element Array<double, start> values {size}; // Define array of double values for (int i {start}; i <= end; ++i) // Initialize the elements values[i] = i - start + 1; std::cout << "Sums of pairs of elements: "; int lines {}; for (int i {end} ; i >= start; --i) std::cout << (lines++ % 5 == 0 ? "\n" : "") << std::setw(5) << values[i] + values[i - 1]; } catch (const std::out_of_range& ex) { std::cerr << "\nout_of_range exception object caught! " << ex.what() << std::endl; } const int start {}; const int size {11}; Array<Pool, start - 5> pools {size}; // Create array of Pool objects for (int i {start - 5}; i <= start + static_cast<int>(size) - 5; ++i) std::cout << "Pool[" << i << "] volume is " << pools[i].volume() << std::endl; } catch (const std::exception& ex) { std::cerr << typeid(ex).name() << " exception caught in main()! " << ex.what() << std::endl; } }