PDA

View Full Version : Method pointers as arguments




Duke Leto
Jul 30, 2009, 10:00 PM
As discussed before, I started making my own view class for GLUT, and I made an event handling method that checks for hit rectangles and calls the appropriate method that was passed.

The method looks like this:

void View::mouseEvent(int x, int y, int button, void (View::*mfunc)(int, int, int))
{
if(pointHitsView(x, y)) (this->*mfunc)(x, y, button);

Enumerator* myEnum = subviews->getEnumerator();
if(myEnum != NULL)
{
View* nextView = (View *)myEnum->getCurrentObject();
while(nextView != NULL)
{
// check hit rect for subview
if(nextView->pointHitsView(x,y)) (nextView->*mfunc)(x, y, button);
nextView = (View *)myEnum->nextObject();
}
}
}


The function compiles with no errors, but when I actually use it, there is one error.

void mouse(int button, int state, int x, int y)
{
void (View::*eventFunc)(int, int, int) = mouseDownAtPosition;
// this gives me "mouseDownAtPosition was not declared in scope"
outerBox->mouseEvent(x, y, button, eventFunc);
testCell->mouseEvent(x, y, button, eventFunc);
}


The mouse() function is in the main.cpp, which handles drawing, and GLUT events.

The mouseEvent() method is in View.cpp.

Why am I getting this error?



autorelease
Jul 30, 2009, 11:51 PM
Looks like
void (View::*eventFunc)(int, int, int) = mouseDownAtPosition;
should be
void (View::*eventFunc)(int, int, int) = &View::mouseDownAtPosition;

Though... do you really need method pointers for this? Couldn't you just require each View subclass to override a method called mouseDown?

void View::mouseEvent(int x, int y, int button)
{
if(pointHitsView(x, y)) mouseDown(x, y, button);

Enumerator* myEnum = subviews->getEnumerator();
if(myEnum != NULL)
{
View* nextView = (View *)myEnum->getCurrentObject();
while(nextView != NULL)
{
// check hit rect for subview
if(nextView->pointHitsView(x,y)) nextView->mouseDown(x, y, button);
nextView = (View *)myEnum->nextObject();
}
}
}


Also note that there's a bug in that method; it only works with a single level of nested views. (i.e. it will fail if you try to click on a subview of a subview of a subview.) You'll need to recursively descend the view hierarchy.

mslide
Jul 31, 2009, 07:37 AM
Are you sure you want to be using pointers to (non-static) member functions? This is a hairy subject and is not as simple as using pointers to C functions. I recommend not doing it.

Duke Leto
Jul 31, 2009, 08:31 AM
Thanks for the bug notice!

It works now.