diff --git a/include/tmatrix.h b/include/tmatrix.h index a1eaa2cf2..e4aa781f5 100644 --- a/include/tmatrix.h +++ b/include/tmatrix.h @@ -11,91 +11,221 @@ using namespace std; -const int MAX_VECTOR_SIZE = 100000000; -const int MAX_MATRIX_SIZE = 10000; +const int MAX_VECTOR_SIZE = 10000000; +const int MAX_MATRIX_SIZE = 1000; // Динамический вектор - // шаблонный вектор на динамической памяти -template +template // Динамический Вектор class TDynamicVector { protected: - size_t sz; - T* pMem; + size_t sz; // Размер вектора + T* pMem; // (указатель на память) public: TDynamicVector(size_t size = 1) : sz(size) { if (sz == 0) - throw out_of_range("Vector size should be greater than zero"); - pMem = new T[sz]();// {}; // У типа T д.б. констуктор по умолчанию + throw out_of_range("Vector size should be greater than zero"); //Размер вектора должен быть больше нуля + if (sz > MAX_VECTOR_SIZE) + throw out_of_range("Size of the vector is larger than the allowed"); //Размер вектора больше допустимого + pMem = new T[sz]();// {}; // У типа T д.б. констуктор по умолчанию, () - заполнен нулями } TDynamicVector(T* arr, size_t s) : sz(s) { - assert(arr != nullptr && "TDynamicVector ctor requires non-nullptr arg"); - pMem = new T[sz]; + if (sz == 0) + throw out_of_range("Vector size should be greater than zero"); + if (sz > MAX_VECTOR_SIZE) + throw out_of_range("Size of the vector is larger than the allowed"); + + assert(arr != nullptr && "TDynamicVector ctor requires non-nullptr arg"); //Для динамического векторного ctor требуется аргумент non-nullptr (проверка не нулевой ли массив) + pMem = new T[sz];// выделяем память под вектор Т размера sz std::copy(arr, arr + sz, pMem); } - TDynamicVector(const TDynamicVector& v) + TDynamicVector(const TDynamicVector& v)// копирование { + sz = v.sz; + if (v.pMem == nullptr) { //Если v.pMem равно nullptr, это означает, что нет данных для копирования + pMem = nullptr; + } + else { + pMem = new T[sz]; + for (int i = 0; i < sz; i++) + { + pMem[i] = v.pMem[i]; + } + } } - TDynamicVector(TDynamicVector&& v) noexcept + TDynamicVector(TDynamicVector&& v) noexcept // перемещение { - } + sz = v.sz; + pMem = v.pMem; + v.sz = 0; + v.pMem = nullptr; + }//Этот конструктор также принимает ссылку на другой объект TDynamicVector, но в отличие от конструктора копирования, он осуществляет перемещение данных из объекта v в новый объект, вместо их копирования. ~TDynamicVector() { + delete[]pMem;// освобождает память, занятую массивом pMem } - TDynamicVector& operator=(const TDynamicVector& v) + TDynamicVector& operator=(const TDynamicVector& v)//Оператор присваивания копированием { + if (this == &v) { //Проверка, не является ли текущий объект this уже равным объекту v + return *this; + } + if (pMem != nullptr) { //Если массив pMem имеет данные, они удаляются, чтобы освободить память. + delete[]pMem; + } + if (v.pMem == nullptr) { + sz = 0; + pMem = nullptr; + } + else { //Размер и элементы массива копируются из объекта v в текущий объект. + sz = v.sz; + pMem = new T[sz]; + for (int i = 0; i < sz; i++) { + pMem[i] = v.pMem[i]; + } + } + return *this; } - TDynamicVector& operator=(TDynamicVector&& v) noexcept + TDynamicVector& operator=(TDynamicVector&& v) noexcept//Оператор присваивания перемещением { + if (this == &v) { + return *this; + } + if (pMem != nullptr) { + delete[]pMem; + } + if (v.pMem == nullptr) { + sz = 0; + pMem = nullptr; + } + else { //размер и указатель на массив присваиваются из объекта v в текущий объект, а объект v становится недействительным + sz = v.sz; + pMem = v.pMem; + + v.sz = 0; + v.pMem = nullptr; + } + return *this; } - size_t size() const noexcept { return sz; } + size_t size() const noexcept { return sz; }//возвращает размер // индексация T& operator[](size_t ind) { + return pMem[ind];//возвращает ссылку на элемент массива pMem по указанному индексу ind } const T& operator[](size_t ind) const { + return pMem[ind]; } // индексация с контролем T& at(size_t ind) { + if ((ind < 0) || (ind >= sz)) {//выходит за границы + throw "Error"; + } + if (pMem == nullptr) {//массив пуст + throw "Error"; + } + return pMem[ind]; } const T& at(size_t ind) const { + if ((ind < 0) || (ind >= sz)) { + throw "Error"; + } + if (pMem == nullptr) { + throw "Error"; + } + return pMem[ind]; } // сравнение bool operator==(const TDynamicVector& v) const noexcept { + if (sz != v.sz) { + return 0; + } + for (int i = 0; i < sz; i++) { + if (pMem[i] != v.pMem[i]) {//сравнение массивов поэлементно + return 0; + } + } + return 1; } bool operator!=(const TDynamicVector& v) const noexcept { + if (sz != v.sz) { + return 1; + } + for (int i = 0; i < sz; i++) { + if (pMem[i] != v.pMem[i]) { + return 1; + } + } + return 0; } // скалярные операции TDynamicVector operator+(T val) { + TDynamicVector temp(*this); + for (int i = 0; i < sz; i++) { + temp[i] = pMem[i] + val; + } + return temp; } TDynamicVector operator-(T val) { + TDynamicVector temp(*this); + for (int i = 0; i < sz; i++) { + temp[i] = pMem[i] - val; + } + return temp; } TDynamicVector operator*(T val) { + TDynamicVector temp(*this); + for (int i = 0; i < sz; i++) { + temp[i] = pMem[i] * val; + } + return temp; } // векторные операции TDynamicVector operator+(const TDynamicVector& v) { + if (this->sz != v.sz) + throw exception("Error"); + TDynamicVector temp(v); + for (int i = 0; i < sz; i++) { + temp[i] = pMem[i] + v.pMem[i]; + } + return temp; } TDynamicVector operator-(const TDynamicVector& v) { + if (this->sz != v.sz) + throw exception("Error"); + TDynamicVector temp(v); + for (int i = 0; i < sz; i++) { + temp[i] = pMem[i] - v.pMem[i]; + } + return temp; } - T operator*(const TDynamicVector& v) noexcept(noexcept(T())) + T operator*(const TDynamicVector& v) /*noexcept(noexcept(T()))*/ { + if (sz != v.sz) { + throw "Error"; + } + T temp{}; + for (int i = 0; i < sz; i++) { + temp = temp + (pMem[i] * v.pMem[i]); + } + return temp; } friend void swap(TDynamicVector& lhs, TDynamicVector& rhs) noexcept @@ -108,13 +238,13 @@ class TDynamicVector friend istream& operator>>(istream& istr, TDynamicVector& v) { for (size_t i = 0; i < v.sz; i++) - istr >> v.pMem[i]; // требуется оператор>> для типа T + istr >> v.pMem[i]; return istr; } friend ostream& operator<<(ostream& ostr, const TDynamicVector& v) { for (size_t i = 0; i < v.sz; i++) - ostr << v.pMem[i] << ' '; // требуется оператор<< для типа T + ostr << v.pMem[i] << ' '; return ostr; } }; @@ -130,44 +260,114 @@ class TDynamicMatrix : private TDynamicVector> public: TDynamicMatrix(size_t s = 1) : TDynamicVector>(s) { - for (size_t i = 0; i < sz; i++) + if (sz == 0) + throw out_of_range("Vector size should be greater than zero"); //Размер вектора должен быть больше нуля + if (sz > MAX_MATRIX_SIZE) + throw out_of_range("Size of the vector is larger than the allowed"); + for (size_t i = 0; i < sz; i++) pMem[i] = TDynamicVector(sz); } using TDynamicVector>::operator[]; + size_t size() const noexcept { return sz; } + + T& at(int a, int b) + { + if (((a < 0) || (b < 0)) || ((a > sz) || (b > sz))) + throw "Error"; + return pMem[a][b]; + } // сравнение bool operator==(const TDynamicMatrix& m) const noexcept { + if (this->sz != m.sz) + return 0; + for (size_t i = 0; i < sz; i++) + if (pMem[i] != m.pMem[i]) + return 0; + return 1; + } + bool operator!=(const TDynamicMatrix& m) const noexcept + { + if (this->sz != m.sz) + return 1; + for (size_t i = 0; i < sz; i++) + if (pMem[i] != m.pMem[i]) + return 1; + return 0; } // матрично-скалярные операции TDynamicMatrix operator*(const T& val) { + TDynamicMatrix res(*this); + for (size_t i = 0; i < sz; i++) + res.pMem[i] = res.pMem[i] * val; + return res; } // матрично-векторные операции TDynamicVector operator*(const TDynamicVector& v) { + if (sz != v.sz) + throw exception("Error"); + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + res[i] = pMem[i] * v; + return res; } // матрично-матричные операции TDynamicMatrix operator+(const TDynamicMatrix& m) { + if (sz != m.sz) + throw "Error"; + TDynamicMatrix res(*this); + for (size_t i = 0; i < sz; i++) + res.pMem[i] = pMem[i] + m.pMem[i]; + return res; } TDynamicMatrix operator-(const TDynamicMatrix& m) { + if (sz != m.sz) + throw "Error"; + TDynamicMatrix res(*this); + for (size_t i = 0; i < sz; i++) + res.pMem[i] = pMem[i] - m.pMem[i]; + return res; } TDynamicMatrix operator*(const TDynamicMatrix& m) { + if (sz != m.sz) + throw "Error"; + TDynamicMatrix res(*this); + for (size_t i = 0; i < sz; i++) + for (size_t j = 0; j < sz; j++) + for (size_t k = 0; k < sz; k++) + res.pMem[i][j] += pMem[i][k] * m.pMem[k][j]; + return res; } // ввод/вывод friend istream& operator>>(istream& istr, TDynamicMatrix& v) { + for (size_t i = 0; i < v.sz; i++) + for (size_t j = 0; j < v.sz; j++) + istr >> v[i][j]; + return istr; } friend ostream& operator<<(ostream& ostr, const TDynamicMatrix& v) { + for (size_t i = 0; i < v.sz; i++) + { + for (size_t j = 0; j < v.sz; j++) + { + ostr << v[i][j] << " "; + } + ostr << endl; + } + return ostr; } }; diff --git a/sln/gtest.vcxproj b/sln/gtest.vcxproj index f76506bb7..648324eb0 100644 --- a/sln/gtest.vcxproj +++ b/sln/gtest.vcxproj @@ -20,12 +20,12 @@ StaticLibrary Unicode true - v142 + v143 StaticLibrary Unicode - v142 + v143 diff --git a/sln/sample_utmatrix.vcxproj b/sln/sample_utmatrix.vcxproj index 350b55ded..43bfdc51c 100644 --- a/sln/sample_utmatrix.vcxproj +++ b/sln/sample_utmatrix.vcxproj @@ -20,12 +20,12 @@ Application Unicode true - v142 + v143 Application Unicode - v142 + v143 diff --git a/sln/test_utmatrix.vcxproj b/sln/test_utmatrix.vcxproj index efa984f6c..b922602b6 100644 --- a/sln/test_utmatrix.vcxproj +++ b/sln/test_utmatrix.vcxproj @@ -20,12 +20,12 @@ Application Unicode true - v142 + v143 Application Unicode - v142 + v143 diff --git a/test/test_tmatrix.cpp b/test/test_tmatrix.cpp index edaf75ef6..b76659dd0 100644 --- a/test/test_tmatrix.cpp +++ b/test/test_tmatrix.cpp @@ -26,86 +26,140 @@ TEST(TDynamicMatrix, can_create_copied_matrix) TEST(TDynamicMatrix, copied_matrix_is_equal_to_source_one) { - ADD_FAILURE(); + TDynamicMatrix v(11); + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 11; j++) { + v[i][j] = 111; + } + } + TDynamicMatrix k(v); + EXPECT_EQ(v, k); } TEST(TDynamicMatrix, copied_matrix_has_its_own_memory) { - ADD_FAILURE(); + TDynamicMatrix v(11); + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 11; j++) { + v[i][j] = 111; + } + } + TDynamicMatrix k(v); + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 11; j++) { + k[i][j] = 0; + } + } + EXPECT_NE(v, k); } TEST(TDynamicMatrix, can_get_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + EXPECT_EQ(11, v.size()); } TEST(TDynamicMatrix, can_set_and_get_element) { - ADD_FAILURE(); + TDynamicMatrix v(11); + v[7][7] = 7; + EXPECT_EQ(7, v[7][7]); } TEST(TDynamicMatrix, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + TDynamicMatrix v(11); + ASSERT_ANY_THROW(v.at(-1, -1) = 7); } TEST(TDynamicMatrix, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + TDynamicMatrix v(11); + ASSERT_ANY_THROW(v.at(12, 12) = 7); } TEST(TDynamicMatrix, can_assign_matrix_to_itself) { - ADD_FAILURE(); + TDynamicMatrix v(11); + ASSERT_NO_THROW(v = v); } TEST(TDynamicMatrix, can_assign_matrices_of_equal_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix w(11); + EXPECT_EQ(v.size(), w.size()); } TEST(TDynamicMatrix, assign_operator_change_matrix_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(11); + ASSERT_NO_THROW(v = k); } TEST(TDynamicMatrix, can_assign_matrices_of_different_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(12); + ASSERT_NO_THROW(v = k); } TEST(TDynamicMatrix, compare_equal_matrices_return_true) { - ADD_FAILURE(); + TDynamicMatrix v(11); + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 11; j++) { + v[i][j] = 111; + } + } + TDynamicMatrix k(v); + EXPECT_EQ(true, v == k); } TEST(TDynamicMatrix, compare_matrix_with_itself_return_true) { - ADD_FAILURE(); + TDynamicMatrix v(11); + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 11; j++) { + v[i][j] = 111; + } + } + EXPECT_EQ(true, v == v); } TEST(TDynamicMatrix, matrices_with_different_size_are_not_equal) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(12); + EXPECT_NE(v, k); } TEST(TDynamicMatrix, can_add_matrices_with_equal_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(11); + ASSERT_NO_THROW(v + k); } TEST(TDynamicMatrix, cant_add_matrices_with_not_equal_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(12); + ASSERT_ANY_THROW(v + k); } TEST(TDynamicMatrix, can_subtract_matrices_with_equal_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(11); + ASSERT_NO_THROW(v - k); } TEST(TDynamicMatrix, cant_subtract_matrixes_with_not_equal_size) { - ADD_FAILURE(); + TDynamicMatrix v(11); + TDynamicMatrix k(12); + ASSERT_ANY_THROW(v - k); } diff --git a/test/test_tvector.cpp b/test/test_tvector.cpp index 1f7737755..a6dd978d7 100644 --- a/test/test_tvector.cpp +++ b/test/test_tvector.cpp @@ -26,12 +26,25 @@ TEST(TDynamicVector, can_create_copied_vector) TEST(TDynamicVector, copied_vector_is_equal_to_source_one) { - ADD_FAILURE(); + TDynamicVector v(11); + for (int i = 0; i < 11; i++) { + v[i] = i; + } + TDynamicVector k(v); + EXPECT_EQ(v, k); } TEST(TDynamicVector, copied_vector_has_its_own_memory) { - ADD_FAILURE(); + TDynamicVector v(11); + for (int i = 0; i < 11; i++) { + v[i] = i; + } + TDynamicVector k(v); + for (int i = 0; i < 11; i++) { + v[i] += i; + } + EXPECT_NE(v, k); } TEST(TDynamicVector, can_get_size) @@ -51,91 +64,120 @@ TEST(TDynamicVector, can_get_size) TEST(TDynamicVector, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_ANY_THROW(v.at(-1)); } TEST(TDynamicVector, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_ANY_THROW(v.at(12)); } TEST(TDynamicVector, can_assign_vector_to_itself) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_NO_THROW(v = v); } TEST(TDynamicVector, can_assign_vectors_of_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(11); + EXPECT_EQ(k.size(), v.size()); } TEST(TDynamicVector, assign_operator_change_vector_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(11); + ASSERT_NO_THROW(v = k); } TEST(TDynamicVector, can_assign_vectors_of_different_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(12); + EXPECT_NE(k.size(), v.size()); } TEST(TDynamicVector, compare_equal_vectors_return_true) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(v); + EXPECT_EQ(true, k == v); } TEST(TDynamicVector, compare_vector_with_itself_return_true) { - ADD_FAILURE(); + TDynamicVector v(11); + EXPECT_EQ(true, v == v); } TEST(TDynamicVector, vectors_with_different_size_are_not_equal) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(12); + EXPECT_NE(k.size(), v.size()); } TEST(TDynamicVector, can_add_scalar_to_vector) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_NO_THROW(v + 11); } TEST(TDynamicVector, can_subtract_scalar_from_vector) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_NO_THROW(v - 7); } TEST(TDynamicVector, can_multiply_scalar_by_vector) { - ADD_FAILURE(); + TDynamicVector v(11); + ASSERT_NO_THROW(v * 7); } TEST(TDynamicVector, can_add_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(11); + ASSERT_NO_THROW(v + k); } TEST(TDynamicVector, cant_add_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(12); + ASSERT_ANY_THROW(v + k); } TEST(TDynamicVector, can_subtract_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(11); + ASSERT_NO_THROW(v - k); } TEST(TDynamicVector, cant_subtract_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(12); + ASSERT_ANY_THROW(v - k); } TEST(TDynamicVector, can_multiply_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(11); + ASSERT_NO_THROW(v * k); } TEST(TDynamicVector, cant_multiply_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v(11); + TDynamicVector k(12); + ASSERT_ANY_THROW(v * k); }