The World of Mayukh Bose

<< Back to Main Page Mayukh's world: e-mail me | about
Mayukh's World: Operator Overloading With C++ Thursday, November 23, 2017
Index
  • Introduction
  • What Operators?
  • Rules
  • Assignment Operator
  • More on Assignment
  • Arithmetic Operators
  • Arithmetic with Globals
  • Increment/Decrement
  • Operator-Assignment
  • Unary Operators
  • Relational Operators
  • Bitshift/Extraction
  • Subscript Operator
  • Function Call Operator
  • Bit and Logical Ops
  • Comma Operator
  • Pointer to Member
  • new and delete Ops
  • Credits and Thanks
  • My Free Software
  • Delphi/C++ Builder
  • Pocket PC
  • FreeSpeech Chat
  • C/C++ Freebies
  • Perl
  • Python
  • Ruby
  • C++ Operator Overloading Tutorial e-mail me

    Function Call Operator ()

    The function call operator in C++ is the () operator. It can be overloaded similar to the subscript operator that we examined previously, with one MAJOR difference. The subscript operator can accept only one argument, whereas the function call operator can accept multiple arguments of varying types. This particular fact is very significant to us.

    For example, if we have a 2-dimensional array class, we cannot overload [] to reference a specific cell of the array, since [] only takes one value as argument. However, we can overload the () operator, since it can take multiple arguments, and therefore, we can specify a row and a column as arguments. In fact, the function call operator is the ONLY overloaded operator that can take variable numbers and types of arguments. This allows us to use (and misuse) it in a variety of situations.

    For our example, we will build on the previous example and overload () to do the same thing as the [] operator. As it happens, some languages (such as BASIC and FORTRAN) use () for array subscripting, so people are used to seeing () used that way. We start by adding another member function to the class.
          class IntArray {
          private:
            int *ptr;
          public:
            IntArray(size_t size) { ptr = new int[size]; }  
    	~IntArray() { delete [] ptr; }
    	int& operator[](int index);
    	int& operator()(int index);
          };
        
    The function implementation is pretty much identical to the previous page as well.
          int& IntArray::operator()(int index){
            return ptr[index];
          }
        
    As before, we can test this object as follows:
          int main(void) {
            IntArray iArray(10); // Declare a 10 element array                            
    
    	// Write Operations
    	iArray(0) = 5; 
    	iArray(1) = 3;
    
    	// Read Operations
    	cout << iArray(0) << endl;
    	cout << iArray(1) << endl;
    
    	return 0;
          }
        
    Running this code produces the expected output.

    As seen before in the previous page (subscript operator), it is not necessary to always return a reference. For instance, if you wanted to make the object read only, you could make it return a const int instead of an int& reference.

    Exercises

    1. Our overloaded operators do not check if the index is within the array bounds. Add code to do this and throw an exception if needed. Another variation of this could be to resize the array as needed, instead of throwing an exception.

    2. The default copy constructor generated by the compiler has a problem in it. It copies the pointer directly from one instance of an object to another, instead of making a copy of the data. This causes a problem because now there are two pointers pointing to the same memory and when one is destroyed, the other will point to freed memory. The solution is to write your own copy constructor that makes a copy of the data properly. Write a copy constructor to handle the data appropriately.

    3. Rewrite the class to handle two dimensional arrays. The following code should help you get started.
    	 class TwoDArray {
    	 private:
    	   int rows, cols;
    	   int *ptr;
    	 public:
    	   TwoDArray(size_t max_rows, size_t max_cols)
    	   {
    	     rows = max_rows; cols = max_cols;
    	     ptr = new int[rows * cols];
    	   }
    	   ~TwoDArray() { delete [] ptr; }
    	   int operator()(int row, int col) const;
    	   int& operator()(int row, int col);
    	 };
    
    	 int TwoDArray::operator()(int row, int col) const {
    	   return ptr[row * rows + col];
    	 }
    
    	 // Implement the other function here
             // Also implement a copy constructor, if you feel like it
           
    Verify that this code works:
    	 int main(void) {
    	   TwoDArray iArray(10, 10); // Declare a 10x10 element array
    
    	   iArray(0, 1) = 5;
    	   iArray(1, 1) = 2;
    	   cout << iArray(0, 1) << endl;
    	   cout << iArray(1, 1) << endl;
    
    	   return 0;
    	 }
           


    <<Previous: Subscript Operator ^Up to Mayukh's World^ Next: Bit and Logical Operators >>

    Copyright © 2004 Mayukh Bose. All rights reserved.
    This work may be freely reproduced provided this copyright notice is preserved.
    OPTIONAL: Please consider linking to this website (http://www.mayukhbose.com/) as well.