Overload subsript operator in C++

Let us say you have an array class to store an integer array. You have a constructor for allocation and getter and setter methods for values of the array. Your program may look something like this.
This is your header file array.h
class IntArray
{
   int *arr;
   int sz;
 public:
   IntArray(int len=10);
   int getElement(int n);
   void setElement(int n,int val);
   int operator[](int n);
   enum {ERRVAL=-999};
};
Next is your cpp file for method definitions array.cpp
#include<iostream>
using namespace std;
#include"array.h"

IntArray::IntArray(int len)
{
  if (len<0)//are you out of your mind
  {
     cout<<"Are you out of your mind???? Give a positive value, I am setting size to 10";
     len=10;
   }
   sz = len; /* allocate memory*/
   arr = new int[sz];
}

int IntArray::getElement(int n)
{
   if (n>=0 && n<sz)
   return arr[n];
   return ERRVAL;
}

void IntArray::setElement(int n,int val)
{
   if (n>=0 && n<sz)
   {
     arr[n]=val;
    }
    else
    {
       cout<<"invalid subscript";
    }
}

Then let us test this using our main in mainArray.cpp
#include<iostream>
using namespace std;
#include"array.h"
int main()
{
   IntArray a(5);
   for(int i=0;i<5;i++)
       a.setElement(i,i*i);
 
   for(int i=0;i<5;i++)
      cout<<"the element "<<"i is "<<a.getElement(i)<<endl;
}
But the getters and setter functions are not user friendly. As our variable a is an array, why can't we use subscript operator - []? Let us do that by overloading subscript operator.

Add this line to array.h
int operator[](int n);

This tells the compiler that our operator function overloads [] operator and takes subscript integer as an operand.
Let us add this function to array.cpp
int IntArray::operator[](int n)
{
if (n>=0 && n<sz)
return arr[n];
return ERRVAL;
}
Now let us change the main function also as
for(int i=0;i<5;i++)

      cout<<"the element "<<"i is "<<a[i]<<endl;
And bingo! Our program is giving correct output. So instead of clumsy a.getElement[i] we are using a[i] to access the ith element of the array inside the object.
Now let us also try to replace setElement.
Change the getElement line in main function as
for(int i=0;i<5;i++)
      a[i] = i*i;

And our output is . But what happened we are getting compilation error which tells us that
Yeah, a[i] is a function call here. A call to the subscript operator function and this function is returning an integer value not a reference. So we can not have it on LHS.
The solution is not so tough. We return a reference from the function so the function returns an lvalue and our error in a[i]=i*i will be corrected. How do we do that? In array.h change the declaration of operator function to
int operator[](int n);

And let us also change the definition of the function to
int& IntArray::operator[](int n)
{
  if (n>=0 && n<sz)
     return arr[n];
  return ERRVAL;
}

But we have a problem with ERRVAL. Our compiler tells us that we can not have ERRVAL as reference. For the time being let us ignore this error condition, later we will throw an exception for this situation.
So the final version of [] operator is
int& IntArray::operator[](int n)
{
  if (n>=0 && n<sz)
     return arr[n];
}

You can take up an exercise of - operator for the array which let us will negate each element of the array.

Comments

Popular Posts