I’ve been looking at a few signal/slot implementations, and with no exception they were pretty complicated, some even relying on MOC and extra code generation, like those of Qt.
I realize there are concerns such as threat safety and whatnot, but for a simple, single threaded scenario, is there something wrong with going for a simple approach, something like:
typedef void (*fPtr)();
class GenericButton
{
public:
GenericButton() : funcitonToCall(nullptr) {}
void setTarget(fPtr target) {
funcitonToCall = target;
}
void pressButton() {
if (funcitonToCall) funcitonToCall();
}
private:
fPtr funcitonToCall;
};
void doSomething(){
std::cout << "doing something..." << std::endl;
}
void doSomethingElse(){
std::cout << "doing something else..." << std::endl;
}
int main(){
GenericButton myButton;
myButton.setTarget(doSomething);
myButton.pressButton();
myButton.setTarget(doSomethingElse);
myButton.pressButton();
}
It is still possible to chain several other methods and pass data in the target void function. So why all the complexity for something as trivial as executing some code when a button gets clicked.
This is a perfectly sensible solution, but don’t restrict yourself to just function pointers. Use
std::functionwhich allows you to bind things, call member functions on objects, use lambdas and still resort to a function pointer where it makes sense. Example:There’s almost always a better solution in C++ than function pointers.
If you don’t have
std::function/std::bindthere’s always alternatives in boost that work and you can roll your ownstd::functionalternative without too much work which would be worth doing if you want to make something like this.Most of the signal/slot mechanisms that are around date from a time when things like
boost::bindwas not a viable option. Those days are long gone and you can get something standard and more flexible for little more complexity than just a function pointer.