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

时间:2013-12-12 18:13:10

标签: c++ object overloading operator-keyword

我无法使用重载*运算符

来对象进行乘法运算

在课程中我将操作符定义为:

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有关,但我不知道该怎么做!

编辑:

我的任务操作员。 Matrix 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;

}

3 个答案:

答案 0 :(得分:2)

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

您已经定义了自己的复制构造函数,以在堆上建立“data”变量。 Matrix 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的临时副本进行交换。因此,您将从operation *的临时变量中复制相应的“数据”。

答案 1 :(得分:1)

这与“调用对象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。非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;
}

答案 2 :(得分:0)

尝试像这样定义运算符:

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