【发布时间】:2022-06-12 21:59:12
【问题描述】:
我是第一次学习 unique_ptr,我有这个任务,我想知道是否有人可以就这方面给我建议和信息。
我在这里的人的帮助下实现了矩阵文件。 :)
main.cpp [此文件无法编辑]
#include <iostream>
#include <memory>
#include "matrix.h"
#include "symetric_matrix.h"
using namespace std;
int main()
{
unique_ptr<Matrix<int, 3, 3>> symetric_matrix(new SymetricMatrix<int, 3>(5)); // SymetricMatrix matrix 3*3 with default element equals to 5;
(*symetric_matrix)(1, 2) = 8;
cout << (*symetric_matrix)(1, 2) << " " << (*symetric_matrix)(2, 1) << endl; // Should print "8 8"
cout << (*symetric_matrix)[1][2] << " " << (*symetric_matrix)[2][1] << endl; // Should print "8 8"
(*symetric_matrix)[1][0] = 18;
cout << (*symetric_matrix)[1][0] << " " << (*symetric_matrix)[0][1] << endl; // Should print "18 18"
}
8 的分配应该以矩阵保持不变的方式进行更改。 matrix.h
#include <exception>
template <class T, int M, int N>
class Matrix
{
private:
T mat[M][N];
int rows = M;
int cols = N;
public:
// Error class
class IllegalOperation : public std::exception
{
public:
IllegalOperation(const char *msg) : _msg(msg) {}
virtual const char *what() const throw() { return _msg.c_str(); };
private:
std::string _msg;
};
// constructor
Matrix(int v = 0)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
mat[i][j] = v;
}
}
// Object Constructor
template <class T1, int M1, int N1>
Matrix(const Matrix<T1, M1, N1> &other)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
mat[i][j] = other(i, j);
}
}
// () overloading
T &operator()(int i, int j)
{
return mat[i][j];
}
const T &operator()(int i, int j) const
{
return mat[i][j];
}
// [] overloading
T *operator[](int index)
{
return mat[index];
}
const T *operator[](int index) const
{
return mat[index];
}
// << overloading
friend std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &L)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
os << L.mat[i][j] << " ";
os << "\n";
}
return os;
}
template <class T1, int M1, int N1>
Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other);
template <class T1, int M1, int N1>
const Matrix<T, M, N1> operator*(Matrix<T1, M1, N1> const &other) const;
Matrix<T, M, N> operator+(Matrix<T, M, N> const &other);
Matrix<T, M, N> operator+=(const Matrix<T, M, N> &other);
// scalar
// Matrix<T, M, N> operator*(T);
friend T min(Matrix obj)
{
T result = obj.mat[0][0];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < obj.mat[i][j])
result = obj.mat[i][j];
}
return result;
}
long double avg() const
{
long double result = 0;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < mat[i][j])
result = result + mat[i][j];
}
return result / (M * N);
}
};
template <class T, int M, int N>
Matrix<T, M, N> Matrix<T, M, N>::operator+(Matrix const &other)
{
if ((this->rows == other.rows) && (this->cols == other.cols))
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
auto &valueFirst = this->mat[i][j];
auto &valueSecond = other.mat[i][j];
// if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
// throw std::out_of_range("Resultant value of matrix is out of range");
// else
resultantMatrix(i, j) = valueFirst + valueSecond;
}
}
return resultantMatrix;
}
else
throw IllegalOperation("Matrices cannot be added, sizes do not match");
}
template <class T, int M, int N>
template <class T1, int M1, int N1>
Matrix<T, M, N1> Matrix<T, M, N>::operator*(Matrix<T1, M1, N1> const &other)
{
std::cout << M << " " << N1;
if (N == M1)
{
Matrix<T, M, N1> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
for (auto k = 0; k < this->cols; k++)
{
auto &valueFirst = this->mat[i][k];
auto &valueSecond = other(k, j);
// if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
// throw std::out_of_range("Resultant value of matrix is out of range");
// else
resultantMatrix(i, j) += valueFirst * valueSecond;
}
}
}
return resultantMatrix;
}
else
throw IllegalOperation("Matrices cannot be multipled, sizes not compatible");
}
template <class T, int M, int N>
template <class T1, int M1, int N1>
Matrix<T, M, N1> const Matrix<T, M, N>::operator*(Matrix<T1, M1, N1> const &other) const
{
if (N == M1)
{
Matrix<T, M, N1> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
for (auto k = 0; k < this->cols; k++)
{
auto &valueFirst = this->mat[i][k];
auto &valueSecond = other(k, j);
// if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
// throw std::out_of_range("Resultant value of matrix is out of range");
// else
resultantMatrix(i, j) += valueFirst * valueSecond;
}
}
}
return resultantMatrix;
}
else
throw IllegalOperation("Matrices cannot be multipled, sizes not compatible");
}
template <class T, int M, int N>
Matrix<T, M, N> Matrix<T, M, N>::operator+=(const Matrix<T, M, N> &other)
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < M; i++)
{
for (auto j = 0; j < N; j++)
{
auto valueFirst = other(i, j);
this->mat[i][j] = this->mat[i][j] + valueFirst;
}
}
return resultantMatrix;
}
// scalar m * T
template <class T, int M, int N>
Matrix<T, M, N> operator*(const Matrix<T, M, N> &other, T scalar)
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < M; i++)
{
for (auto j = 0; j < N; j++)
{
auto valueFirst = other(i, j);
if (scalar == 0)
resultantMatrix(i, j) = 0;
// else if ((multiplicationOverflow(valueFirst, scalar)) || (multiplicationUnderflow(valueFirst, scalar)))
// throw std::out_of_range("Resultant value of matrix is out of range");
else
resultantMatrix(i, j) = other(i, j) * scalar;
}
}
return resultantMatrix;
}
// scalar T *m
template <class T, int M, int N>
Matrix<T, M, N> operator*(T scalar, const Matrix<T, M, N> &other)
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < M; i++)
{
for (auto j = 0; j < N; j++)
{
auto valueFirst = other(i, j);
if (scalar == 0)
resultantMatrix(i, j) = 0;
// else if ((multiplicationOverflow(valueFirst, scalar)) || (multiplicationUnderflow(valueFirst, scalar)))
// throw std::out_of_range("Resultant value of matrix is out of range");
else
resultantMatrix(i, j) = other(i, j) * scalar;
}
}
return resultantMatrix;
}
template <class T, int M, int N>
bool operator!=(const Matrix<T, M, N> &other1, const Matrix<T, M, N> &other2)
{
for (auto i = 0; i < M; i++)
{
for (auto j = 0; j < N; j++)
{
auto valueFirst = other1(i, j);
auto valueSecond = other2(i, j);
if (valueFirst != valueSecond)
return true;
}
}
return false;
}
symetric_matrix.h
template <class T, int M>
class SymetricMatrix : public Matrix<T, M, M>
{
private:
T mat[M][M];
public:
SymetricMatrix(int val)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < M; j++)
mat[i][j] = val;
}
}
};
谁能告诉我如何通过symmetric_matrix file 更改矩阵的两个元素而不更改main.cpp 文件。
通过(*symmetric_matrix)(1, 2) = 8; 操作,它应该改变矩阵[1,2] 和矩阵[2,1] 以保持对称。
我必须在其中使用运算符重载吗?由于是指针,我不确定。
代码只改变了它应该改变的矩阵[1,2]。
对于所有看到我在同一个文件上不断提出问题的人,我深表歉意。我正在努力学习,在来这里之前我也在尝试自己的解决方案,直到我陷入困境。
【问题讨论】:
-
很明显,只有
Matrix应该有mat。只有一个,在Matrix。是什么让您相信SymmetricMatrix也需要一个?SymmetricMatrix中的方法必须通过调用Matrix中的方法来实现,才能访问底层矩阵。你的 C++ 教科书中的章节主题是什么,这个练习题来自哪里?为了实现这一点,您应该实现运算符重载。这应该在那里解释。您是否熟悉“运算符重载”的含义? -
只存储矩阵的一部分。访问元素时,请检查,确保第一个索引大于或等于第二个索引,如果不是这种情况,请交换实际访问的元素的索引...您确实需要将
()运算符设为虚拟当然... -
不是已经提到过,您需要虚拟继承,并且至少需要一个
virtual析构函数才能使其正常工作?
标签: c++