【问题标题】:Two square bracket overloading两个方括号重载
【发布时间】:2011-04-12 14:49:47
【问题描述】:

我正在用 c++ 编写一个矩阵类,并试图重载一些运算符,如 = 和 >> 和

我无法为矩阵类重载运算符 [][]。 如果我有一个像 M1 这样的类矩阵对象,那么我可以使用这种方式为每个元素赋值:

M1[1][2]=5;

int X;

X=M1[4][5];

【问题讨论】:

标签: c++ indexing operator-overloading brackets


【解决方案1】:

只需重载operator[] 并使其返回指向矩阵相应行或列的指针。由于指针支持[] 下标,因此可以通过'double-square' 符号[][] 进行访问。

您还可以使用两个参数重载operator()

【讨论】:

  • 我更喜欢 RedX 的解决方案而不是这个解决方案,因为在我看来,除非绝对必须,否则不应在 C++ 中使用指针。
  • 我发现operator(x,y)在这种情况下是一个很好的解决方案。
  • 如何用两个参数重载 operator()?当我尝试这样做时,我收到一个编译器错误,说它“必须只接受一个参数”。
【解决方案2】:

C++ 中没有operator[][]。你必须 return 一个辅助对象,然后重载 operator[] 才能获得这种访问权限。

【讨论】:

    【解决方案3】:

    你可以超载operator[]。所以如果你想这样使用矩阵,你应该把矩阵作为向量数组。

    class Matrix
    {
    ...
      Vector & operator[]( int index );
    ...
    };
    

    class Vector
    {
    ...
      double & operator[]( int index );
    ...
    };
    

    最后:

    Matrix m;
    ...
    double value = m[i][j];
    ...
    

    【讨论】:

      【解决方案4】:

      没有operator[][],你可以实现operator[]来返回对行/列对象的引用,你可以在其中实现operator[]来返回单元格引用。

      您可以执行以下操作来避免所有麻烦..

      struct loc
      {
        int x;
        int y;
      };
      

      然后在您的operator[] 重载中,接受loc,类似

      T& operator[](loc const& cLoc)
      {
       // now you have x/y you can return the object there.
      }
      

      要调用,您可以简单地执行以下操作:

      matrix[loc(2,3)] = 5; 
      

      【讨论】:

      • 这是一个我以前从未见过的有趣想法,但它的作用仍然很明显。
      【解决方案5】:

      实际上,几年前我在自己的矩阵类中就是这样做的。在这种情况下,我在下面定义了一个包含 sn-p 的矩阵模板类。

      然后我能够迭代并分配如下:

                for(size_t k=1; k<n; ++k) {       
                         minor[p][k-1]=major[j][k];        
                 }
      

      我希望这会有所帮助。

      // //////////////////////////////////////////////////////////////////////////////
      // list is internal vector representation of n x m matrix
      T* list;
      // Proxy object used to provide the column operator
      template < typename T >
      class OperatorBracketHelper
      {
          Matrix < T > & parent ;
          size_t firstIndex ;
      
          public :
              OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
              parent ( Parent ), firstIndex ( FirstIndex ) {}
      
              // method called for column operator
              T & operator []( size_t SecondIndex )
              {
                  // Call the parent GetElement method which will actually retrieve the element
                  return parent.GetElement ( firstIndex , SecondIndex );
              }
      };
      
      // method called for row operator
      OperatorBracketHelper < T > operator []( size_t FirstIndex )
      {
          // Return a proxy object that "knows" to which container it has to ask the element
          // and which is the first index (specified in this call)
          return OperatorBracketHelper < T >(* this , FirstIndex );
      }
      
      T & GetElement ( size_t FirstIndex , size_t SecondIndex )
      {
          return list[FirstIndex*cols+SecondIndex];
      }
      

      【讨论】:

        【解决方案6】:

        我正在研究一个矩阵类,我决定首先创建一个具有动态二维数组的 Array 类。所以,就像你一样,我遇到了这个障碍,我如何重载两个方括号。我如何处理这个案子很简单;我将方括号运算符作为成员函数重载了两次。首先,我重载了 [] 以便返回一个指向所需行的指针,可以这么说,然后下面的成员函数(即再次重载 operator [])返回一个与数组元素相同类型的左值。

        但是,请注意,您调用前一个重载运算符 [] 的索引必须保存在某个地方,以便您可以在后一个重载运算符 [] 中使用它。出于这个原因,我只是在类 Array 中添加了一个 int 类型的新成员(我在下面的代码中将其命名为“test”)。

        class Array {
        
        private: 
        
         double **ptr; int test;
         ...   /* the rest of the members includes the number of rows and columns */
        
        public:
            Array(int=3,int=3);  // Constructor
            Array(Array &);      // Copy Constructor
            ~Array();            // Destructor
            void get_array();
            void show_array();
            double* operator[] (int);
            double operator[] (short int);
            ...
        };
        
        ... 
        
        double* Array::operator[] (int a) {
            test = a;
            double* p = ptr[test];
            return p;
        }
        
        double Array::operator[] (short int b) {
           return ((*this)[test][b]);
        }
        

        因此,例如,在 main 我可以简单地写:

        int main(){
        Array example;
        cout << example[1][2];  
        }
        

        希望对你有帮助。

        【讨论】:

          【解决方案7】:

          你不能像这样重载[][],因为没有这样的 操作员。您可以重载[] 以返回同样的东西 在其上定义了[](代理);在最简单的情况下, 像double* 这样的东西会起作用,但通常会更好, 虽然工作多一点,但要使用完整的课程。 (补充的地方 例如,边界检查。)

          或者,您可以重载(x,y)。取决于你是谁 问,一种格式或另一种格式“更好”。 (其实是 严格来说是风格问题。)

          【讨论】:

            【解决方案8】:

            模板矩阵类

            template <uint8_t rows, uint8_t cols, typename T>
            class MatrixMxN {
            public:
                T* operator[](uint8_t f_row) {
                    return &m_val[f_row * cols];
                }
            protected:
                T m_val[rows*cols];
            };
            

            这里是3行4列整数类型的矩阵对象。

            MatrixMxN<3, 4, int32_t> M;
            M[2][3] = 10;
            std::cout << M[2][3] << std::endl;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-08-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-07-11
              • 2020-04-08
              相关资源
              最近更新 更多