重载运算符C++:Object=Object*Object

Overloaded operator C++: Object = Object * Object

本文关键字:Object 运算符 C++ 重载      更新时间:2023-10-16

我在使用重载的*运算符相乘对象时遇到问题

在类中,我将运算符定义为:

const Matrix operator*(Matrix& B);

实现是

const Matrix Matrix::operator* (Matrix& B){
   Matrix r = Matrix(B.M,B.N);
   for(int i = 0; i < r.M; i++){
       for(int j = 0; j < r.N; j++){
        r.data[i*N+j] = (*this)(i,j) * (int)B(i,j);
       }
   }
   return r;
}

当我呼叫时

 Matrix C = A * B

我会得到预期的结果,但调用

C = C * C

导致错误。

我猜这是为了调用对象C,但我不知道该怎么办!

编辑:

我的任务操作员。矩阵R是一个深度复制。

Matrix Matrix::operator=(Matrix& B){
Matrix r(M,N);
for(int i = 0; i < M; i++){
    for(int j = 0; j < N; j++){
        r.data[i*N+j] = B(i,j);                                 
    }
}
return r;

}

错误是因为您将数据存储在一个名为"data"的变量中(该变量是堆上的int[]),并且您没有重写赋值运算符以将要复制的对象中的值复制到当前成员变量"data"中。因此,默认赋值运算符将为您复制"数据"指针,在您的情况下,该指针来自赋值后将超出范围的临时值。您的析构函数很可能会删除您现在指向的"data"变量,因为临时变量超出了范围。

您已经定义了自己的复制构造函数来在堆上建立"data"变量。在第一个例子中,矩阵C=A*B将使用复制构造函数,这是有效的。

第二个示例使用默认赋值运算符,该运算符将只复制操作返回的临时值中的数据指针。因此,您基本上没有数据指向的值

您必须定义一个赋值运算符才能使其工作。

以下是建议与您的复制构造函数配合使用的函数:

void Matrix::swap(Matrix& other)
{
   std::swap(M, other.M);
   std::swap(N, other.N);
   std::swap(data, other.data);
}
Matrix& Matrix::operator= (Matrix matrix)
{
   swap(matrix);
   return *this;
}
Matrix Matrix::operator* (const Matrix& B)
{
   Matrix r = Matrix(B.M,B.N);
   for(int i = 0; i < r.M; i++){
       for(int j = 0; j < r.N; j++){
        r.data[i*N+j] = (*this)(i,j) * (int)B(i,j);
       }
   }
   return r;
}

这很有效,因为复制构造函数将用于赋值运算符(operator=)中的"matrix"。然后,交换函数将用矩阵的临时副本来交换"数据"数组。因此,您将从操作*的临时变量中复制适当的"数据"。

这与"调用对象C"无关。

第一个版本

Matrix C = A * B;

使用构造函数或类Matrix初始化新对象C

第二版

C = C * C;

使用类Matrix赋值运算符为现有对象C赋值。

您设法以某种方式搞砸了赋值运算符声明/实现(在发布的代码中没有显示),这就是为什么第二个版本没有编译的原因。

您的operator *声明也存在问题。即使你想让它作为类成员,一种更有意义的声明方式是

Matrix Matrix::operator* (const Matrix& B) const {
  ...

请注意const限定符的放置方式。

编辑:所以,这是您的问题。你的作业操作员完全崩溃了。

首先,您宣布您的分配操作员为

Matrix Matrix::operator=(Matrix& B)

此运算符无法接受右侧的临时对象,因为您未能将参数声明为const。非常量引用不能绑定到临时对象。在C = C * C中,赋值的右侧实际上是由*运算符产生的临时对象。

将您的分配操作员重新声明为

Matrix &Matrix::operator=(const Matrix& B)

注意,它接受const引用并返回一个引用。

其次,您的赋值操作符应该赋值给*this,而不是一些独立的临时对象。并且它应该返回对*this的引用。换句话说,实现应该是类似的东西

Matrix &Matrix::operator=(const Matrix& B){
  // Resize `*this` to match the size of `B`
  for(int i = 0; i < M; i++){
    for(int j = 0; j < N; j++){
        this->data[i*N+j] = B(i,j);                                 
    }
  }
  return r;
}

尝试定义如下运算符:

Matrix operator* (const Matrix& x, const Matrix& y)
{
    //...
}