Showing posts with label Function Pointers. Show all posts
Showing posts with label Function Pointers. Show all posts

Wednesday, 7 April 2010

Example of 'functors'

What are 'functors?'

Depending on what you prefer to read, there are many definitions and explanations of Functors.

From the function pointer tutorial:

Functors are functions with a state. In C++ you can realize them as a class with one or more private members to store the state and with an overloaded operator () to execute the function. Functors can encapsulate C and C++ function pointers employing the concepts templates and polymorphism. You can build up a list of pointers to member functions of arbitrary classes and call them all through the same interface without bothering about their class or the need of a pointer to an instance. All the functions just have got to have the same return-type and calling parameters. Sometimes functors are also known as closures. You can also use functors to implement callbacks.

From StackOverflow:
  • A functor is pretty much just a class which defines the operator(). That makes it "look like" a function.
  • Another advantage to a functor over a pointer to a function is that the call can be inlined in more cases.
  • You can use boost::function, to create functors from functions and methods
Here is a simple example of functors that I have created using mishmash from various places:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to demonstrate the use of functors

#include<iostream>

using namespace
std;

class
someClass
{

public
:
someClass(int x) : someVariable(x) {}
int
operator()(int y) {return (someVariable + y);}
int
internalStateValue(){return someVariable;}

private
:
int
someVariable;
};


int
main()
{

someClass class1(50);
someClass class2(75);

cout<<"Class1 state variable value is : "<<class1.internalStateValue()<<endl;
cout<<"Class2 state variable value is : "<<class2.internalStateValue()<<endl;

int
test1 = class1(22);
cout<<"Test 1 value is : "<< test1<<endl;
int
test2 = class2(22);
cout<<"Test 2 value is : "<< test2<<endl;

cout<<"Class1 final state variable value is : "<<class1.internalStateValue()<<endl;
cout<<"Class2 final state variable value is : "<<class2.internalStateValue()<<endl;

return
0;
}





The output is as follows:

Friday, 6 March 2009

Simple example of Callback Functions

Here is a simple example introducing to the concept of callbacks in C++. Function Pointers will be used implicitly in demonstrating this example.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example showing how callback functions work in C++
#include<iostream>

using namespace
std;

int
adds(int a, int b)
{

return
a+b;
}


int
subs(int a, int b)
{

return
a-b;
}


int
DoIt(int x, int y, int (*c)(int, int))
{

cout<<"DoIt : "<<c(x,y)<<endl;
return
0;
}


int
main()
{

DoIt(3,4,adds);
DoIt(4,3,subs);

//subs by another name
int (*minus)(int,int) = subs;
DoIt(4,2,minus);

return
0;
}


Wednesday, 4 March 2009

Simple Function Pointers example

This example shows how function pointers work. There is also an example of how priority queues work.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//This program intents to show the use of function pointers
//This program also uses priority queues
#include<iostream>
#include<queue>

using namespace
std;

typedef
int (*fpRegCb)(int* i_p, int index);

int
funcA(int *val, int index)
{

cout<<"Func A: index = "<<index<<" val = "<<*val<<endl;
return
(*val + 10);
}


int
funcB(int *val, int index)
{

cout<<"Func B: index = "<<index<<" val = "<<*val<<endl;
return
(*val + 15);
}


class
someSimpleListType
{

private
:
someSimpleListType(); //This cant be used
public:
int
index;
int
*value;
fpRegCb callback;
someSimpleListType(fpRegCb cb, int *val, int idx):value(val),index(idx)
{

callback = cb;
};

//< operator is overloaded for use with priority queues. This will
//decide the priority of the new element, where it should be placed
const bool operator <(const someSimpleListType& sLT) const
{

return
(index < sLT.index);
}
};


priority_queue <someSimpleListType> someSimpleList;

int
main()
{

int
index=0;
int
*a=new int(22);
int
*b=new int(37);
int
*c=new int(62);

//The higher the priority, higher it is in the queue
someSimpleList.push(someSimpleListType(funcA, a, index++));
someSimpleList.push(someSimpleListType(funcB, b, index++));
someSimpleList.push(someSimpleListType(funcB, c, index++));
//The last push will end up top of queue as index(priority) is greatest

//Lets get all the elements from the list and process them
cout<<"Test 1"<<endl;
while
(!someSimpleList.empty())
{

someSimpleListType &sLT = someSimpleList.top();
cout<<"Callback["<<sLT.index<<"] = "<<sLT.callback(sLT.value,sLT.index)<<endl;
someSimpleList.pop();
}


//Since the priority queue is now empty, push some more elements
someSimpleList.push(someSimpleListType(funcA, a, index++));
someSimpleList.push(someSimpleListType(funcB, b, index++));
someSimpleList.push(someSimpleListType(funcB, c, index++));

//This time we will only process funcB and ignore funcA
cout<<endl<<"Test 2"<<endl;
while
(!someSimpleList.empty())
{

someSimpleListType &sLT = someSimpleList.top();
if
(sLT.callback == funcB)
{

cout<<"Callback["<<sLT.index<<"] = "<<sLT.callback(sLT.value,sLT.index)<<endl;
}

someSimpleList.pop();
}


return
0;
}