【问题标题】:Overloading the multiplication operator in c++在 C++ 中重载乘法运算符
【发布时间】:2015-02-17 15:30:18
【问题描述】:

我已经为 LAPACK 编写了一个 C++ 接口,但我遇到了一些内存问题,这让我重新考虑了一些运算符重载。

现在,我在类定义之外重载了 operator*(但作为 Matrix 类的朋友),它接受两个 Matrix 对象,分配第三个具有适当尺寸的对象,使用 D(GE/SY)MM计算乘积(存储到新分配的矩阵的内部存储中),然后返回指向该新矩阵的指针。即。

class Matrix {
...
friend Matrix* operator*(const Matrix&, const Matrix&);
...
}

Matrix* operator*(const Matrix& m1, const Matrix& m2) {
  Matrix *prod = new Matrix(m1.rows_, m2.cols_);
  if(m1.cols_!=m2.rows_) {
    throw 3008;
  } else {
    double alpha = 1.0;
    double beta = 0.0;
    if(m1.symm_=='G' && m2.symm_=='G'){
      dgemm_(&m1.trans_,&m2.trans_,&m1.rows_,&m2.cols_,&m1.cols_,&alpha,m1.data_,
             &m1.rows_,m2.data_,&m1.cols_,&beta,prod->data_,&m2.cols_);
    } else if(m1.symm_=='S'){
      char SIDE = 'L';
      char UPLO = 'L';
      dsymm_(&SIDE,&UPLO,&m1.rows_,&m2.cols_,&alpha,m1.data_,&m1.rows_,m2.data_,
             &m2.cols_,&beta,prod->data_,&m2.cols_);
    } else if(m2.symm_=='S'){
      char SIDE = 'R';
      char UPLO = 'L';
      dsymm_(&SIDE,&UPLO,&m2.rows_,&m1.cols_,&alpha,m2.data_,&m2.rows_,m1.data_,
             &m1.cols_,&beta,prod->data_,&m1.cols_);
    };
  }
  return prod;
};

那我利用

Matrix *A, *B, *C;
// def of A and B
C = (*A)*(*B);

这很好用。我遇到的问题是每次执行此操作时都必须分配一个新矩阵。我想做的是分配一次C 矩阵并将AB 的乘积放入C (C->data_) 的内部存储中。根据我在运算符重载方面的发现,我找不到一个很好的方法来做到这一点。我知道我可以使用成员函数来执行此操作(即C->mult(A,B)),但如果可能的话,我想避免这种情况(我正在编写此代码以方便非 CSE 类型的开发)。任何想法将不胜感激。

【问题讨论】:

  • 返回 Matrix 而不是 Matrix*
  • 你这样做完全错了。 operator* 应该返回 Matrix,而不是 Matrix*。如果您担心效率,请查看move assignment operator

标签: c++ matrix operator-overloading member-functions non-member-functions


【解决方案1】:
class Matrix
{

    struct Product
    {
        const Matrix* a; 
        const Matrix* b;
    };

    Matrix& operator = (const Product& p)
    {
        // if this matrix dims differ from required by product of p.a and p.b
        // reallocate it first and set dims
        // {     
            // rows = ....; cols = ....;
            // delete [] data; 
            // data = new [rows*cols];
        // }


        // then calculate product
        // data[0] = ...;
        // ...

        return *this;

    }

    Product operator * (const Matrix& op) const
    {
        Product p;
        p.a = this;
        p.b = &op;
        return p;
    }

    int rows,cols;
    double* data;

    /// your Matrix stuff
    // ...
};

void test()
{
    Matrix a(4,2),b(2,4),c;

    c = a * b; // (note a*b returns Product without calculating its result
               // result is calculated inside = operator

    c = a * b; // note that this time c is initialized to correct size so no
               // additional reallocations will occur

}

【讨论】:

  • 您可以搜索到的术语是“表达式模板”en.wikipedia.org/wiki/Expression_templates
  • 为什么要把实际的产品操作移到operator=上?
  • 因为我们需要等待存储才能存储产品结果。
  • 我想我理解了解决方案。十分优雅!感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 2021-07-18
  • 1970-01-01
相关资源
最近更新 更多