Thursday, October 21, 2010

() vs [] for subscripting in case of more than 1 parameter

Use operator() rather than operator[].
When you have multiple subscripts, the cleanest way to do it is with operator() rather than with operator[]. The reason is that operator[] always takes exactly one parameter, but operator() can take any number of parameters (in the case of a rectangular matrix, two parameters are needed).
For example:
 class Matrix {
 public:
   Matrix(unsigned rows, unsigned cols);
   double& operator() (unsigned row, unsigned col);        
 subscript operators often come in pairs
   double  operator() (unsigned row, unsigned col) const;  
 subscript operators often come in pairs
   
...
  ~Matrix();                              
// Destructor
   Matrix(Matrix const& m);               
// Copy constructor
   Matrix& operator= (Matrix const& m);   
// Assignment operator
   
...
 private:
   unsigned rows_, cols_;
   double* data_;
 };

 inline
 Matrix::Matrix(unsigned rows, unsigned cols)
   : rows_ (rows)
   , cols_ (cols)
   
//data_ <--initialized below (after the 'if/throw' statement)
 {
   if (rows == 0 || cols == 0)
     throw BadIndex("Matrix constructor has 0 size");
   data_ = new double[rows * cols];
 }

 inline
 Matrix::~Matrix()
 {
   delete[] data_;
 }

 inline
 double& Matrix::operator() (unsigned row, unsigned col)
 {
   if (row >= rows_ || col >= cols_)
     throw BadIndex("Matrix subscript out of bounds");
   return data_[cols_*row + col];
 }

 inline
 double Matrix::operator() (unsigned row, unsigned col) const
 {
   if (row >= rows_ || col >= cols_)
     throw BadIndex("const Matrix subscript out of bounds");
   return data_[cols_*row + col];
 }
Then you can access an element of Matrix m using m(i,j) rather than m[i][j]:
 int main()
 {
   Matrix m(10,10);
   m(5,8) = 106.15;
   std::cout << m(5,8);
   
...
 }

No comments:

Post a Comment