Is it possible to put cbfun's into a class?

q66680 wrote on Thursday, March 13, 2014:

hi.i want to put my cbfuns into my class.something like that:

class scene{

public:
virtual void mouse_callback(GLFWwindow*, int, int, int);
};

i tried a few case.But no lucky.i always get func signature error something like:

error: cannot convert ‘void (scene::)(GLFWwindow, int, int, int)’ to ‘GLFWmousebuttonfun {aka void ()(GLFWwindow, int, int, int)}’ for argument ‘2’ to ‘void (* glfwSetMouseButtonCallback(GLFWwindow*, GLFWmousebuttonfun))(GLFWwindow*, int, int, int)’

So i wonder whether it is possible.if so how?

it might be better to add this signature to all cbfuns. for above e.g:

void mouse_callback(GLFWwindow*, int, int, int,void* userdata);

i think @userdata signature above have many use case and many help to developer.

Doing so developer can share his data along cbfuns.
i noticed wayland/weston use this approach for its cbfuns.

What about you? performance may be affected.

dougbinks wrote on Thursday, March 13, 2014:

Pointers to C++ member functions can’t be used in this way (try searching C++ pointer to member function for more information).

A typical approach to get around this is a static function and data member, something like:

class scene{
public:
static scene m_Scene;
static void mouse_callback_static(GLFWwindow* window, int button, int action, int mods)
{
    m_Scene.mouse_callback(window,button,action,mods);
}
virtual void mouse_callback(GLFWwindow* window, int button, int action, int mods);
};

You can then use mouse_callback_static as the callback function. To have different scene instances for different windows would require some form of mapping between window and scene, for example using std::map or similar.

q66680 wrote on Thursday, March 13, 2014:

it has helped that you said.Thank you.

EDIT:it’s ok that to put callback func into class by adding “static” keyword.

But i cannot virtualize it.Because of:

is it reality?

dougbinks wrote on Monday, March 31, 2014:

To use virtual members, you need to do this by setting a point to the base class with an instance of a derived class. You can do this as follows:

class scene{
public:
static scene* m_pScene;
static void mouse_callback_static(GLFWwindow* window, int button, int action, int mods)
{
    m_pScene->mouse_callback(window,button,action,mods);
}
virtual void mouse_callback(GLFWwindow* window, int button, int action, int mods);
};

class myDerivedscene : public scene
{
    myDerivedscene()
    {
        m_pScene = this;
    }
};