如何为形式a[x][y]创建重载操作符

How do create an overloaded operator for the form a[x][y]?

本文关键字:创建 重载 操作符      更新时间:2023-10-16

我有一个简单的矩阵类,我必须以a[index1][index2]的格式读取/写入。

例如:

Matrix a;
a[1][2] = 5;

我如何在c++中实现它?谢谢。

这是一个很好的基本实现,它完全符合您的要求。

更新(2013年9月26日):我已经改进了很多代码。

模板中T类型只需满足std::vector类型的要求。

#include <vector>
#include <stdexcept>
template<typename T>
class matrix {
    class row {
        std::vector<T> values;
    public:
        row(std::size_t n)
            : values(n, T()) {}
        T& operator[] (std::size_t index) {
            if (index < values.size())
                return values[index];
            else
                throw std::domain_error("Matrix column index out of bounds.");
        }
        const T& operator[] (std::size_t index) const {
            if (index < values.size())
                return values[index];
            else
                throw std::domain_error("Matrix column index out of bounds.");
        }
        std::size_t size() const { return values.size(); }
    };
    std::vector<row> rows;
public:
    matrix(std::size_t m, std::size_t n)
        : rows(m, row(n)) {}
    row& operator[](std::size_t index) {
        if (index < rows.size())
            return rows[index];
        else
            throw std::domain_error("Matrix row index out of bounds.");
    }
    const row& operator[](std::size_t index) const {
        if (index < rows.size())
            return rows[index];
        else
            throw std::domain_error("Matrix row index out of bounds.");
    }
    std::size_t row_count() const { return rows.size(); }
    std::size_t col_count() const {
        if (rows.size()) return rows[0].size();
        return 0;
    }
    std::size_t size() const { return row_count() * col_count(); }
};

为方便起见,可以使用这个帮助器来打印矩阵。

#include <ostream>
template<typename T>
std::ostream& operator <<(std::ostream& o, const matrix<T>& mat) {
    for (std::size_t i = 0u; i < mat.row_count(); ++i) {
        for (std::size_t j = 0u; j < mat.col_count(); ++j) {
            o << mat[i][j] << ' ';
        }
        o << 'n';
    }
    return o;
}

为您提供一个用法示例来测试:

int main() {
    matrix<int> mat_0(2, 3);
    matrix<double> mat_1(1, 2);
    mat_0[0][0] = 2;
    mat_0[0][1] = 3;
    mat_0[0][2] = 4;
    mat_0[1][0] = 3;
    mat_0[1][1] = 7;
    mat_0[1][2] = 9;
    mat_1[0][0] = 0.43;
    mat_1[0][1] = 213.01;
    std::cout << mat_0;
    std::cout << 'n';
    std::cout << mat_1;
    return 0;
}

您需要重载Matrix::operator[],以便它返回一个表示矩阵中的一列的助手类。这个helper类还应该重载operator[]来访问该列中的元素。

然而,以这种方式实现它可能会过于复杂。相反,实现operator()并将这两个索引作为参数可能更容易:

int& Matrix::operator()(int i, int j)
{
  return internal_array[i][j];
}

定义嵌套的class RowType,其中operator[]返回一个指向Matrix元素的ref,并定义Matrix operator []返回一个指向RowType元素的ref。

这是主题的变化(围绕第一个答案)。我只是认为你不应该使用new-delete…啊,还有一个模板,可以使用int, double, complex, (string!?)等。这不是一个完整的实现,我没有调试它。这只是一个想法。

#include <vector>
template <typename Num>
class Matrix {
   public:
    class RowType 
    { public:
       RowType () { }
       RowType (unsigned int columnCount):values(columnCount,Num()) {}
             int& operator[](unsigned int index)     {return values[index];}
       const int& operator[](unsigned int index)const{return values[index];}
       std::vector<Num> values;
    };
    Matrix() {  }
    Matrix(unsigned int rowCount, unsigned int columnCount)
              :rows(rowCount, MatrixRow<Num>(columnCount) )  {}
          RowType& operator[](unsigned int index)     {return rows[index]);}
    const RowType& operator[](unsigned int index)const{return rows[index]);}
  private:  std::vector<RowType<Num>> rows;
};
....
Matrix<int> a(10,10);
a[9][9]=1;

你可以创建一个一维矩阵类,例如Matrix1D,并重载它的[]运算符,使你能够访问特定索引处的值。

然后你可以创建一个2d矩阵类,例如Matrix2D,并重载它的[]运算符,让你访问其中包含的Matrix1D类之一。

这样你就可以从a (Matrix2D)转换到Matrix1D ([]),然后再转换到第二个[]的值。