In the world of
C++ every thing changes.... in
C we use a pointer to a function is used to implement callbacks.. C++ provides a far better alternative the function objects(functors). Function objects are simple classes that overload the () operator , so normally they behave like functions because they have overloaded the () operator but they are actually objects. Using function objects over function pointers gives us a lot of advantages like , the function objects may contain member variables that can be used to store the state of the object, they are more stable to changes as compared to function pointers , well you may say that the function pointers also support changes but you would need to keep the prototype same otherwise you break the existing stable code that uses the function pointer where as in the case of function objects you can just another overloaded version of the () operator to the function object class. From optimization point of view you have the option of making the overloaded () operator as inline thus finally avoiding a function call if it is required. You also have the option of having a generic function object with the help of templates , we willsee them as we go along.
Now let us see how we can implement a function object.
class Minus
{
public:
int operator()(int a, int b) const
{
return (b - a);
}
};
Now let us use the fuction object.
int testFunctionObject(int a, int b, Minus &sub )
{
return sub(a,b);
}
int main()
{
Minus funObj;
cout << testFunctionObject(10,20, funObj);
return 0;
}
cool ha...
The call to sub inside the testFunctionObject() is not a simple function call sub is an object and the statement sub(a,b) is transformed to sub.operator()(a,b) .
Now lets create a generic function object using templates.
template <class T>
class Add
{
public:
T operator()(T a,T b) const
{
return (a+b);
}
};
or we can also implement in another way
class Mul
{
public:
template<class T> T operator()(T a,T b) const {return a*b;}
};
The
standard library defines several useful function objects that are used in
STL algorithms for example in the sort()
algorithm takes a predicate object as its third argument.... now what is predicate object , well it is a template function object that returns a bool result (greater<> / less<> used in sort to set the sorting order to ascending or descending). See the example below:
int main()
{
vector vi;
//..fill vector
sort(vi.begin(), vi.end(), greater<int>() );//descending
sort(vi.begin(), vi.end(), less<int>() ); //ascending
}
A full example of function object use can be found below:
#include <iostream>
using namespace std;
//Normal function objects
class Minus
{
public:
int operator()(int a, int b) const
{
return (b - a);
}
};
//Generic function objects
template <class T>
class Add
{
public:
T operator()(T a,T b) const
{
return (a+b);
}
};
//Another way of defining generic function objects this is much simpler to use see the main() function
class Mul
{
public:
template<class T> T operator()(T a,T b) const {return a*b;}
};
//Using function pointers.
double Div(int a , int b)
{
double c = 0.00;
if(b!=0)
{
c = a/b;
}
return c;
}
int main()
{
int a=10,b = 30,c;
Minus sub;
c=sub(a,b);
cout << c << endl;
Add<double> dblAdd;
cout << dblAdd(2.456,5.789) << endl;
Add<int> intAdd;
cout << intAdd(4,6) << endl;
Mul mul;
cout << mul(4.897,7.0) << endl;
double (*fptrDiv)(int,int); // defining the function pointer
fptrDiv = &Div;
cout << fptrDiv(20,10) << endl;
return 0;
}
.