Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Arsentiev_vectormatrix_210518.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include "windows.h"
- #include <iostream>
- template<typename T> // Шаблонный класс Matrix параметризуется типом данных, из которых состоит матрица - int (матрица целых), double (матрица вещественных) и т.д.
- class Matrix
- {
- private:
- T** matrix_; // указатель на матрицу, далее число строк и число столбцов. Они задаются пользователем в конструкторе Matrix.
- int rows_;
- int columns_;
- public:
- /* : rows_(... - Это список инициализации объекта. Он состоит из двух полей -
- * rows_ и columns_. Оба инициализируются аргументами конструктора,
- * которые передает пользователь. Это происходит до выполнения тела конструктора.
- */
- Matrix<T>(int _rows, int _columns)
- : rows_(_rows), columns_(_columns)
- {
- matrix_ = new T*[_rows];
- for (int i = 0; i < _rows; i++)
- {
- matrix_[i] = new T[_columns];
- }
- }
- /* Это обёртки для доступа к числу полей и столбцов. */
- int getRows()
- {
- return rows_;
- }
- int getColumns()
- {
- return columns_;
- }
- /* Для доступа к элементам перегружается не operator[], а operator(). Это безопаснее, поскольку матрица не
- * выдает свои строки как промежуточный результат, а позволяет обращаться только к числам по отдельности.
- * Возвращается не значение результата, а ссылка на него - так можно и читать ячейку, и записывать в нее.
- */
- T& operator()(int _row, int _column)
- {
- return matrix_[_row][_column];
- }
- /* Для всех Matrix<T>& operator'ов: */
- Matrix<T>& operator-(T _arg)
- {
- /* Если матрица-результат в результате операции не меняется, вернуть исходную матрицу.*/
- if (_arg == 0)
- {
- return *this;
- }
- /* Иначе создаем матрицу-результат, той же размерности что исходная. */
- Matrix<T>* result = new Matrix<T>(getRows(), getColumns());
- for (int i = 0; i < getRows(); i++)
- {
- for (int j = 0; j < getColumns(); j++)
- {
- /* result и this - указатели. Нужно разыменовать их, чтобы к получившимся объектам
- * типа Matrix можно было применить operator(). Это обыкновенное разыменование, this
- * окружен скобками только чтобы оно выполнялось раньше operator().
- */
- (*result)(i, j) = (*this)(i, j) - _arg;
- }
- }
- return *result;
- }
- Matrix<T>& operator+(T _arg)
- {
- if (_arg == 0)
- {
- return *this;
- }
- Matrix<T>* result = new Matrix<T>(getRows(), getColumns());
- for (int i = 0; i < getRows(); i++)
- {
- for (int j = 0; j < getColumns(); j++)
- {
- (*result)(i, j) = (*this)(i, j) + _arg;
- }
- }
- return *result;
- }
- Matrix<T>& operator*(T _arg)
- {
- if (_arg == 1)
- {
- return *this;
- }
- Matrix<T>* result = new Matrix<T>(getRows(), getColumns());
- for (int i = 0; i < getRows(); i++)
- {
- for (int j = 0; j < getColumns(); j++)
- {
- (*result)(i, j) = (*this)(i, j) * _arg;
- }
- }
- return *result;
- }
- };
- template<typename T> // Шаблонный класс Vector параметризуется типом данных, из которых состоит вектор - int (вектор целых), double (вектор вещественных) и т.д.
- class Vector
- {
- private:
- T* vector_;
- int size_;
- public:
- Vector<T>(int _size)
- : size_(_size) // Это список инициализации объекта. Он состоит из одного поля - поле size_ инициализируется параметром конструктора Vector.
- {
- vector_ = new T[_size];
- }
- /* Это обёртка для доступа к числу элементов. */
- int getSize()
- {
- return size_;
- }
- /* См. Matrix::operator().
- */
- T& operator()(int _row)
- {
- return vector_[_row];
- }
- /* Функция умножения вектора на матрицу. Возвращает вектор той же размерности,
- * являющийся произведением, или вектор нулевой размерности, если умножение невозможно
- */
- Vector<T>& mult(Matrix<T>& _matrix)
- {
- if (size_ != _matrix.getRows())
- {
- return *(new Vector<T>(0));
- }
- Vector<T>* result = new Vector<T>(size_);
- for (int i = 0; i < _matrix.getRows(); i++)
- {
- T buffer = 0;
- for (int j = 0; j < _matrix.getColumns(); j++)
- {
- buffer += _matrix(i, j) * (*this)(j);
- }
- (*result)(i) = buffer;
- }
- return *result;
- }
- /* Это дружественная классу Vector функция умножения. Она не принадлежит классу Vector,
- * но имеет доступ к его закрытым полям.
- * Возвращает вектор той же размерности,
- * являющийся произведением, или вектор нулевой размерности, если умножение невозможно
- */
- friend Vector<T>& multVectorAndMatrix(Vector<T>& _vector, Matrix<T>& _matrix)
- {
- /* Дружественной классу Vector функции не нужно вызывать Vector::getSize(). Она обращается
- * к закрытому полю size_ напрямую.
- */
- if (_vector.size_ != _matrix.getRows())
- {
- return *(new Vector<T>(0));
- }
- Vector<T>* result = new Vector<T>(_vector.size_);
- for (int i = 0; i < _matrix.getRows(); i++)
- {
- T buffer = 0;
- for (int j = 0; j < _matrix.getColumns(); j++)
- {
- buffer += _matrix(i, j) * _vector(j);
- }
- (*result)(i) = buffer;
- }
- return *result;
- }
- /** ДЛЯ ВСЕХ Vector<T>& operator'ов */
- Vector<T>& operator*(T _arg)
- {
- /* Если вектор-результат после умножения не отличается от исходного,
- * то не создавать новый вектор, а вернуть исходный.
- */
- if (_arg == 1)
- {
- return *this;
- }
- /* Создание нового вектора и умножение. Возвращается ссылка на новый вектор.*/
- Vector<T>* result = new Vector<T>(size_);
- for (int i = 0; i < size_; i++)
- {
- /* Разыменовывается указатель на новый вектор, затем вызывается operator(),
- * элементу нового вектора присваивается произведение.
- * this - тоже указатель, и его тоже надо разыменовать перед тем как вызывать operator().
- */
- (*result)(i) = (*this)(i) * _arg;
- }
- return *result;
- }
- Vector<T>& operator+(T _arg)
- {
- if (_arg == 0)
- {
- return *this;
- }
- Vector<T>* result = new Vector<T>(size_);
- for (int i = 0; i < size_; i++)
- {
- (*result)(i) = (*this)(i) + _arg;
- }
- return *result;
- }
- Vector<T>& operator-(T _arg)
- {
- if (_arg == 0)
- {
- return *this;
- }
- Vector<T>* result = new Vector<T>(size_);
- for (int i = 0; i < size_; i++)
- {
- (*result)(i) = (*this)(i) - _arg;
- }
- return *result;
- }
- };
- template<typename T>
- std::ostream& operator<< (std::ostream& _stream, Matrix<T>& _matrix)
- {
- for (int i = 0; i < _matrix.getRows(); i++)
- {
- for (int j = 0; j < _matrix.getColumns(); j++)
- {
- _stream << _matrix(i, j) << ' ';
- }
- _stream << std::endl;
- }
- return _stream;
- }
- template<typename T>
- std::ostream& operator<< (std::ostream& _stream, Vector<T>& _vector)
- {
- for (int i = 0; i < _vector.getSize(); i++)
- {
- _stream << _vector(i) << ' ';
- }
- _stream << std::endl;
- return _stream;
- }
- template<typename T>
- std::istream& operator>> (std::istream& _stream, Matrix<T>& _matrix)
- {
- for (int i = 0; i < _matrix.getRows(); i++)
- {
- for (int j = 0; j < _matrix.getColumns(); j++)
- {
- _stream >> _matrix(i, j);
- }
- }
- return _stream;
- }
- template<typename T>
- std::istream& operator>> (std::istream& _stream, Vector<T>& _vector)
- {
- for (int i = 0; i < _vector.getSize(); i++)
- {
- _stream >> _vector(i);
- }
- return _stream;
- }
- int main()
- {
- Matrix<double> matr(3, 3);
- Vector<double> vect(3);
- std::cout << "Fill the matrix(" << matr.getRows() << ", " << matr.getColumns() << "):" << std::endl;
- std::cin >> matr;
- std::cout << "Fill the vector(" << vect.getSize() << "):" << std::endl;
- std::cin >> vect;
- std::cout << (matr * 2 + 3);
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement