【问题标题】:How do create an overloaded operator for the form a[x][y]? [duplicate]如何为 a[x][y] 形式创建重载运算符? [复制]
【发布时间】:2013-03-24 12:43:49
【问题描述】:

我有一个简单的 Matrix 类,我必须以 a[index1][index2] 的格式对其进行读/写。

例如:

Matrix a;

a[1][2] = 5;

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

【问题讨论】:

标签: c++ overloading


【解决方案1】:

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

更新(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;
}

【讨论】:

    【解决方案2】:

    您需要重载Matrix::operator[],以便它返回一个帮助类,该类代表矩阵中的一列。该帮助程序类还应重载 operator[] 以访问该列中的元素。

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

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

    【讨论】:

    • :(但我必须使用这种格式a[1][2] = 5;你能写吗?
    • +1 double a[x][y] 效率不高,如果您需要良好的性能,最好使用 a(x,y) 形式。
    【解决方案3】:

    使用operator[] 定义嵌套的class RowType,将引用返回到Matrix 元素,并定义Matrix operator [] 以将引用返回到RowType 的元素。

    这是 thema 的一个变体(围绕第一个答案)。我只是相信你不应该使用 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;
    

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2016-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-28
        • 1970-01-01
        • 1970-01-01
        • 2016-12-27
        • 2017-01-29
        相关资源
        最近更新 更多