【问题标题】:What is the correct way to overload an operator of a primitive type in C++?在 C++ 中重载原始类型的运算符的正确方法是什么?
【发布时间】:2021-07-29 08:51:01
【问题描述】:

我正在尝试编写一个简单的矩阵类以在我的一个课程项目中使用。类的定义如下所示。

#ifndef MATRIX_HH
#define MATRIX_HH

#include <cstdio>
#include <cstdlib>
#include <omp.h>

#include "MatrixException.hh"

#define F77_CALL(x) x ## _
#define F77_NAME(x) F77_CALL(x)

#ifdef __cplusplus
extern "C" {
#endif

extern void F77_NAME(dgemm)(const char *transa,const char *transb,
    const int *m, const int *n, const int *k,
    const double *alpha, const double *a, const int *lda,const double *b, 
    const int *ldb, const double *beta, double *c, const int *ldc);

#ifdef __cplusplus
}
#endif

class Matrix {
private:
    /** The number of rows. */
    int m;
    /** The number of columns. */
    int n;
protected:
    /** The matrix entries, stored in row-major order. */
    double *data;
public:
    /** The matrix dimensions (as an array). */
    int *dims;
    Matrix(int m_,int n_);
    Matrix(int m_,int n_,double *data_);
    ~Matrix();
    void shape();
    void print();
    const double &operator()(int i) const;
    const double &operator()(int i,int j) const;
    double &operator()(int i,int j);
    Matrix transpose();
    Matrix operator + (const double c);
    Matrix operator - (const double c);
    Matrix operator * (const double c);
    Matrix operator + (const Matrix &B);
    Matrix operator - (const Matrix &B);
    Matrix operator * (const Matrix &B);
    double sum();
};
#endif

如何使用这个类的一个例子是:

// Two random matrices
Matrix A(3,3),B(3,3);
// Matrix addition
Matrix C=A+B;
// Matrix-matrix multiplication
Matrix D=A*B;
// Add a scalar to each entry of A
Matrix E=A+1.;

这已经是很多功能了,但我会发现我的矩阵类能够执行以下操作很有用:

Matrix A(3,3);
// This should be equivalent to A+1.
Matrix B=1.+A;

如何重载double 等基本类型的+ 运算符来完成这样的事情?我尝试声明类似:

Matrix double::operator+(const Matrix&B);

但是,当我尝试编译时,这会出错。

g++-10 -fopenmp -Wall -std=c++11 -O3   -framework Accelerate -c Matrix.cc
In file included from Matrix.cc:1:
Matrix.hh:53:2: error: two or more data types in declaration of 'operator+'
   53 |  Matrix double::operator + (const Matrix &B);
      |  ^~~~~~

这样做的正确方法是什么?

PS。我知道存在像Eigen 这样的线性代数库,它们提供了很多“开箱即用”的功能。但是,由于这是一个课程项目,我选择编写自己的矩阵类。

【问题讨论】:

标签: c++ matrix operator-overloading


【解决方案1】:

您可以将重载运算符添加为非成员函数。

Matrix operator+(double c, const Matrix&B) {
    return B + c;  // calling Matrix::operator + (const double c)
}

PS:最好将作为成员函数实现的运算符标记为const,它们不应该对要调用的对象进行修改。

【讨论】:

  • 如果你这样做(你应该这样做),你需要将该函数声明为 Matrix 类的友元,以便它可以访问 Matrix 的受保护部分和私有部分。
  • @Sniggerfardimungus 对于这种情况,我们可以调用Matrix::operator + (const double c)
  • 很公平。旧习难改。 =]
  • @Sniggerfardimungus 嗯,这是一个好习惯,尤其是当所有运算符都作为非成员重载时。
  • @ErickRuiz 您应该将成员运算符标记为const,例如Matrix operator + (const double c) const; ...
【解决方案2】:

可以这样实现:

在类中,添加:

class Matrix {
   ...
public:
  friend Matrix operator + (double a, const Matrix &B);
   ...
}

然后,在类外定义:

Matrix operator + (double a, const Matrix &B)
{
   ...
}

最好的问候。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多