我做了一个矩阵类。这是它的一部分。
Math::Matrix::Matrix(int row, int col, double * mat)
{
this->mat = new double[(this->row = row) * (this->col = col)];
for (int i = 0; i < row * col; i++)
{
this->mat[i] = mat[i];
}
}
Math::Matrix::~Matrix()
{
if (this->mat != nullptr)
{
delete[] this->mat;
}
}
const Math::Matrix Math::Matrix::multiply(Matrix & A) const
{
if (!this->is_multipliable(A))
{
throw new std::exception("Math::Matrix::multiply : cannot multiply!");
}
Matrix B = Matrix(this->row, A.col);
for (int k = 0; k < this->col; k++)
{
for (int i = 0; i < this->row; i++)
{
for (int j = 0; j < A.col; j++)
{
B.mat[i * A.col + j] = this->mat[i * this->col + k] * A.mat[k * A.col + j];
}
}
}
return B;
}
std::ostream & Math::operator<<(std::ostream & os, const Matrix & m)
{
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
os << m.mat[i*m.col + j] << ' ';
}
os << '\n';
}
return os;
}
这是我写的矩阵类的一部分,当我尝试的时候
int main()
{
A = Math::Matrix(2, 3, new double[6]{ 1, 2, 3, 4, 5, 6 });
B = Math::Matrix(3, 4, new double[12]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 });
std::cout << A << std::endl;
std::cout << B << std::endl;
std::cout << A.multiply(B) << std::endl;
}
在main中,程序会输出一些愚蠢的数字,比如
-1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 1.07458e-255 3.02386e-294 1.41763e-311
2.122e-314 -7.84591e+298 -1.45684e+144 1.87482e-310
2.9803e-294 -1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
(不调试)
或
1 2 3
4 5 6
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
3.67842e-293 8.81477e-310 3.6647e-293 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
-1.45682e+144 -1.45682e+144 -1.45682e+144 -1.45682e+144
(调试)
然后抛出异常。
在 Debug模式下,它表示“wntdll.pdb 包含查找模块 ntdll.dll 源代码所需的调试信息”。
我使用的是 visual studio 2017。
这段代码似乎有什么问题?
最佳答案
让我们猜测一下您是如何定义 Matrix
的,然后将其重写为默认情况下正确。
namespace Math {
class Matrix {
double * mat; // Bad. Owning raw pointer
int col, row; // Questionable. std::size_t is the normal type for an index
public:
Matrix(int row, int col, double * mat); // Bad. Owning raw pointer
~Matrix(); // Will be un-necessary under the rule of 0
const Matrix multiply(Matrix & A) const; // this is usually named "operator *"
friend std::ostream & operator<<(std::ostream & os, const Matrix & m); // Good
};
}
这是我们整理的方式
namespace Math {
class Matrix {
std::vector<double> mat;
std::size_t col, row;
public:
Matrix(std::size_t row, std::size_t col)
: row(row), col(col), mat(row * col, 0)
{}
template <typename InputIterator>
Matrix(std::size_t row, std::size_t col, InputIterator it) // copy from any sequence of doubles
: Matrix(row, col) // delegate to 2-arg constructor to initialises fields
{
std::copy_n(it, row * col, mat.begin());
}
double & data(std::size_t c, std::size_t r) // Convinience
{ return mat[(r * col) + c]; }
double data(std::size_t c, std::size_t r) const // Overload for const
{ return mat[(r * col) + c]; }
friend Matrix operator*(const Matrix & lhs, const Matrix & rhs)
{
if (!lhs.is_multipliable(rhs))
{
// MSVC includes this as a non-standard extension
// std::runtime_error is a portable replacement
throw new std::exception("Math::Matrix::multiply : cannot multiply!");
}
Matrix result = Matrix(lhs.row, rhs.col);
for (int k = 0; k < lhs.col; k++)
{
for (int i = 0; i < lhs.row; i++)
{
for (int j = 0; j < rhs.col; j++)
{
result.data(i, j) += lhs.data(i, k) * rhs.data(k, j);
}
}
}
return result;
}
friend std::ostream & operator<<(std::ostream & os, const Matrix & m);
friend std::istream & operator>>(std::istream & is, Matrix & m);
};
}
请注意,std::exception
未定义为具有 const char *
accepting constructor
关于c++ - 使用 operator<< 并打印错误值的类的程序 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50412616/