12.10 OVERLOADING OF THE () OPERATOR


12.10 OVERLOADING OF THE ‘()’ OPERATOR

It is also possible to overload the function call operator‘()’. Overloading this operator allows an object to be used as a function object. A function object, also known as a functor, can serve a role akin to that of a function pointer when supplied as an argument to another function. In other words, if you overload the function call ‘()apos; for a class, an object of that type can act like a function. When such an object is invoked like a function, it is the code that is in the overload definition of ‘()’ that gets executed. One of the primary advantages of a functor over a regular function is that the data members of the former can be deployed to advantage in the operations carried out by the code in the overloading of ‘()’.[7]

To illustrate the concept of a function object, let's say we want to sort by age a list of Cat objects made from the following class:

      class Cat {      public:           string name;           int age;           Cat( string nam, int yy) : name(nam), age( yy ) {}      }; 

The Cat objects will be the elements of a list of type list<Cat>:

      list<Cat> kittyList; 

To sort the cats by age, we have to tell the generic STL algorithm sort how to compare two Cat objects by their age fields. For that purpose we define a comparator class as follows:

      class Cat_Comparator {      public:           bool operator() ( const Cat&, const Cat& ) const;      }; 

and provide the following overload definition for the ‘()’ operator:

      bool Cat_Comparator::operator() ( const Cat& x1,                                        const Cat& x2 ) const {           return x1.age < x2.age;      } 

With operator() overloaded for the Cat_Comparator class, an object of type Cat_Comparator can be made to act like a function. This is demonstrated by the following code in lines (A) and (B) of the program SortWithFunctor.cc below:

      Cat_Comparator comp;      kittyList.sort( comp ); 

Note that the argument to sort in line (B) is an object. Its role is very much like that of the function pointer argument in the call to qsort in Chapter 4. What is invoked where comp is called in the body of sort is the code in the overloading of the ‘()’ operator. The return type when an object is invoked like a function is the return type for the overloading of the operator ‘().’

Here is the code for SortWithFunctor.cc:

 
//SortWithFunctor.cc #include <string> #include <list> using namespace std; class Cat { public: string name; int age; Cat( string nam, int yy) : name(nam), age( yy ) {} }; class Cat_Comparator { public: bool operator() (const Cat&, const Cat&) const; }; bool Cat_Comparator:: operator() (const Cat& x1, const Cat& x2) const { return x1.age < x2.age; } template<class T> void print(list<T> ); int main() { Cat kitty1( "socks", 6 ); Cat kitty2( "cuddles", 3 ); Cat kitty3( "tabby", 8 ); list<Cat> kittyList; kittyList.push_back( kitty1 ); kittyList.push_back( kitty2 ); kittyList.push_back( kitty3 ); Cat_Comparator comp; //(A) kittyList.sort( comp ); //(B) print( kittyList ); // cuddles 3 socks 6 tabby 6 return 0; } template<class T> void print( list<T> li ) { typedef list<T>::const_iterator CI; for ( CI iter = li.begin(); iter != li.end(); iter++ ) cout << iter->name << " " << iter->age << " "; cout << endl << endl; }

To shed further light on the parallels between a regular function and a function object, we obviously cannot compare two Cat object, kitty1 and kitty2, by making the following call

      Cat_Comparator( kitty1, kitty2 );        // WRONG 

since that would try to invoke a two-parameter constructor for Cat-Comparator, if such a constructor were to exist, and not the comparison code in the overloading of the function call operator. If we wanted to, we could make a direct invocation of the function-call overloading by the following calls:

      Cat_Comparator cat_comp;      bool test = cat_comp.operator()( kitty1, kitty2 );      cout << "value of test is: " << test << endl; 

[7]As an example of how a data member can prove useful to a function object, see the class ThresholdCheck defined in Problem 4 in the homework section of Chapter 5.




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net