C++重载运算符[ ][ ]

14

我有一个名为CMatrix的类,其中包含指向值数组的“双指针”。

class CMatrix {
public:
    int rows, cols;
    int **arr;
};

我只需要通过输入以下代码来访问矩阵的值:

CMatrix x;
x[0][0] = 23;

我知道如何使用以下方法实现:

x(0,0) = 23;

但是我真的需要以另一种方式做。有人能帮助我吗?

最终,我是这样做的...

class CMatrix {
public:
   int rows, cols;
   int **arr;

public:
   int const* operator[]( int const y ) const
   {
      return &arr[0][y];
   }

   int* operator[]( int const y )
   {
      return &arr[0][y];
   }

   ....

4
在C++中没有operator[][],也不能自己创造一个。 - bash.d
“我真的需要用另一种方式来做这件事” 为什么?这是一个任务吗? - Bartek Banachewicz
只需重载数组项的 [] 运算符即可。 - Jan Turoň
@BartekBanachewicz 因为这是学校作业,需要使用准确的术语... - Tomas Sykora
7个回答

30

你无法重载operator [][],但是在这里的常见惯用语是使用一个代理类,即在你的矩阵类上重载operator []以返回另一个类的实例,然后在该类上重载operator []

例如:

class CMatrix {
public:
    class CRow {
        friend class CMatrix;
    public:
        int& operator[](int col)
        {
            return parent.arr[row][col];
        }
    private:
        CRow(CMatrix &parent_, int row_) : 
            parent(parent_),
            row(row_)
        {}

        CMatrix& parent;
        int row;
    };

    CRow operator[](int row)
    {
        return CRow(*this, row);
    }
private:
    int rows, cols;
    int **arr;
};

你可能想把 CMatrix 类设为 CRow 类的友元,否则它将无法构造一个 CRow - Some programmer dude
请注意,这在“const CMatrix”上不起作用,您需要一个代理的“const”版本。您可以将“CRow”设置为模板,并使用适当的“CMatrix&”或“const CMatrix&”进行实例化,以减少代码重复。 - Chris Dodd

18

C++中没有operator[][]。但是,您可以重载operator[]来返回另一个结构,在该重载中再次使用operator[]以获得所需的效果。


4
你可以通过重载operator[]返回一个int*,然后再使用第二个[]进行索引。除了int*,你还可以返回另一个表示行的类,其operator[]可访问行中的单个元素。
基本上,连续应用operator[]作用于前一次应用的结果。

2
在C++23中,为容器添加了部分支持:多维下标运算符。虽然使用的语法是 v[x, y, z] 而不是 v[x][y][z]

2
如果您使用标准库容器创建矩阵,那么这非常简单:
class Matrix {
    vector<vector<int>> data;

public:
    vector<int>& operator[] (size_t i) { return data[i]; }
};

因为这是学校作业,我不能使用任何其他库,只能使用iostream :( - Tomas Sykora
4
问题要求中没有提到这一点。 - Bartek Banachewicz

1

其他答案告诉你怎么做,但是...

不要这样做。

相反,重载operator ()

int & operator () ( size_t row, size_t col )
{
  // maybe validate `row` and `col` first?
  return arr[row * cols + col];
}

为什么不这样做?

C++ FAQ解释了一切,直接从权威口中得知。

简而言之:封装和安全性。


1
你可以使用 operator[] 并使其返回矩阵相应的 行或列 的指针。由于指针支持使用 [ ] 进行下标访问,因此可以使用“双方括号”表示法 [][] 进行访问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接