This is where functors come in handy:
Code:
struct functor_type
{
virtual void operator ()(void) {};
};
template <class type>
struct functor : functor_type
{
functor()
{
self = 0;
function = 0;
}
functor(type * _this, void (type::*some_function)(void))
{
make(_this, some_function);
}
functor & make(type * _this, void (type::*some_function)(void))
{
self = _this;
function = some_function;
return *this;
}
void operator ()(void)
{
(*self.*function)(); // can't use self->function()!
}
type * self;
void (type::*function)(void);
};
Notice that the above just covers functions that take no parameters and return nothing. In other words, for every possible function signature you need, you have to code a corresponding functor method. That's one drawback with functors.
Anyway, now you just plug this into the classes themselves. Notice that class 'b' doesn't need to know what type of class gave it a functor, but class 'a' does have to parameterize it's template:
Code:
struct b
{
void Register(functor_type & passedInFnToCallback)
{
callback = passedInFnToCallback;
}
void FnThatCallsBackLater()
{
callback();
}
b()
:callback(dummy)
{
}
functor_type & callback, dummy;
};
struct a
{
a(b & B)
{
callback.make(this, &a::Callback);
B.Register(callback);
}
void Callback()
{
cout << "Hello from 'a'" << endl;
}
functor<a> callback;
};
Example:
Code:
int main()
{
b b;
a a(b);
b.callback();
return cin.get();
}
Hope that helps.