Advertisement

Function Pointers + Classes = ??

Started by March 03, 2001 03:09 AM
9 comments, last by Michael Cleaver 23 years, 11 months ago
When trying to neaten some of my code by restructuring it into a class I have run across a problem which I''ve been stuck on before but always gave up. This time, I won''t give up unless its impossible >. Heres the situation - my games'' GUI is based upon a single window class which stores pointers to the window objects(push buttons, text boxes, picture boxes etc..) which are all seperate classes. The main window class stores a pointer to a function which is used as the callback function for all of the buttons. This is how I did it.. class GUIWindow { public: ..... void (*CallbackFunction)(GUIWindow * wnd,void * data1,void * data2); }; The the pointer is set using Window->CallbackFunction = cbf; where cbf was a locally defined function in the ''main'' cpp file where windows were created and used. Problems started when I tried to integrate all the window usage and manipulation code specific to my game into a class - ''GameMenus''. The function ''cbf'' became a member of this class and if I try ''CallbackFunction = cbf'' from any function within this class i get the compiler error... C:\programming\IsoGL\Source\GameMenus.cpp(37) : error C2440: ''='' : cannot convert from ''void (__thiscall GameMenus::*)(class GUIWindow *,void *,void *)'' to ''void (__cdecl *)(class GUIWindow *,void *,void *)'' There is no context in which this conversion is possible Is there any way which this can be achieved?? Thanks, Michael Cleaver
Try making the member function static, and pass the object as another parameter to the function. Then have the static function call the member function on the object, like so:


class window
{
public:
static void callback_function(window* object, ...)
{ object->callback(...); /* calls member function */ };

private:
void callback(...); // member function
};

// Don''t forget to declare it outside the class too
void window::callback_function(window* object, ...);


where the ellipses "..." means the parameters you are already using.

Controls such as buttons and check boxes and the like are normally written to send stuff to their parent (which they should already have a pointer to) using a virtual member function declared in window, as opposed to passing around function pointers and object pointers manually.
Advertisement
Check this out:
"Creating a Function Pointer to a C++ Member Function"

Thanks for the replies, but I think my original post wasn''t clear enough. Both solutions can''t be used for my problem. The function pointer void (*CallbackFunction)(GUIWindow*,void*,void*) is a member of the GUIWindow class. I''m trying to point this at a function which is a member of another class - the GameMenus class. The GameMenus class contains a fucntion like so...

class GameMenus
{
public:
void CreateWindows();
void Callback(GUIWindow * wnd,void * data1,void * data2);
};

Now in the function CreateWindows() I create a GUIWindow object and try to set its ''CallbackFunction'' using Window->CallbackFunction = Callback;
This is where the problem occurs.

This is driving me mad!!

Sorry for the unclear posts but I''m finding this situation very difficult to explain.



Hello

I''m really not too sure what you are trying to do but look at ''virtual functions''. They maybe the answer to your problem
Why not just pass GameMenus by reference to GUIWindow?

class GUIWindow
{
public:
// constructors/destructors etc
SetCreator(GameMenu& gm)
{
m_gamemenus = &gm
}

Callback()
{
m_gamemenus->Callback(this, 0, 0); //whatever
}

protected:
GameMenus* m_gamemenus;
};

class GameMenus
{
public:
CreateWindows()
{
GUIWindow* wnd = new GUIWindow(/*params*/);
wnd->SetCallback(*this);
}

protected:

};

I think you need to revisit the design of your classes. Having to use function pointers in an OO language, in this context, is a sign of a weak design (no offense).

Can you ptovide more information on what you are trying to do? Maybe then we (i.e. ppl here) can provide more useful help



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Advertisement
Dire Wolf: I can''t use your method because I am trying to make my game engine (including the base code for the GUI) as seperate as possible from the code of the actual game. Id like my game to manage its windows using a single class - GameMenus. The engine can not rely on the existance of the GameMenus class (so that I can use it in different situations), only on the existance of a Callback function. With the structure I desire, the callback function is a member of the GameMenus class which what is causing all the problems (it works fine when its external to the class but it doesn''t have access to all of the other members and I would prefer not to make a temporary hack). Hope that clears the situation a little more...

You should probably be using a combination of has-a and is-a relationships.

Can you explain the purpose of GUIWindow, GameMenus and the relationship to your engine?

Once I know more I can give you a hand



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
For instance, I''m not sure of the purpose of the callback in the GameMenus class ( which I''d have named WindowManager based on its purpose )

As I understand it, GameMenus creates Windows and registers itself (and hence its Callback method) with them. These GUIWindows in turn use this callback via their stored reference to GameMenus (via function pointer or whatever). What is the purpose of the callback? Is it for notification of events? Can you provide small description of program flow/logic (related to interaction of GUIWindow and GameMenus).

I have an idea but I need to know more first.



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
I''m not sure if I really understand what you want, but try the following:

class GUIWindow
{
public: .....
void (GUIWindow::*CallbackFunction)(GUIWindow * wnd,void * data1,void * data2);
};

Thiss will declare CallbackFunction as a pointer to a member. For calling you may need either the .* ot ->* operator.
However I don''t know why you can''t solve this more elegant by using virtual functions.

This topic is closed to new replies.

Advertisement