If I'm understanding you correctly, it sounds like templates may be a good way to go. You may want to spend some time learning about them.
(Disclaimer: I'm just typing this here without testing so my syntax might not be quite right. I also haven't given this much thought, so it's possible there are better solutions)
Your register function in your Button class could look something like this:
template <typename T>
void registerCallback(std::function<void(T *, int)> c)
{
callback = c;
}
Calling the function would then look something like this:
myButton.registerCallback<otherClass>(&otherClass::myCallback);
Note that your whole button class will also need to be a template so that its member variable that stores the callback can handle any type. The member variable would be declared as
std::function<void(T *, int)> callback
Where T is the generic type.
The code in the stackoverflow answer allows you to register the callback function first and then later decide which object you want to actually "callon". Alternatively, you could pass in the object at the time you do the register. This will allow you to use std::bind such that your button class no longer needs to be generic.
template <typename T>
void registerCallback(T* object, std::function<void(T *, int)> c)
{
callback = std::bind(c, object, std::placeholders::_1);
}
so the callback member variable can simply be
std::function<void(int)> callback
and the callon function would likewise be modified such that you no longer pass in the object to call because the button class would already know which one.
Hopefully this gives you some ideas on one way you could proceed.
There's no complexity with callbacks. Forget inheritance and virtual functions.
class Button
{
std::function<void()> callback;
};
class Menu
{
void open();
};
Button button;
Menu menu;
button.callback = std::bind(&Menu::open, std::ref(menu));
// or...
button.callback = [&]{menu.open();};
PS: remember this is the SFML forum ;)
Thank you Arcade and Laurent for your replies, they were both useful and I got a minimal example working while I decide exactly how to implement in my program. Thank you!
#include <functional>
#include <iostream>
int main()
{
// There's no complexity with callbacks. Forget inheritance and virtual functions.
class Button
{
public:
std::function<void()> callback;
};
class Menu
{
public:
void open() {
std::cout << "I was opened" << std::endl;
};
};
Button button;
Menu menu;
//button.callback = std::bind(&Menu::open, std::ref(menu)); // Bind implementation
// or...
button.callback = [&] {menu.open(); }; // Lamda implementation
button.callback(); // Returns "I was opened"
return 0;
}
Recoil, I'm glad I could ask a useful question.