/////////////////////////////////////////////////////////// // Проект Task3_2 /////////////////////////////////////////////////////////// // VectError.h #ifndef _VECT_ERROR_ #define _VECT_ERROR_ #include #define DEBUG class VectError { public: VectError() {} virtual void ErrMsg() const { std::cerr << "Error with Vect object.\n"; } void Continue() const { #ifdef DEBUG std::cerr << "Debug: program is being continued.\n"; #else throw; #endif } }; class VectRangeErr : public VectError { public: VectRangeErr(int _min, int _max, int _actual) : min(_min), max(_max), actual(_actual) {} void ErrMsg() const { std::cerr << "Error of index: "; std::cerr << "possible range: " << min << " - " << max << ", "; std::cerr << "actual index: " << actual << std::endl; Continue(); } private: int min, max; int actual; }; class VectPopErr : public VectError { public: void ErrMsg() const { std::cerr << "Error of pop\n"; Continue(); } }; #endif /* _VECT_ERROR_ */ /////////////////////////////////////////////////////////// // Vect.h #ifndef _VECT_ #define _VECT_ #include #include #include "VectError.h" // Template class Vect template class Vect { public: explicit Vect() : first(0), last(0) {} explicit Vect(size_t _n, const T& _v = T()) { Allocate(_n); for (size_t i = 0; i < _n; ++i) *(first + i) = _v; } Vect(const Vect&); // конструктор копирования Vect& operator =(const Vect&); // операция присваивания ~Vect() { #ifdef DEBUG cout << "Destructor of " << markName << endl; #endif Destroy(); first = 0, last = 0; } // установить отладочное имя void mark(std::string& name) { markName = name; } // получить отладочное имя std::string mark() const { return markName; } size_t size() const; // получить размера вектора T* begin() const { return first; } // получить указатель на 1-й элемент T* end() const { return last; } // получить указатель на элемент, // следующий за последним элементом T& operator[](size_t i); // операция индексирования void insert(T* _P, const T& _x); // вставка элемента в позицию _P void push_back(const T& _x); // вставка элемента в конец вектора void pop_back(); // удаление элемента из конца вектора void show() const; // вывод в cout содержимого вектора protected: void Allocate(size_t _n) { first = new T [_n * sizeof(T)]; last = first + _n; } void Destroy() { for (T* p = first; p != last; ++p) p->~T(); delete [] first; } T* first; // указатель на 1-й элемент T* last; // указатель на элемент, следующий за последним std::string markName; }; // Конструктор копирования template Vect::Vect(const Vect& other) { size_t n = other.size(); Allocate(n); for (size_t i = 0; i < n; ++i) *(first + i) = *(other.first + i); markName = string("Copy of ") + other.markName; #ifdef DEBUG cout << "Copy constructor: " << markName << endl; #endif } // Операция присваивания template Vect& Vect::operator =(const Vect& other) { if (this == &other) return *this; Destroy(); size_t n = other.size(); Allocate(n); for (size_t i = 0; i < n; ++i) *(first + i) = *(other.first + i); return *this; } // Получение размера вектора template size_t Vect::size() const { if (first > last) throw VectError(); return (0 == first ? 0 : last - first); } // Операция доступа по индексу template T& Vect::operator[](size_t i) { if(i < 0 || i > (size() - 1) ) throw VectRangeErr(0, last - first - 1, i); return (*(first + i)); } // Вставка элемента со значением _x в позицию _P template void Vect::insert(T* _P, const T& _x) { size_t n = size() + 1; // новый размер T* new_first = new T [n * sizeof(T)]; T* new_last = new_first + n; size_t offset = _P - first; for (size_t i = 0; i < offset; ++i) *(new_first + i) = *(first + i); *(new_first + offset) = _x; for (i = offset; i < n; ++i) *(new_first + i + 1) = *(first + i); Destroy(); first = new_first; last = new_last; } // Вставка элемента в конец вектора template void Vect::push_back(const T& _x) { if (!size()) { Allocate(1); *first = _x; } else insert(end(), _x); } // Удаление элемента из конца вектора template void Vect::pop_back() { if(last == first) throw VectPopErr(); T* p = end() - 1; p->~T(); last--; } // Вывод в cout содержимого вектора template void Vect::show() const { cout << "\n===== Contents of " << markName << "=====" << endl; size_t n = size(); for (size_t i = 0; i < n; ++i) cout << *(first + i) << " "; cout << endl; } #endif /* _VECT_ */ /////////////////////////////////////////////////////////// // Main.cpp #include "Vect.h" #include #include using namespace std; template void SomeFunction(Vect v) { std::cout << "Reversive output for " << v.mark() << ":" << endl; size_t n = v.size(); for (int i = n - 1; i >= 0; --i) std::cout << v[i] << " "; std::cout << endl; } int main() { try { string initStr[5] = {"first", "second", "third", "fourth", "fifth"}; Vect v1(10); v1.mark(string("v1")); size_t n = v1.size(); for (int i = 0; i < n; ++i) v1[i] = i+1; v1.show(); SomeFunction(v1); try { Vect v2(5); v2.mark(string("v2")); size_t n = v2.size(); for (int i = 0; i < n; ++i) v2[i] = initStr[i]; v2.show(); v2.insert(v2.begin() + 3, "After_third"); v2.show(); cout << v2[6] << endl; v2.push_back("Add_1"); v2.push_back("Add_2"); v2.push_back("Add_3"); v2.show(); v2.pop_back(); v2.pop_back(); v2.show(); } catch (VectError& vre) { vre.ErrMsg(); } try { Vect v3; v3.mark(string("v3")); v3.push_back(41); v3.push_back(42); v3.push_back(43); v3.show(); Vect v4; v4.mark(string("v4")); v4 = v3; v4.show(); v3.pop_back(); v3.pop_back(); v3.pop_back(); v3.pop_back(); v3.show(); } catch (VectError& vre) { vre.ErrMsg(); } } catch (...) { cerr << "Epilogue: error of Main().\n"; } return 0; } //-------------- конец проекта Task3_2 ---------------- //////////////////////////////////////////////////////////