Operator Overloading - II

Let us consider some special cases of operator overloading

Overloading of subscript operator:

subscript operator can be overloaded to access the dynamically allocated array elements within an object.

 
class Arr
{
    int *arr;
    int size;

public:
    int& operator [](int n) ;
    int operator[](int n) const;
/****code *****/
};

int &Arr::operator [](int index)
{
    return arr[index];
}

int Arr::operator [](int index) const
{
    return arr[index];
}

Const version of operator function is written so that constant objects can also access array elements. Non-constant version is helpful in modifying the array elements.

Make sure that non-const version of [] function returns a reference, so that you can assign values using statement like

obj1[3]=99;

Increment and Decrement operator ++ and --:

++ and -- have prefix and postfix versions for basic data types. a++ and ++a.  So how do we overload these operators with two versions?


For postfix versions of these functions, we should use a dummy int parameter. 



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Number
{
    int num;
public:
    Number & operator++();/*prefix version*/
    Number operator++(int a);/*postfix version*/
/****code***/
};
Number & Number::operator++()
{
    num++;
    return *this;
}

Number Number::operator++(int dummy)
{
    Number temp = *this;
    num++;
    return temp;
}

int main()
{
    Number obj(9);
    Number obj2(1000);
    obj2 = ++obj;/*calls prefix*/
    obj = obj2++;/*calls postfix*/
}

new operator:
New operator takes size_t parameter and returns a void pointer. The easy way of overloading new operator would be
 
void *Number::operator new(size_t bytes)
{
    char *ptr = ::new char[bytes];/*call global new operator*/
    return (void*) ptr;
}

Note that compiler provided new operator for classes will be sufficient in most situations. You need to overload new and delete operator, only if you want to use your own block of memory for dynamic allocation.

Insertion and Extraction operators (<< and >>) :

These two operators are used to read and write objects from iostreams and files. These should be overloaded as non-member functions  because their first parameter will not be the current class object. . >> must have istream object as first parameter and << must have ostream object as first parameter.

These two functions must return reference to iostream objects in order to use chaining in io operation. And it is necessary to use second parameter also as reference parameter in extraction operator as the function modifies object.

 
ostream & operator <<(ostream& out, Number & obj)
{
    out<<obj.num;
    return out;
}

istream & operator >>(istream& in, Number & obj)
{
    in>>obj.num;
    return in;
}


Conversion Operators:

These are used to convert objects to basic data types. They are written without return type. Instead, data type is the name of the operator.
 
class Number
{
    int a;
public:
    operator int()/*Converts Number object to int*/
    {
         return a;
    }
/****code*****/
};


Function call operator:

parantheses - () can be overloaded to create an object which behaves like a function. Such objects are called function objects or functors.

 
class Cube
{
public:
int operator ()(int n)
{
   return n*n*n;
}
};
int main()
{
    Cube cobj;
    int m = cobj(10);/*this cubes 10 and returns answer*/
}


Overloading of assignment operator:

Compiler provides overloaded assignment operator function for a class. But you have to write your own assignment operator function if you need deep copy.

Assignment operator function looks almost like a copy constructor. You allocate memory and you copy elements.

But before that, you should release earlier memory allocated.

There is one more problem however. What if you use a statement which ultimately becomes self assignment

ob1 = ob1;

In this case, if you delete memory, all hell breaks loose.

To avoid this problem, check for self assignment, then delete memory, allocate new memory and copy elements.

 
A& A::operator =(A & obj1)
{
    if(this !=&obj1)/*self assignment?*/
    {
      delete arr;
      arr = new int[obj1.n];
      for(int i=0;i<n;i++)
         arr[i] = obj1.arr[i];
    }
    return *this;
}
 

Comments

Popular Posts