复制构造函数和赋值运算符有问题。编写了多个matricies的代码:
Matrix& Matrix::operator * (const Matrix &second) const
{
// Create result matrix
Matrix result(Rows(), second.Columns());
// Multiply matricies
for (unsigned i = 0; i < Rows(); i++)
{
for (unsigned j = 0; j < second.Columns(); j++)
{
result[i][j] = 0.0;
for (unsigned k = 0; k < Columns(); k++)
{
result[i][j] += m_matrix[i][k] * second[k][j];
}
}
}
return result;
}
在主要代码中,我给操作员打电话:
Matrix C = A * B;
但是代码在赋值之前会破坏结果变量,如何正确编写这样的代码来返回结果矩阵?复制构造函数是:
Matrix::Matrix(const Matrix& matrix)
{
AllocateMatrixArray(matrix.Rows(), matrix.Columns());
CopyMatrixData(matrix);
}
作业运算符是:
Matrix& Matrix::operator = (const Matrix& other)
{
AllocateMatrixArray(other.Rows(), other.Columns());
CopyMatrixData(other);
return *this;
}
但是我看到编译器没有使用它 - 复制构造函数就足够了。
答案 0 :(得分:1)
您不应该返回对局部变量的引用。按惯例,opertor*
(我的意思是当然是两个参数版本)会向结果返回副本。对于operator+
,operator-
等其他操作也是如此。这些运算符的移动版本会返回引用,例如operator *=
,operator +=
等。
答案 1 :(得分:1)
您的代码返回对局部变量的引用,该变量将在函数范围的末尾被销毁。不要这样做:
Matrix Matrix::operator * (const Matrix &second) const {
// same as above
}
请注意,返回值现在是Matrix
而不是Matrix&
。
答案 2 :(得分:1)
如果你想写C = A * B这样的表达式,所有C A和B必须是&#34;值&#34;。
因此operator*
的返回值必须为matrix
而不是matrix&
,如果&
引用局部变量(如result
),则为espscialy将在}
被销毁(因此在执行之前)。
尽管如此,还有一些问题:
示例Matrix C = A*B
不是作业:分配发生后,已存在的对象的值发生了变化。但是Matrix C是在上下文中创建的:事实上,这里所谓的是Matrix
构造函数(在这种情况下是复制构造函数)
可能存在内存泄漏:虽然我不知道如何处理矩阵数据,但operator=
似乎分配新空间然后复制其中的数据。但是包含旧数据的空间会发生什么?它是否仍然被遗忘?是否由智能指针自动释放?
同样,就像=
应该忽略旧数据一样,类本身也应该在销毁时忽略自己的数据,因此也应该实现析构函数。否则每次关闭Matrix时(如本地result
),其数据都会保留。