redefining or adding a classes member function dynamically/ during execution - c++

Hey i'm trying to make a very simple GUI using SFML, and i want to be able to attach a function to my Button class in the constructor, as so the user can define what happens when the button is pressed.
I've worked a little before with GLUT and noticed these declerations:
glutReshapeFunc(Resize);
glutDisplayFunc(Draw);
Which apparently define what function should be called when the window is resized or displayed. I want something exactly like this for my button so upon construction you can define what function should be called. I want to be able to pass a function name just like glut, not having define a new class wich overides a virtual functin.
I also doubt it's possible however to pass parameters for these
called functions, as you never know what or how many there would be.
Am i right?
So anyway..... How do i accomplish this or something like it?? Thanks!

You can store a callback using e.g. std::function (for C++0x; boost::function is also available and has a similar interface).
#include <functional>
class Button {
public:
template<typename T>
explicit
Button(T const& t): callback(t) {}
void
press()
{
callback();
}
private:
std::function<void()> callback;
};
// example use with a lambda
Button b([] { do_stuff(); });
b.press(); // will call do_stuff

In C++ it's better to use virtual function approach to address such kind of problems. That's more maintainable at long run.
You can choose to redesign a little bit to your code, where you can have a common handle to various subclasses. Now based on subclass chosen you can call a particular function. For example:
class Shape
{
public:
virtual void Resize () = 0;
virtual void Draw () = 0;
};
class Triangle : public Shape
{
public:
// implement above to functions
};
class Square : public Shape
{
public:
// implement above to functions
};
Now, just pass the handle of Shape* wherever you want and call the above abstract methods;
void foo(Shape *p)
{
p->Resize();
}

(Rewrote everything), I had misread the question.
You seem to be wanting to pass plain old function pointers around to other functions. All you need to do is just pass the name of the function you want, but do so inside an if (or something like that) so the function passed is actualy what you want:
if(i am feeling lucky today){
glutDisplayFunc(DrawMyLuckyShape);
}else{
glutDisplayFunc(DrawAFoo);
}
The bad news is that since C is a nasty language you can't set up to pass extra parameters to your functions (ie, use closures). Therefore, you need to rely on a) the functions being passed some parameter quen being called or b) the functions looking at some global state.

Related

Passing states of StateMachine as parameter to a function pointer C++ OOP

I'm fairly new to the concept of function pointer in C++, so I don't know how to write my question properly. Please bear with me.
Basically, what I'm trying to do is to create a Button object whose constructor accepts a function pointer as its parameter. That function pointer points to a function which will change state of the StateMachine.
Here is the sample code (it doesn't work, and irrelevant bits have been stripped out)
Button.h
#include "StateMachine.h"
class Button
{
private:
void (*m_onclickAction)(); //a data member
public:
Button(void (*action)());
};
StateMachine.h (I didn't write it, I just use it with permission. So there should be no problem with the code, and I don't want to modify it)
#include <map>
template<class E, class T>
class StateMachine
{
public:
typedef void (T::*CallbackOnInitialise)();
typedef void (T::*CallbackOnExit)();
private:
T* m_pOwner;
E m_currentState;
// Maps to store function pointers to state functions.
std::map<E, CallbackOnInitialise> m_statesOnInitialise;
std::map<E, CallbackOnExit> m_statesOnExit;
public:
StateMachine(T* pOwner, E emptyState)
{
m_currentState = emptyState;
m_pOwner = pOwner;
}
void ChangeState(E statenext)
{
//do something to change the state
}
};
So that in my main Program class, I could be able to do something like this
#include "Button.h"
#include "StateMachine.h"
//Code to instantiate an StateMachine object goes here
Button* aButton = new Button(aStateMachine->ChangeState(NEW_STATE));
The problem is I can't think of a way to correctly pass the NEW_STATE, which is an enum declared in the Program class as the function pointer is expecting no parameter. I have tried tweaking around with it, but no success.
Any suggestion on how should I do it?
You have a couple of problems here. The first is that in your version you call the ChangeState member function when you create the Button instance. The second is that m_onclickAction is a pointer to a function, which is not the same as a pointer to a member function.
For this I suggest you look into std::function and std::bind:
class Button
{
std::function<void(int)> m_onclickAction;
public:
Button(std::function<void(int)> action) { ... }
};
Then you can create your button like this:
Button* aButton = new Button(
std::bind(&StateMachine::ChangeState, aStateMachine, NEW_STATE));
For callbacks boost::bind() and boost::function() is a very useful tool. So your Button class may look like this:
class Button
{
public:
typedef boost::function<void()> Callback;
Button( Callback clickAction );
private:
Callback m_onclickAction; //a data member
};
Code to pass StateMachine method with parameter then would be:
Button* aButton = new Button( boost::bind( &StateMachine::ChangeState, aStateMachine, NEW_STATE ) );
If you use C++11 you can replace boost::bind with std::bind and boost::function with std::function.
Tha library has a design bug.
The problem is that a function pointer is just a function pointer in C++ (not a closure) and therefore it doesn't have any context.
If you want to create a button that draws a blue circle you will need a global function that will draw a blue circle taking no parameters.
If you want another button to draw a yellow circle you will need another global function that draws a yellow circle taking no parameters.
More specifically the problem is that the library doesn't have any way to store in the button what is called a "context" to be able to pass your code a color to use to draw the circle.
C++11 has added something that reminds a bit closures (not the real thing because of lifetime issues that are hard to solve in any language without garbage collection) but they are not bare function pointers.
What you want to do is just impossible without changing the Button class unless you use some bad hack as the one you can see here that tries to emulate std::bind in C using bare function pointers.

std::bind inside of a class, general concept of an event system

I'm working on a library that's based upon a simple event-system.
For work with GUI elements ("controls"), these are needed a lot. For example, the Window class has got a bunch of events, like "onMouseMove", "onKeyPress", "onKeyRelease", .. However, the basic class for controls is the Control class. It has a virtual function draw (which obviously draws the control) and a virtual function connect which connects the control's and the main window's events (works similar to the Qt Signal-Slot-Concept).
But since the Event class takes an std::function<...> pointer as subject (=> Slot), I cannot simply connect a member function of a derived control class with an event of the window. As a workaround, I'm doing the following thing:
class A : public Control {
friend class Window;
public:
A(){
this->eventHandler = [this] () -> void {
if ( someCondition ) this->onSomeCondition.notify();
};
}
Event<> onSomeCondition;
protected:
std::function<void()> eventHandler;
void connect(Window *window){
window->onSomeHigherEvent.attach(&this->eventHandler);
}
void draw(...) const{
drawSome(...);
}
};
What this basically does is that it assigns a lambda function to the std::function<...> in the constructor and attaches that std::function<...> to the chosen event.
There is a major problem though: What happens if I instantiate a few more objects of that class? If I had the event handlers specified in the class, as a normal function like so:
void eventHandler() {
if ( someCondition ) this->onSomeCondition.notify();
}
And could assign that function to the std::function<...> using std::bind, which does not work for some reason, at least as long as I'm using the following call:
std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.
Anyways, the lambda-function-workaround seems to be less time efficient since it's not really built into the class. Is there a more efficient way to solve this problem? Maybe not by solving the lambda-function problem in particular but by changing the concept?
I'm not sure what your asking, since I can't find the question, but ...
std::bind(&A::eventHandler, this, std::placeholders::_1); // *this will not work since that's just a (reference to the?) copy to of the object.
This creates a callable object that has one unbound parameter, i.e. it expects to be called with one argument, which is not compatible with std::function<void()> because that is a function that expects to be called with no arguments. It's also not compatible with the eventHandler member function you show, because that too takes no arguments.
Maybe you just want to use std::bind(&A::eventHandler, this);

C++: Redefine one or the other operation in the child class

In the following code:
class GraphicalCardDeck : public CardDeck, public GraphicalObject {
public:
virtual void draw () {
return CardDeck::draw();
}
virtual void paint () {
GraphicalObject::draw();
}
}
GraphicalCardDeck gcd;
gcd->draw(); // selects CardDeck draw
gcd->paint(); // selects GraphicalObject draw
When in the class CardDeck there is a function named draw, and in the class GraphicalObject there is a function named draw.
The book mentions a problem when we do:
GraphicalObject* g = new GraphicalCardDeck();
g->draw(); // opps, doing wrong method!
Why will it call the wrong method? It will not call the function draw in the class CardDeck as we define?
Thank you.
Yes, it will call the function draw in the CardDeck as we defined. But that might be surprising to someone not familiar with the internals of our class:
GraphicalObject* g = new GraphicalCardDeck();
g->draw(); // opps, doing wrong method!
Someone that wrote this might expect that GraphicalObject::draw() is called (or at least an overwritten version of that function that provides the same functionality). Since our overwritten function provides completely different functionality (that required by CardDeck), from the perspective of the one writing the above code the "wrong" function is called (aka. not the one he intended to call).
So it works like you expected, but when just looking at the interface and without knowledge of the internal implementation one might expect different behavior.

How do I implement a callback in C++?

I want to implement a class in c++ that has a callback.
So I think I need a method that has 2 arguments:
the target object. (let's say
*myObj)
the pointer to a member function of
the target object. (so i can do
*myObj->memberFunc(); )
The conditions are:
myObj can be from any class.
the member function that is gonna be the callback function is non-static.
I've been reading about this but it seems like I need to know the class of myObj before hand. But I am not sure how to do it. How can I handle this? Is this possible in C++?
This is something I have in mind but is surely incorrect.
class MyClassWithCallback{
public
void *targetObj;
void (*callback)(int number);
void setCallback(void *myObj, void(*callbackPtr)(int number)){
targetObj = myObj;
callback = callbackPtr;
};
void callCallback(int a){
(myObj)->ptr(a);
};
};
class Target{
public
int res;
void doSomething(int a){//so something here. This is gonna be the callback function};
};
int main(){
Target myTarget;
MyClassWithCallback myCaller;
myCaller.setCallback((void *)&myTarget, &doSomething);
}
I appreciate any help.
Thank you.
UPDATE
Most of you said Observing and Delegation, well that's i exactly what i am looking for, I am kind of a Objective-C/Cocoa minded guy.
My current implementation is using interfaces with virtual functions. Is just I thought it would be "smarter" to just pass the object and a member function pointer (like boost!) instead of defining an Interface. But It seems that everybody agrees that Interfaces are the easiest way right? Boost seems to be a good idea, (assuming is installed)
The best solution, use boost::function with boost::bind, or if your compiler supports tr1/c++0x use std::tr1::function and std::tr1::bind.
So it becomes as simple as:
boost::function<void()> callback;
Target myTarget;
callback=boost::bind(&Target::doSomething,&myTarget);
callback(); // calls the function
And your set callback becomes:
class MyClassWithCallback{
public:
void setCallback(boost::function<void()> const &cb)
{
callback_ = cb;
}
void call_it() { callback_(); }
private:
boost::function<void()> callback_;
};
Otherwise you need to implement some abstract class
struct callback {
virtual void call() = 0;
virtual ~callback() {}
};
struct TargetCallback {
virtual void call() { ((*self).*member)()); }
void (Target::*member)();
Target *self;
TargetCallback(void (Target::*m)(),Target *p) :
member(m),
self(p)
{}
};
And then use:
myCaller.setCallback(new TargetCallback(&Target::doSomething,&myTarget));
When your class get modified into:
class MyClassWithCallback{
public:
void setCallback(callback *cb)
{
callback_.reset(cb);
}
void call_it() { callback_->call(); }
private:
std::auto_ptr<callback> callback_;
};
And of course if the function you want to call does not change you may just implement some interface, i.e. derive Target from some abstract class with this call.
One trick is to use interfaces instead, that way you don't need specifically to know the class in your 'MyClassWithCallback', if the object passed in implements the interface.
e.g. (pseudo code)
struct myinterface
{
void doSomething()=0;
};
class Target : public myinterface { ..implement doSomething... };
and
myinterface *targetObj;
void setCallback(myinterface *myObj){
targetObj = myObj;
};
doing the callback
targetObj->doSomething();
setting it up:
Target myTarget;
MyClassWithCallback myCaller;
myCaller.setCallback(myTarget);
The Observer design pattern seems to be what you're looking for.
You have a few basic options:
1) Specify what class the callback is going to use, so that the object pointer and member function pointer types are known, and can be used in the caller. The class might have several member functions with the same signature, which you can choose between, but your options are quite limited.
One thing that you've done wrong in your code is that member function pointers and free function pointers in C++ are not the same, and are not compatible types. Your callback registration function takes a function pointer, but you're trying to pass it a member function pointer. Not allowed. Furthermore, the type of the "this" object is part of the type of a member function pointer, so there's no such thing in C++ as "a pointer to any member function which takes an integer and returns void". It has to be, "a pointer to any member function of Target which takes an integer and returns void". Hence the limited options.
2) Define a pure virtual function in an interface class. Any class which wants to receive the callback therefore can inherit from the interface class. Thanks to multiple inheritance, this doesn't interfere with the rest of your class hierarchy. This is almost exactly the same as defining an Interface in Java.
3) Use a non-member function for the callback. The for each class which wants to use it, you write a little stub free function which takes the object pointer and calls the right member function on it. So in your case you'd have:
dosomething_stub(void *obj, int a) {
((Target *)obj)->doSomething(a);
}
4) Use templates:
template<typename CB> class MyClassWithCallback {
CB *callback;
public:
void setCallback(CB &cb) { callback = &cb; }
void callCallback(int a) {
callback(a);
}
};
class Target {
void operator()(int a) { /* do something; */ }
};
int main() {
Target t;
MyClassWithCallback<T> caller;
caller.setCallback(t);
}
Whether you can use templates depends whether your ClassWithCallback is part of some big old framework - if so then it might not be possible (to be precise: might require some more tricks, such as a template class which inherits from a non-template class having a virtual member function), because you can't necessarily instantiate the entire framework once for each callback recipient.
Also, look at the Observer Pattern and signals and slots . This extends to multiple subscribers.
In C++, pointers to class methods are hardly used. The fact that you called in - it is delegates and their use is not recommended. Instead of them, you must use virtual functions and abstract classes.
However, C++ would not have been so fond of me, if it not supported completely different concepts of programming. If you still want delegates, you should look towards "boost functional" (part of C + +0 x), it allows pointers to methods of classes regardless of the class name. Besides, in C++ Builder has type __closure - implementation of a delegate at the level of the compiler.
P.S. Sorry for bad English...

C++ function pointers and classes

Say I have:
void Render(void(*Call)())
{
D3dDevice->BeginScene();
Call();
D3dDevice->EndScene();
D3dDevice->Present(0,0,0,0);
}
This is fine as long as the function I want to use to render is a function or a static member function:
Render(MainMenuRender);
Render(MainMenu::Render);
However, I really want to be able to use a class method as well since in most cases the rendering function will want to access member variables, and Id rather not make the class instance global, e.g.
Render(MainMenu->Render);
However I really have no idea how to do this, and still allow functions and static member functions to be used.
There are a lot of ways to skin this cat, including templates. My favorite is Boost.function as I've found it to be the most flexible in the long run. Also read up on Boost.bind for binding to member functions as well as many other tricks.
It would look like this:
#include <boost/bind.hpp>
#include <boost/function.hpp>
void Render(boost::function0<void> Call)
{
// as before...
}
Render(boost::bind(&MainMenu::Render, myMainMenuInstance));
You can make a wrapper function void Wrap(T *t) that just calls t->Call() and have Render take such a function together with an object. That is:
void Wrap(T *t)
{
t->Call();
}
void Render(void (*f)(T *), T *t)
{
...
f(t);
...
}
What about what C++ FAQ: Pointers to members says?
I did so once by defining a global function "Call" which accepts a pointer to your intance as member
void CallRender(myclass *Instance)
{
Instance->Render();
}
So render becomes:
void Render(void (*Call)(myclass*), myclass* Instance)
{
...
Call(Instance);
...
}
And your call to render is:
Render(CallRender, &MainMenu);
I know it's ugly, but worked for me (I was using pthreads)
You can't call a member function from a pointer unless you have a reference to the object as well. For example:
((object).*(ptrToMember))
So you won't be able to acheive this without changing the signature of your render method. This article explains why this is generally a bad idea.
A better way might be to define a "Renderer" interface which your classes that have render methods can implement and have that be the parameter type of your main Render method. You could then write a "StaticCaller" implementation to support the calling of your static methods by reference.
eg (My C++ is really rusty, I haven't compiled this either).
void Render(IRenderer *Renderer)
{
D3dDevice->BeginScene();
Renderer->Render();
D3dDevice->EndScene();
D3dDevice->Present(0,0,0,0);
}
// The "interface"
public class IRenderer
{
public:
virtual void Render();
};
public class StaticCaller: public IRenderer
{
void (*Call)();
public:
StaticCaller((*Call)())
{
this->Call = Call;
}
void Render()
{
Call();
}
};
All this is pretty boilerplate but it should make for more readability.
You can declare a function pointer to a member function of class T using:
typedef void (T::*FUNCTIONPOINTERTYPE)(args..)
FUNCTIONPOINTERTYPE function;
And invoke it as:
T* t;
FUNCTIONPOINTERTYPE function;
(t->*function)(args..);
Extrapolating this into useful currying system with variable arguments, types, return values, etc, is monotonous and annoying. I've heard good things about the aforementioned boost library, so I'd recommend looking into that before doing anything drastic.