Re: Function pointer and functor problem
On Oct 24, 10:31 pm, "lali.cpp" <lali....@gmail.com> wrote:
I am having a doubt about function pointers and functors. I know that
the signatures of a function pointer and a pointer to a class member
function are different. However signature of a global function and
signature of a static class function are compatible.
Here is what i want to achieve:
There are 2 unrelated classes say A and B ( they are unrelated and
hence i don't want to make them part of any inheritance structure)
I have written a timer class in which i can register multiple timers,
it takes a timeout value and a function pointer that would be invoked
when the timer times out i.e basically i want a callback mechanism on
timeout. So internally the timer is using a queue to store all these
function pointer and all these function pointers have signature void
(*ptr)( );
So the queue would be like:
typedef void (*ptr)( );
queue<ptr> timer_queue;
The problem is i want to invoke the member function of classes A and
B when a timer expires so that i can change the state of object of
class A or B.
To call member functions you need an extra piece of data: an object to
call the member function upon. Thus, your queue should be declared
like this:
struct callback
{
typedef void fun_type(void* arg);
fun_type* fun;
void* arg; // <--- object pointer
callback(fun_type* f, void* a)
: fun(f)
, arg(a)
{}
void invoke() { fun(arg); }
};
typedef std::queue<callback> timer_queue;
Let me make it clear( i really suck in communication, sorry for that)
class A
{
public:
A( ):a(5)
{
}
void timerExpired( )
{
cout<<a;
}
private:
int a
};
class B
{
public:
B():name("JOHN")
{
}
void timerExpired( )
{
cout<<name;
}
private:
string name;
};
So i want a timer that can help me code the below code :( the
following code may not be syntactically correct )
Timer timer;
A obj_of_a;
B obj_of b
// please remember that timer uses a queue of function pointers
timer.registerTimer(A::timerExpired,6)// expires after 5 seconds
timer.registerTimer(B::timerExpired,2) // expires after 2 seconds
Problem is that these two functions are not static and if i make them
static how would i change the state of the objects ( static functions
don't have this pointer)
You make them static and make them accept the extra argument, which is
the pointer to the object:
class A
{
public:
A()
: a(5)
{}
static void timerExpired(void* arg)
{
A* that = static_cast<A*>(arg);
std::cout << that->a;
}
private:
int a;
};
class B
{
public:
B()
: name("JOHN")
{}
static void timerExpired(void* arg)
{
B* that = static_cast<B*>(arg);
std::cout << that->name;
}
private:
std::string name;
};
Then you do:
struct Timer
{
// ...
void registerTimer(callback cb, int timeout);
// ...
};
Timer timer;
A obj_of_a;
B obj_of_b;
// please remember that timer uses a queue of function pointers
timer.registerTimer(callback(A::timerExpired, &obj_of_a),6); //
expires after 5 seconds
timer.registerTimer(callback(B::timerExpired, &obj_of_b),2); //
expires after 2 seconds
Is it even possible i.e to store pointers to member functions (of
different classes) in a queue and invoke them.
It can be done if i make A and B derived from class C containing a
virtual function timerExpired and then storing a functor instead of a
function pointer but i don't want to do that as in my case A and B are
not at all related.
Can it be done somehow using wrapper static functions of classes A and
B ??
Please provide some hint or guidance.
Another way is to use boost::function<void()> as your callback
functor. This way you can use regular function pointers as well as
member function pointers and more. Here is your example once more:
#include <queue>
#include <string>
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function<void()> callback;
typedef std::queue<callback> timer_queue;
class A
{
public:
A()
: a(5)
{}
void timerExpired()
{
std::cout << a;
}
private:
int a;
};
class B
{
public:
B()
: name("JOHN")
{}
void timerExpired()
{
std::cout << name;
}
private:
std::string name;
};
struct Timer
{
// ...
void registerTimer(callback cb, int timeout);
// ...
};
int main()
{
Timer timer;
A obj_of_a;
B obj_of_b;
// please remember that timer uses a queue of function pointers
timer.registerTimer(boost::bind(&A::timerExpired, &obj_of_a),
6); // expires after 5 seconds
timer.registerTimer(boost::bind(&B::timerExpired, &obj_of_b),
2); // expires after 2 seconds
}
Please see:
http://www.boost.org/doc/libs/1_36_0/doc/html/function.html
http://www.boost.org/doc/libs/1_36_0/libs/bind/bind.html
--
Max
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]