CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    C++ General: How to declare and use two-dimensional arrays?

    Q: How can I define a dynamic two-dimensional array?

    A: The following class shows one way of encapsulating a two-dimensional array:

    Code:
    template <class T>
    class dynamic_2d_array
    {
    public:
      dynamic_2d_array(int row, int col) : m_row(row),
                                           m_col(col),
                                           m_data((row != 0 && col != 0) ? new T[row * col] : NULL){}
    
      dynamic_2d_array(const dynamic_2d_array& src) : m_row(src.m_row),
                                                      m_col(src.m_col),
                                                      m_data((src.m_row != 0 && src.m_col != 0) ? new T[src.m_row * src.m_col] : NULL)
      {
        for(int r = 0;r < m_row; ++r)
          for(int c = 0; c < m_col; ++c)
            (*this)[r][c] = src[r][c];
      }
    
      ~dynamic_2d_array()
      {
        if(m_data)
          delete []m_data;
      }
      
      inline T* operator[](int i) { return (m_data + (m_col * i)); }
    
      inline T const*const operator[](int i) const {return (m_data + (m_col * i)); }
    
    
    private:
      dynamic_2d_array& operator=(const dynamic_2d_array&);
      const int m_row;
      const int m_col;
      T* m_data; 
    };
    A different approach using the STL 'vector' class is shown in the following FAQ...


    FAQ contributed by: [Axter]


    Last edited by Andreas Masur; July 23rd, 2005 at 12:36 PM.

  2. #2
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: C++ General: How to declare and use two-dimensional arrays?

    A: Here is another alternative approach. This uses a non-standard notation but is simple to use. I will call the class matrix.

    Code:
    template <typename T>
    class Matrix
    {
    private:
       size_t m_nRows;
       size_t m_nCols;
       std::vector< T > m_vect;
    
    public:
       Matrix( size_t nRows=0. size_t nCols=0, const T& t= T() )
        : m_nRows( nRows ), m_nCols (nCols), m_vect( nRows * nCols, t )
       {
       }
    
       size_t rows() const { return m_nRows; }
       size_t cols() const { return m_nCols; }
    
       T& operator()( size_t row, size_t col )
       {
            assert( row < m_nRows && col < m_nCols );
            return m_vect[ row * m_nCols + col ];
       }
    
       const T& operator()( size_t row, size_t col ) const
       {
            assert( row < m_nRows && col < m_nCols );
            return m_vect[ row * m_nCols + col ];
       }
            
       T* getRow( size_t  row )
       {
             assert( row <= m_nRows ); // we allow one past the end
                                                 // this permits certain algorithms
    
             return &m_vect[ row * m_nCols ];
       }
    
       const T* getRow( size_t row ) const
       {
             assert( row <= m_nRows ); // see comment above
             return &m_vect[ row * m_nCols ];
       }
     
       T* operator[]( size_t  row ) // same as getRow
       {
           return getRow( row );
        }
    
       const T* operator[]( size_t row ) const
       {
            return getRow( row );
        }
       
       class const_row_iterator
       {
         private:
              const Matrix * m_pMatrix;
              size_t m_nRow;
        
         public:
              const_row_iterator( const Matrix *pMatrix=0, size_t nRow = 0 )
                 : m_pMatrix (pMatrix), m_nRow( nRow )
              {
              }
    
           bool operator!=( const const_row_iterator & rhs )const
           {
                return (m_row != rhs.m_row) || (m_pMatrix != rhs.m_pMatrix);
           {
    
           const T* operator*() const
           {
                return m_pMatrix->getRow( m_nRow );
           }
    
           const_row_iterator& operator++()
           {
              ++m_nRow;
              return *this;
          }
    
          const_row_iterator operator++( int )
          {
              const_row_iterator itCopy( *this );
              ++m_nRow;
             return itCopy;
         }
      }; // end of const_row_iterator class
    
       const_row_iterator begin() const
        {
           return const_row_iterator( this, 0 );
        }
    
        const_row_iterator end() const
        {
            return const_row_iterator( this, m_nRows );
        }
    };
    That will give you reasonable functionality. You can do more with it (add a non-const iterator, give iterator more than FwdIterator traits).

    Note: For matrices of numerical types, it may be better to use valarray instead of vector. Then a row could be returned as slicearray. I have never actually implemented one this way though.


    Last edited by Andreas Masur; July 23rd, 2005 at 12:54 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured