【问题标题】:How to overload array index operator for wrapper class of 2D array? [duplicate]如何为二维数组的包装类重载数组索引运算符? [复制]
【发布时间】:2010-12-30 13:58:53
【问题描述】:
#define ROW 3
#define COL 4

class Matrix
{
   private:
      int mat[ROW][COL];  
    //.....
    //.....

};

int main()
{
  Matrix m;
  int a = m[0][1]; //  reading
  m[0][2] = m[1][1]; // writing
} 

我直接认为不可能重载 [][] 。

我认为我必须间接地做到这一点,但如何实现呢?

【问题讨论】:

    标签: c++ operator-overloading


    【解决方案1】:

    由于您想将元素存储在固定大小的数组中,这将相当容易:

    #define ROWS 3
    #define COLS 4
    
    typedef int row_type[COLS];
    
    class matrix {
       row_type elements[ROWS];
    public:
       ...
       row_type const& operator[](int r) const {return elements[r];}
       row_type      & operator[](int r)       {return elements[r];}
       ...
    };
    

    应该可以的。

    此外,您可能希望将#defines 替换为适当的常量或使用类型(int)和大小(3x4)的模板参数,以使您的矩阵类更通用。如果您想支持动态大小,您的 operator[] 需要返回代理对象。这是可能的,但您可能更喜欢 operator() 使用两个索引参数来访问元素。

    【讨论】:

      【解决方案2】:

      更简单的解决方案是使用 operator(),因为它允许多个参数。

      class M
      {
          public:
             int& operator()(int x,int y)  {return at(x,y);}
          // .. Stuff to hold data and implement at()
      };
      
      
      M   a;
      a(1,2) = 4;
      

      简单的方法是第一个 operator[] 返回一个中间对象,第二个 operator[] 返回数组中的值。

      class M
      {
          public:
          class R
          {
               private:
                   friend class M; // Only M can create these objects.
                   R(M& parent,int row): m_parent(parent),m_row(row) {}
               public:
                    int& operator[](int col) {return m_parent.at(m_row,col);}
               private:
                    M&  m_parent;
                    int m_row;
          };
      
          R operator[](int row) {return R(*this,row);}
      
          // .. Stuff to hold data and implement at()
      };
      
      M   b;
      b[1][2] = 3;   // This is shorthand for:
      
      R    row = b[1];
      int& val = row[2];
      val      = 3;
      

      【讨论】:

      • 一个好的优化器会把代理版本改成和operator()一样高效的代码吗?
      • 这取决于编译器。但我喜欢尽可能直观地使用我的对象。使用对象感觉越自然,犯错的可能性就越小。我个人更喜欢代理,但在这种情况下,它有六分之一,我不能肯定地说一个比另一个更好。
      • 是的,我一直使用operator(),但我想这次我会使用代理(我编写游戏引擎),看看它是否会产生任何问题。我无法想象编译器很难让它同样快,因为它会有所有运算符的完整定义。
      • 应该是:int&运算符()(int x,int y)
      • 印象深刻!我只是让它与一个模板类(用于矩阵操作)一起工作。我有一个小的语法错误,因为我试图从 R::operator[] 而不是 R 本身返回一个 R&。一旦我发现它就没有问题了。非常光滑! (现在看看我是否可以重载“地址”运算符,以便我可以在矩阵中返回一个向量。:P
      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 2013-01-17
      • 2019-08-21
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 2016-03-09
      • 1970-01-01
      相关资源
      最近更新 更多