矩阵乘法后的赋值运算符和复制构造函数

时间:2013-01-25 15:04:50

标签: c++ constructor copy-constructor

复制构造函数和赋值运算符有问题。编写了多个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;
}

但是我看到编译器没有使用它 - 复制构造函数就足够了。

3 个答案:

答案 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),其数据都会保留。