C++ function pointer errors

Started by
7 comments, last by joanusdmentia 17 years, 11 months ago
i have made a static image class which i am able to pass void function into the class for event handling like mouse over mouse click and so on... now this used to work when my application wasnt a class, and the function that i would pass was not embedded inside a class. ive read some information about how you have to pass the function differently if its embedded in a class but i cant figure it out... the compiling error i get is cannot convert parameter 2 from 'void (__thiscall Application::* )(void)' to 'void (__cdecl *)(void)' button is the object im trying to create...and im passing the exit function into the class so that it can react to an event.. class Application { ..application stuff void setup() { Button* button = guiMgr->createButton("test","button.png"); button->setEventHandler(Button::MOUSECLICK,Exit); } void Exit() { } }; this doesnt work though...it works if i take the exit function and move it outside of the class....but i dont want that... can someone help me out here thanks
Advertisement
The sad fact is that you can't have pointers to member functions.. one way to go over it is to do a global function that calls the member function, like

Application *g_app; // initialized somewherevoid handler(){   g_app->handler();}


And then you register handler() for the callback.
are you sure about that..it just seems like a hack to do it that way and i thought id seen it done before in the past...

ive used CEGUI and they do similar event handling where you pass a function to the button that handles the event...and the function could be part of a class with no errors..
Quote:Original post by clb
The sad fact is that you can't have pointers to member functions..


You can have pointers to member functions, they just aren't compatible with pointers to non-member functions (static member functions are included with the latter). If an API expects a pointer to non-member, you can't give it a pointer to member, and conversely.

This is why, if you have control over the interface, you should design it to accept something like boost::function, which takes care of erasing the differences between those entities.

If not, you're screwed. See this thread for a similar question.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
You can have function pointers to member function. But rather than going through it all here, I'm going to point you here. Thats the best function pointer tutorial I've found, and it should answer all your questions about function pointers. I think you would be especially interested in functors.
I think you can, actually. I'm still somewhat new to C++, but I was recently helped with a very similar problem (see this
). I was working with a class array of pointers to class functions and received the same compiler error, and by adding a "(this->*...)" to my array of f.p.'s I got it to compile and work successfully. It's a matter of either scope visibility or the need for an object instance (this) reference.

Try adding "Application::", "this.", "Application::*", "(this->...)", or some such thing... one of these should do the trick. :)
Quote:Original post by Perost
You can have function pointers to member function.
Yeah, was just about to say...

The syntax for defining a pointer to a member function is something like so:

int (MyClass::*myFunctionPtr)(int) = NULL;

Then you assign it some value like such:

myFunctionPtr = &MyClass::someFunction;

Check out Perost's link for further info.
thanks for the help everyone....ive gotten it to work by just making my function static...

id rather not have that but im not sure right now how i have to change my button class so that i pass in a non-static member function to it..

right now the pointer is passed to a function like so

void Button::setEventHandler(int type,void(*eventPtr)(void))

is there an easy way to change this so i can pass a non-static member function to it
// Originalclass Button{public:    void setEventHandler(int type, void(*eventPtr)(void));private:    std::map<int, void(*)(void)> m_handlers;};// Would become...class Button{public:    void setEventHandler(int type, const boost::function<void()>& handler);private:    std::map<int, boost::function<void()> > m_handlers;};// Or better yet...class Button{    typedef boost::function<void()> EventHandler;public:    void setEventHandler(int type, const EventHandler& handler);private:    std::map<int, EventHandler> m_handlers;};// Usageclass Application{    void setup()    {        Button* button = guiMgr->createButton("test","button.png");        button->setEventHandler(Button::MOUSECLICK,             boost::bind(&Application::Exit, this) );    }    void Exit() { }};


boost::function provides a generic interface to both member and non-member function pointers (amongst other things). boost::bind provides a mechanism for binding values to a function, in this case it's being used to bind the this pointer as the first parameter of the call to Application::Exit(). Normally when calling Application::Exit() you pass an implicit first parameter which is a pointer to the object (thus the function really takes 1 parameter and is incompatible with your function pointer), using boost::bind makes it look like it takes 0 parameters but since the result is an object and not a function pointer you need to use boost::function to store it somewhere.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V

This topic is closed to new replies.

Advertisement