[C++] Another function pointer query - passing as arguments

Recommended Posts

Hello, I am trying to grasp function pointers, particularly to use as callbacks in my GUI. Can anyone explain what I have done wrong here, when trying to pass a function pointer?
class cTimer
{
public:
cTimer();

void SetCallback( void (*ptrTimeOut)( void ) );

void Start( float target );

bool Update( void );

void (*ptrTimeOut)( void );
//	void (cTimer::*ptrTimeOut)( void );
//	inline void TimeOut( void ) { (*this.*ptrTimeOut)(); }

protected:
float m_time;
float m_target;
};

// Then in my main class, cSimulationLayer

void cSimulationLayer::NextStage()
{
m_stage++;
}

void cSimulationLayer::Init()
{
m_timer				= new cTimer();
m_timer->SetCallback ( cSimulationLayer::*NextStage() );
// or.....
m_timer->SetCallback ( &(cSimulationLayer::NextStage()) );

}


I think I am close!

Share on other sites
Is cSimulationLayer::NextStage a static function?

Share on other sites
To enhance Nitage's answer: you can't treat non-static member function as normal functions. They need extra data to work (namely, a "this" pointer). However, static member function don't have this requirement, and thus can be used as normal, non member functions when it comes to catsing them to a function pointer.

Regards,

Share on other sites
Its not a static function.

I thought that it would be okay since its local to the function call thats supplying the function pointer... but I guess its not local to the cTimer class during the actual call.

In that case how do I supply a function pointer to the cTimer class?

I'm obviously wanting each instantiation of the timer to call a different function when it has expired:

m_timer->SetCallback( &(g_simulationLayer->NextStage()) );
m_timeOut->SetCallback( &(g_simulationLayer->RestartGame()) );
m_messageEventTimer->SetCallback( &(m_eventManager->RandomEvent()) );

When I do this sort of thing, the error is all about & needed a lhs value. I hoped the & would be providing the pointer!

Thanks

Si

Share on other sites
In that case, you need to somehow store both the member function address and the instance(the "this" pointer).

I strongly recommend to take a look at boost, especially boost::function and boost::bind(SC++L has similar functionality with mem_fun and bind1st/bind2nd but not as powerful). Using those, the code would simply become:

class cTimer {public:	cTimer();		void SetCallback( boost::function< void(void) > );...};m_timer->SetCallback( boost::bind(&cSimulationLayer::NextStage,&g_simulationLayer) );

Every non-static member function actually has one more parameter than it appears: the first parameter is always the "this" pointer, which is implicitly passed. For example, when you call g_simulationLayer.NextStage(), you actually call cSimulationLayer::NextStage(&g_simulationLayer).

What you do here is just "bind" the first parameter of cSimulationLayer::NextStage(the "this" pointer) to &g_simulationLayer.

You can even take this a step further and "bind" other parameters of the callback for later use. For example, let's say you have member function ChangeColor:

class SomeClass{  void ChangeColor(float r,float g,float b)  {  ...  }};

If you want timer1 to change the color of instance1 to (1,0,0) and timer2 to change the color of instance2 to (0,0,1):

timer1->SetCallback( boost::bind(&SomeClass::ChangeColor,&instance1,1,0,0) );
timer2->SetCallback( boost::bind(&SomeClass::ChangeColor,&instance2,0,0,1) );

From my experience this is extemely useful.

Create an account

Register a new account

• Forum Statistics

• Total Topics
628372
• Total Posts
2982305

• 10
• 9
• 13
• 24
• 11