简而言之,我被赋予了创建一个动态分配内存以形成int值矩阵的类的任务。
该类的一部分是执行基本矩阵计算的成员函数 - 加法,减法和乘法。所有东西都编译(至少在我的末尾),但是当我使用驱动程序来测试乘法部分时,它会一直崩溃。
我正在使用Codeblocks作为我的IDE,并且试图弄清楚调试器没有太多运气。似乎计算完成了(具有正确的值),但事情在某处发生了可怕的错误。
为清楚起见,Matrix类的每个对象都有以下成员数据:
private:
int rows;
int cols;
int **element;
下面是实现文件的片段,其中重载的运算符*被充实。在执行乘法的循环之前temp.element [i] [x]被设置为'0'的部分被注释掉了,因为默认构造函数已经将所有值都设置为'0' - 当我把它放入时我忘记了本来。当我没有注释掉它时它没有用。
在测试中,我使用了一个2x3阵列和一个3x2阵列。
Matrix Matrix::operator*(const Matrix &aMatrix) const
{
if(cols == aMatrix.rows)
{
Matrix temp(rows, aMatrix.cols);
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < aMatrix.cols; x++)
{
//temp.element[i][x] = 0;
for(int n = 0; n < cols; n++)
{
temp.element[i][x] += (element[i][n]
* aMatrix.element[n][x]);
}
}
}
return temp;
}
else
{
cerr << "Matrix multiplication failed -- incompatible matrix sizes."
<< endl;
return *this;
}
}
在尝试查看代码并发现错误时,我开始重新检查我的其他功能。似乎加法和减法都有效,但如果矩阵不相容(即尝试添加2x3和4x4),程序将关闭。
下面是添加的片段(在最终循环中,减法几乎相同' - '而不是'+'。
Matrix Matrix::operator+(const Matrix &aMatrix) const
{
if(rows == aMatrix.rows && cols == aMatrix.cols)
{
Matrix temp(rows, cols);
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < cols; x++)
{
temp.element[i][x] = element[i][x] + aMatrix.element[i][x];
}
}
return temp;
}
else
{
cerr << "Undefined matrix addition -- matrices are different sizes."
<< endl;
return *this;
}
}
感谢任何帮助或见解。感谢。
已编辑:添加了重载的赋值运算符,复制构造函数和析构函数代码。
下面是重载的赋值运算符:
Matrix Matrix::operator=(Matrix aMatrix)
{
if(this != &aMatrix)
{
for(int i = 0; i < rows; i++)
{
delete [] element[i];
element[i] = NULL;
}
delete [] element;
rows = aMatrix.rows;
cols = aMatrix.cols;
element = new int* [rows];
for(int i = 0; i < rows; i++)
{
element[i] = new int [cols];
for (int x = 0; x < cols; x++)
{
element[i][x] = aMatrix.element[i][x];
}
}
}
return *this;
}
下面是复制构造函数:
Matrix::Matrix(const Matrix &aMatrix)
{
rows = aMatrix.rows;
cols = aMatrix.cols;
element = new int* [rows];
for(int i = 0; i < rows; i++)
{
element[i] = new int [cols];
for (int x = 0; x < cols; x++)
{
element[i][x] = aMatrix.element[i][x];
}
}
}
析构函数:
Matrix::~Matrix()
{
for(int i = 0; i < rows; i++)
{
delete [] element[i];
element[i] = NULL:
}
delete [] element;
element = NULL;
}
答案 0 :(得分:0)
您需要弄清楚这些操作的语法和语义。从你的例子看起来好像你想要的东西:
Matrix lhs = <something>;
Matrix rhs = <something>;
Matrix result = lhs * rhs;
到&#34;只是工作&#34;。虽然这在语法上可能很好,但您需要考虑如果lhs和rhs不能相乘(或添加等)会发生什么。您还需要担心正确设置结果。你不能只返回一个由多个行,列和一组指针组成的结构&#34;并期望不会遇到可怕的内存管理问题。
使产品消失的原因是什么?什么时候超出范围? C ++不是一个非常好的线性代数语言。
您需要做的第一个决定是,您是否打算为无效操作抛出异常,或者返回一些错误的指示,可能是bool和const char *来显示错误消息。
然后你可能应该尝试编写一个带有结果引用和2个操作数引用的函数,如果矩阵支持该操作,则只需要正确的基本代数。 (我还没有提到你的Matrix只是一个整数矩阵。)
在&#34;现实生活&#34;中,您可能会尝试找到管理所有这些的开源标准解决方案,因为需要非常小心地管理数值运算。
有人甚至可能认为这是几十年前在Fortran中已经解决的问题,直到今天,如果性能成为一个问题,那么潜在的计算很可能是在Fortran中,或者是来自C的端口的库。
答案 1 :(得分:0)
您发布了一个复制构造函数和赋值运算符。您的任务操作员有4个主要问题:
new
在分配期间抛出异常,则您通过事先删除内存来搞乱对象。您可以根据复制构造函数重写赋值运算符并缓解这些问题:
#include <algorithm>
//...
Matrix& Matrix::operator=(const Matrix& aMatrix)
{
Matrix temp(aMatrix);
swap(*this, temp);
return *this;
}
void Matrix::swap(Matrix& left, Matrix& right)
{
std::swap(left.rows, right.rows);
std::swap(left.cols, right.cols);
std::swap(left.element, right.element);
}
您只需将swap
函数添加到Matrix类(可能作为private
)函数。
上面的代码使用了copy/swap
成语,并缓解了我提到的所有问题。如果正确编写了复制构造函数和析构函数,这将起作用。关于这个习惯用法有很多线索,但基本上发生的事情就是:
从传入的对象创建临时对象。如果new
投掷出现问题,则this
不会搞砸。
与临时成员交换this
个成员。这将使用临时数据刷新this
对象,并为临时提供我们不再需要的旧数据。
让临时骰子用我们从this
给出的旧东西。
返回this
。
至于其他方面,如果两个矩阵不能相乘,那么就抛出异常。不要返回虚假或混淆的Matrix对象,而这些对象并不能真正反映发生的事情。
此外,您应首先编写运算符+=
和*=
。为什么?因为实施运算符+
和*
分别可以+=
和*=
加上,所以加上+=
和{{ 1}}可用。
例如:
*=
因此,如果Matrix大小是个问题,operator +和+ =将抛出异常。请注意运算符Matrix& Matrix::operator+=(const Matrix &aMatrix)
{
if(rows != aMatrix.rows || cols != aMatrix.cols)
throw SomeException;
for(int i = 0; i < rows; i++)
{
for(int x = 0; x < cols; x++)
element[i][x] += aMatrix.element[i][x];
}
return *this;
}
Matrix Matrix::operator+(const Matrix &aMatrix)
{
Matrix temp(*this);
temp += aMatrix;
return temp;
}
如何按+
实现。采用与+=
,*
以及*=
和-
相同的方法。