Pointer to member function the strange way - c++

I have a class, Mouse, than handles mouse events. It consists of a number of static functions for simple "where is it, etc" calls, but it also has a few non-static members, namely some event-handling stuff when it's used as an object. I'm having trouble, however with how I can allow any object to subscribe to the events. In my Mouse.h file I have the follwing declarations: (excuse the syntax errors, this is from memory)
typedef void (*MouseEvent)(Point pos,MouseButton button)
class Mouse {
MouseEvent m_downEvent;
//...
void HookMouseDown(MouseEvent handler);
void OnMouseDown();
}
...and in the implemenation...
void Mouse::HookMouseDown(MouseEvent handler) {
if (handler != NULL) m_downEvent = handler;
}
void Mouse::OnMouseDown() {
if (m_downEvent != NULL) m_downEvent(m_pos,m_button);
}
Now in my subscriber's code, It seemed logical to hook up the event this way:
m_mouse.HookMouseDown(&MyClass::MouseDown);
But my compiler (MVC2008) doesn't like the fact that I'm passing it a pointer-to-member-function rather a pointer-to-free-function. After some research on here, I discovered that changing my typedef to
typedef void (MyClass::*MouseEvent)(Point pos,MouseButton button)
it won't complain and will work fine, but the problem is that this restricts subscribers to the event to only MyClass objects.
Will I have to get templates involved to allow any object to subscribe to these events? Or would it be bad design to allow anything to consume mouse events in the first place?

it won't complain and will work fine, but the problem is that this restricts subscribers to the event to only MyClass objects.
Nope, you will be able to 'invoke' that member through derived class instances as well.
Regardless, the problem has been solved many times over using std::mem_fun_ptr (c++03) std::function<> (c++0x), std::bind (c++0x) and boost::bind.
Here is a full sample, see it live on https://ideone.com/mut9V:
#include <iostream>
struct MyBase
{
virtual void DoStuff(int, float) { std::cout << "Base" << std::endl; }
};
struct MyDerived : MyBase
{
virtual void DoStuff(int, float) { std::cout << "Derived" << std::endl; }
};
int main()
{
typedef void (MyBase::*memfun)(int, float);
memfun event(&MyBase::DoStuff);
MyBase base;
MyDerived derived;
(base.*event)(42, 3.14);
(derived.*event)(42, 3.14);
}

To make the class Mouse handle pointers to member-functions of arbitrary classes, you could make it a template:
template<class T>
class Mouse {
typedef void (T::*MouseEvent)(Point pos,MouseButton button);
MouseEvent m_downEvent;
//...
void HookMouseDown(MouseEvent handler);
void OnMouseDown();
}

Or would it be bad design to allow anything to consume mouse events in the first place?
I think it is quite nice to use an event based design. On the other hand it is a pain in the ass to support both free functions and member functions. Especially if you have also to supply the instance which calls this function.
Coincidentally I stumbled upon a Delegate implementation which exactly deals with this matter. Have a look at this interesting article.
The HookMouseDown could now return a reference to an internal delegate, which then can be bound to either a free function or a member function:
mouse.HookMouseDown().Bind<MyClass, &MyClass::MyMember>(myinstance);

You really want std::function and std::bind/lambdas (function/bind also available in Boost). This more than adequately solves the problem.

Related

Store Function Pointers to any Member Function

My Event Manager
For a event manager I need to store many pointers to functions in a vector to call them when the event is triggered. (I will provide the source code of the EventFunction helper class at the end of this question.)
// an event is defined by a string name and a number
typedef pair<string, int> EventKey;
// EventFunction holds a pointer to a listener function with or without data parameter
typedef unordered_map<EventKey, vector<EventFunction>> ListEvent;
// stores all events and their listeners
ListEvent List;
Registering an listener could be done by calling the first or the second function, depending on if you want receive additional data or not. (This code is from my event manager class.)
public:
typedef void (*EventFunctionPointer)();
typedef void (*EventFunctionPointerData)(void* Data);
// let components register for events by functions with or without data parameter,
// internally simple create a EventFunction object and call the private function
void ManagerEvent::Listen(EventFunctionPointer Function, string Name, int State);
void ManagerEvent::Listen(EventFunctionPointerData Function, string Name, int State);
private:
void ManagerEvent::Listen(EventFunction Function, string Name, int State)
{
EventKey Key(Name, State);
List[Key].push_back(Function);
}
Member Function Pointers
That code doesn't work because I store function pointers but not member function pointers in my List. All these pointers should be member function pointers because a component like ComponentSound will listen to the event "PlayerLevelup" with on of its member functions ComponentSound::PlayerLevelup to play a nice sound if the event is triggered.
A member function pointer in C++ looks like this.
// ReturnType (Class::*MemberFunction)(Parameters);
void (ComponentSound::*PlayerLevelup)();
The problem is, any component class should be able to listen for events, but storing the member function pointers in the event manager requires me to specify the listening class. As you can see in the example, I need to specify ComponentSound but the event manager should simply have a vector of member function pointers to any class.
Question
An Answer to one of these question would help me a lot.
How can I store function pointers to any member function in a vector in my event manager? (Maybe it helps that all the listening functions are inherited from one abstract class Component.)
How can I design my event manager in another way to reach the aimed functionality? (I want to use string and int keys for messages.)
I tried to keep my question general but if you need more informations or code please comment.
Assignments
In my vector of member function pointers I use EventFunction instead of only a pointer to provide two message types. One with, and one without a data parameter.
class EventFunction
{
private: EventFunctionPointer Pointer; EventFunctionPointerData PointerData; bool Data;
public:
EventFunction(EventFunctionPointer Pointer) : Pointer(Pointer), PointerData(NULL), Data(false) { }
EventFunction(EventFunctionPointerData PointerData) : PointerData(PointerData), Pointer(NULL), Data(true) { }
EventFunctionPointer GetFunction() { return Pointer; }
EventFunctionPointerData GetFunctionData() { return PointerData; } bool IsData() { return Data; }
void Call(void* Data = NULL){ if(this->Data) PointerData(Data); else Pointer(); }
};
You will have to use std::function. This is the only way to achieve a generic callback. As soon as you involve function pointers instead of function objects, it is not generic, will never be generic, and can never be made to be generic.
unordered_map<string, vector<std::function<void()>>>
Function pointers are bad and should never be explicitly used in C++, only passed to templates like std::bind and std::function's constructor, and member function pointers are even worse.
You can use functors to achieve this. If you wrap a functor around your member functions you can make a vector out of functors. A functor looks like this:
template <class T> class MyFunctor
{
private:
T* ObjectPtr;
void (T::*MemberFunction) ();
public:
void operator () ()
{
return (*this->ObjectPtr.*this->MemberFunction)();
}
};
So basically a functor overrides the () operator and returns the member function stored in the functor class. Functors can be quite complex if you want them to work with different signatures but in this article you can get further information.
http://www.codeproject.com/Articles/7112/Pointers-to-Member-Functions-and-Functors
Not a direct response, so bear with me.
Before we start: This is generally referred to as the Observer pattern, you might find lots of confused information on the web about it, and many failed implementations, but who knows you might also strike gold.
Okay, so first the question has a fundamental flaw: it fails to consider that capturing object references is tricky, because object lifetimes are bounded.
Therefore, even before we delve into the specifics of an implementation we need to ask ourselves how to handle stale references. There are two basic strategies:
Not having stale references, this implies that registered objects unregister themselves automatically upon destruction. The mechanism can be factored out in a base class.
Having a way to tell good and stale references apart when inspecting them, and lazily collecting the stale ones. The mechanism can be enforced using a shared_ptr/weak_ptr pair and realizing that weak_ptr are observers of the shared_ptr.
Both solutions are viable and neither implementation is perfect. The base class mechanism assumes you can actually modify your class hierarchy while the weak_ptr trick assumes that all observes will be heap-allocated and their lifetime controlled by a weak_ptr.
I will make an example using shared_ptr (and make use of a number of C++11 facilities, though none is mandatory here):
class EventManager {
typedef std::unique_ptr<Observer> OPtr;
typedef std::vector<OPtr> Observers;
public:
// Callback observers of "name"
// Returns the number of observers so invoked
size_t signal(std::string const& name) const {
auto const it = _observers.find(name);
if (it == _observers.end()) { return 0; }
Observers& obs = it->second;
size_t count = 0;
auto invoker = [&count](OPtr const& p) -> bool {
bool const invoked = p->invoke();
count += invoked;
return not invoked; // if not invoked, remove it!
};
obs.erase(std::remove_if(obs.begin(), obs.end(), invoker), obs.end());
if (obs.empty()) { _observers.erase(it); }
return count;
}
// Registers a function callback on event "name"
void register(std::string const& name, void (*f)()) {
_observers[name].push_back(OPtr(new ObserverFunc(f)));
}
// Registers an object callback on event "name"
template <typename T>
void register(std::string const& name, std::shared_ptr<T> const& p, void (T::*f)()) {
_observers[name].push_back(OPtr(new ObserverMember<T>(p, f)));
}
private:
struct Observer { virtual ~Observer() {} virtual bool invoke() = 0; };
struct ObserverFunc: Observer {
ObserverFunc(void (*f)()): _f(f) {}
virtual bool invoke() override { _f(); return true; }
void (*_f)();
};
template <typename T>
struct ObserverMember: Observer {
ObserverT(std::weak_ptr<T> p, void (T::*f)()): _p(p), _f(f) {}
virtual bool invoke() override {
std::shared_ptr<T> p = _p.lock();
if (not p) { return false; }
p->*_f();
return true;
}
std::weak_ptr<T> _p;
void (T::*_f)();
};
// mutable because we remove observers lazily
mutable std::unordered_map<std::string, Observers> _observers;
}; // class EventManager
This is the typical case where you should use polymorphism instead of function (or member function) pointers.
As you noted, your component classes should inherit from a common class Component, which contains virtual method(s) representing the event(s):
class Component
{
public:
virtual void OnPlayerLevelUp()
{
}
};
class ComponentSound : public Component
{
public:
// override it
void OnPlayerLevelUp()
{
// do the actual work
}
};
Your ListEvent type will now look like this:
typedef unordered_map<EventKey, vector<Component*>> ListEvent;
As for the optional void* paramenter in event methods, you can specify it as an optional parameter, but the fact that it's a void* is a bad sign (use of void* can lead to loss of type safety), so I would suggest that you look for a different way to achieve what you want.

pass lambda expression as member function pointer in c++

I have a framework function which expects an object and a member function pointer (callback), like this:
do_some_work(Object* optr, void (Object::*fptr)()); // will call (optr->*fptr)()
How can I pass a lambda expression to it? Want to do somethink like this:
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, [](){ /* this lambda I want to pass */ });
}
};
The meaning of it all is to not clutter the interface of MyObject class with callbacks.
UPD
I can improve do_some_work in no way because I don't control framework and because actually it isn't one function, there're hundreds of them. Whole framework is based on callbacks of that type. Common usage example without lambdas:
typedef void (Object::*Callback)();
class MyObject : public Object
{
void mystuff()
{
do_some_work(this, (Callback)(MyClass::do_work));
}
void do_work()
{
// here the work is done
}
};
SOLUTION Here's my solution based on Marcelo's answer:
class CallbackWrapper : public Object
{
fptr fptr_;
public:
CallbackWrapper(void (*fptr)()) : fptr_(fptr) { }
void execute()
{
*fptr_();
}
};
class MyObject : public Object
{
void mystuff()
{
CallbackWrapper* do_work = new CallbackWrapper([]()
{
/* this lambda is passed */
});
do_some_work(do_work, (Callback)(CallbackWrapper::execute));
}
};
Since we create the CallbackWrapper we can control it's lifetime for the cases where the callback is used asynchonously. Thanks to all.
This is impossible. The construct (optr->*fptr)() requires that fptr be a pointer-to-member. If do_some_work is under your control, change it to take something that's compatible with a lambda function, such as std::function<void()> or a parameterised type. If it's a legacy framework that isn't under your control, you may be able to wrap it, if it's a function template, e.g.:
template <typename Object>
do_some_work(Object* optr, void (Object::*fptr)());
Then, you can implement a wrapper template:
template <typename F>
void do_some_work(F f) {
struct S {
F f;
S(F f) : f(f) { }
void call() { f(); delete this; }
};
S* lamf = new S(f);
do_some_work(lamf, &S::call);
}
class MyObject // You probably don't need this class anymore.
{
void mystuff()
{
do_some_work([](){ /* Do your thing... */ });
}
};
Edit: If do_some_work completes asynchronously, you must allocate lamf on the heap. I've amended the above code accordingly, just to be on the safe side. Thanks to #David Rodriguez for pointing this out.
There are deeper problems with the approach that you are trying to take than the syntactical mismatch. As DeadMG suggests, the best solution is to improve the interface of do_some_work to take a functor of some sort (std::function<void()> in C++11 or with boost, or even a generic F on which operator() is called.
The solution provided by Marcelo solves the syntactical mismatch, but because the library takes the first element by pointer, it is the responsibility of the caller to ensure that the object will be alive when the callback is executed. Assuming that the callback is asynchronous, the problem with his solution (and other similar alternatives) is that the object can potentially be destroyed before the callback is executed, causing undefined behavior.
I would suggest that you use some form of plimp idiom, where the goal in this case would be to hide the need for callbacks (because the rest of the implementation might not need to be hidden you could use just another class to handle the callbacks but store it by value, if you don't want do have to dynamically allocate more memory):
class MyClass;
class MyClassCallbacks {
MyClass* ptr;
public:
MyClassCallbacks( MyClass* ptr ) : ptr(ptr) {}
// callbacks that execute code on `ptr`
void callback1() {
// do some operations
// update *ptr
}
};
class MyClass {
MyClassCallbacks callbackHandler;
public:
void mystuff() {
do_some_work( &callbackHandler, &MyClassHandler::callback1 );
}
};
In this design, the two classes are separated but represent a unique single entity, so it is fine to add a friend declaration and let MyClassCallbacks access the internal data in MyClass (both of them are one single entity, divided only to provide a cleaner interface, but coupling is already high, so adding the extra coupling requiered by friend is no problem).
Because there is a 1-1 relationship between MyClass and MyClassCallbacks instances, their lifetimes are bound and there would be no lifetime issues, except during destruction. During destruction you must ensure that there is no callback registered that can kick in while the MyClass object is being destroyed.
Since you are at it, you might want to walk the extra mile and do a proper pimpl: move all of the data and implementation into a different type that is held by pointer, and offer a MyClass that stores a pointer and offers just the public functions, implemented as forwarders to the pimpl object. This could be somehow tricky as you are using inheritance, and the pimpl idiom is a bit cumbersome to implement on type hierarchies (if you need to extend MyClass, deriving from Object could be done in the pimpl object, rather than the interface type).
I don't think you can do that. Your do_some_work() is declared to accept pointer to methods of class Object, so such should be provided. Otherwise optr->*fptr is invalid since the lambda is not member of Object. Probably you should try using std::function and adding the needed members of Object in its closure.
You must use std::function<void()>. Both function and member function pointers are highly unsuited to being callbacks.

redefining or adding a classes member function dynamically/ during execution

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.

C++: How to build an events / messaging system without void pointers?

I'd like to have a dynamic messaging system in my C++ project, one where there is a fixed list of existing events, events can be triggered anywhere during runtime, and where you can subscribe callback functions to certain events.
There should be an option for arguments passed around in those events. For example, one event might not need any arguments (EVENT_EXIT), and some may need multiple ones (EVENT_PLAYER_CHAT: Player object pointer, String with message)
The first option for making this possible is allowing to pass a void pointer as argument to the event manager when triggering an event, and receiving it in the callback function.
Although: I was told that void pointers are unsafe and I shouldn't use them.
How can I keep (semi) dynamic argument types and counts for my events whilst not using void pointers?
Since others have mentioned the visitor pattern, here is a slight twist using Boost.Variant. This library is often a good choice (or at least it has been for me) when you need a set of different behaviors based on a value. Compared to a void*, it has the benefit of static type checking: if you write a visitor class the misses one of the cases, your code will not compile rather than failing at run time.
Step 1: Define message types:
struct EVENT_EXIT { }; // just a tag, really
struct EVENT_PLAYER_CHAT { Player * p; std::string msg; };
typedef boost::variant<EVENT_EXIT,
EVENT_PLAYER_CHAT> event;
Step 2: Define a visitor:
struct event_handler : public boost::static_visitor<void> {
void operator()(EVENT_EXIT const& e) {
// handle exit event here
}
void operator()(EVENT_PLAYER_CHAT const& e) {
// handle chat event here
std::cout << e.msg << std::endl;
}
};
This defines an event handler that nicely separates out the code for each kind of event. The existence of all operator() overloads is checked at compile time (on template instantiation), so if you add an event type later, the compiler will force you to add corresponding handler code.
Note that event_handler subclasses boost::static_visitor<void>. This determines the return type for each of the operator() overloads.
Step 3: Use your event handler:
event_handler handler;
// ...
event const& e = get_event(); //variant type
boost::apply_visitor(handler, e); // will not compile unless handler
// implements operator() for each
// kind of event
Here, apply_visitor will call the appropriate overload for the 'actual' value of e. For example, if we define get_event as follows:
event get_event() {
return EXIT_EVENT();
}
Then the return value will be converted implicitly to event(EXIT_EVENT()). Then apply_visitor will call the corresponding operator()(EXIT_EVENT const&) overload.
Templates would allow you to write a type-safe event manager without it knowing the message types a-priori.
If the event types change at runtime, or you need to mix multiple types into a single container, you can use pointers to a common base class of all the message/event types.
Something I've done in the past is set up a delegate-based system not unlike what is in C#, using the (excellent) FastDelegate library: http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible
So with that in hand, I created some general-purpose Event classes to contain the lists of delegates, like so:
template <class T1>
class Event1 {
public:
typedef FastDelegate1<T1> Delegate;
private:
std::vector<Delegate> m_delegates;
public:
// ...operator() to invoke, operators += and -= to add/remove subscriptions
};
// ...more explicit specializations for diff arg counts (Event2, etc.), unfortunately
Then you can have the various sub-components expose their specific event objects (I used an interface-style but that's not necessary):
typedef Event2<Player*, std::string> PlayerChatEvent;
class IPlayerEvents {
public:
virtual PlayerChatEvent& OnPlayerChat() = 0;
virtual PlayerLogoutEvent& OnPlayerLogout() = 0; // etc...
};
Consumers of this interface can register like so:
void OtherClass::Subscribe(IPlayerEvent& evts) {
evts.OnPlayerChat() += MakeDelegate(this, &OtherClass::OnPlayerChat);
}
void OtherClass::OnPlayerChat(Player* player, std::string message) {
// handle it...
}
The result is is all individually static-typed per event type--no dynamic_casting. However it does decentralize the event system, which may or may not be an issue for your architecture.
You could use a base class, optionally abstract, and use dynamic_cast. The argument will be checked at run-time. A compile-time would probably be better, though.
class EventArgs
{
public:
virtual ~EventArgs();
};
class PlayerChatEventArgs : public EventArgs
{
public:
PlayerChatEventArgs(Player* player, const std::string& message);
virtual ~PlayerChatEventArgs();
Player* GetPlayer() const;
const std::string& GetMessage() const;
private:
Player* player;
std::string message;
};
class Event
{
public:
virtual ~Event() = 0;
virtual void Handle(const EventArgs& args) = 0;
};
class ExitEvent : public Event
{
public:
virtual ~ExitEvent();
virtual void Handle(const EventArgs& /*args*/)
{
// Perform exit stuff.
}
};
class PlayerChatEvent : public Event
{
public:
virtual ~PlayerChatEvent();
virtual void Handle(const EventArgs& args)
{
// this will throw a bad_cast exception if cast fails.
const PlayerChatEventArgs& playerchatargs =
dynamic_cast<const PlayerChatEventArgs&>(args);
// Perform player chat stuff.
}
};
I would think about having a base class for the messages, and then derive all the messages from that base class. You will then be passing pointers to the base class around the events.
You will, presumably, have some basic funcitonaliy in the base class, which may include a member saying what type of message it is. This will allow you to check the message type before casting to the version you need.
It is tempting to have the base class as the most basic type of message, but I would advise making it a virtual class so that every message has to be cast to be used. This symmetry makes it much less prone to bugs later when the complexity (inevitably) increases

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...