I'm working on a OpenGL menu which contains some buttons. I want to be able to associate an action (member function (with a fixed signature) of any class!) to a button which gets executed when the button is pressed. I can do it right now but only for one type. I want to be able to use any member function of any class for my callback.
Right now I'm doing it like this:
#define BUTTONCALLBACK(Func) bind1st( mem_fun( &ClassICanSupport::Func ), this )
I can then create a button like this:
Button* b = new Button("Bla", BUTTONCALLBACK(functionIWanttoCall));
The Callback function has the following signature:
void callback(Button* source);
When I press the button I can execute the callback function which I passed.
I had a look at boost::bind but I couldn't really find a way to tackle the problem. Furthermore all my classes are derived from a class Object so I thought about a void* which I could convert to the right class with some typeid hack but I was unable to get it working. At the end I always had the problem that I couldn't completly eliminate the class type of the callback function (which would be necessary to save the function pointer in my button class) and still being able to call the function.
Do you have any idea how to tackle this problem?
Don't use pointers, use boost::function together with boost::bind (or std::function and std::bind if C++0x), something like
// in Button class (or whatever signature you need)
Button(const std::string&, boost::function<void(Button*)> callback) // ...
// you can then use callback as a function
// in calling code
Button *b = new Button("..", boost::bind(&Class::func, this));
You should use a function<void(Button*)> object. These are run-time polymorphic and can be used with any object that supports void operator()(Button*). You can find one in Boost, TR1 and C++0x. boost::bind works well with these objects.
Well, the easiest way would be with virtual functions, if you don't want to pull in Boost or don't have access to C++0x.
#include <iostream>
// fwd declare
class Button;
class BtnCallbackBase{
public:
virtual void operator()(Button*) = 0;
};
template<class C>
class BtnCallback : public BtnCallbackBase{
private:
typedef void (C::*callback_func)(Button*);
C* _object;
callback_func _onclick;
public:
BtnCallback(C* obj, callback_func func)
: _object(obj)
, _onclick(func)
{}
virtual void operator()(Button* btn){
(_object->*_onclick)(btn);
}
};
class Button{
public:
Button()
: _onclick(0)
{}
void Click(){
if(_onclick != 0)
(*_onclick)(this);
}
template<class C>
void RegisterCallback(C* obj, void (C::*func)(Button*)){
// cleanup old callback, deleting null pointer is a noop
delete _onclick;
_onclick = new BtnCallback<C>(obj,func);
}
~Button(){
delete _onclick;
}
private:
BtnCallbackBase* _onclick;
};
class MyClass{
public:
void ExampleCallback(Button* btn){
std::cout << "Callback works!\n";
}
};
int main(){
Button btn;
MyClass test;
btn.RegisterCallback(&test, &MyClass::ExampleCallback);
btn.Click();
}
Full example on Ideone.
If you want a solution to your problem without using Boost library / without using new C++ features then one of the best choice is Generic Callbacks Dispatcher discussed by Danny Kalev / Herb Sutter.
http://www.gotw.ca/gotw/083.htm
Related
I'm working on a game project that features scratch-built controls rendered into an opengl context; things like buttons, scrollbars, listboxes, etc. Many of these controls are nested; for example, my listbox has a scrollbar, a scrollbar has 3 buttons, etc.
When a scrollbar changes value, I'd like it to call 'some' function (typically in it's parent object) that responds to the change. For example, if the listbox has a slider, it should instantiate the slider, then tell the new slider that it should call the listboxes 'onScroll(float)' function. All of the controls share a common base class, so I could have a 'base* parent' parent pointer, then do 'parent->onScroll(val)'. The problem though is what happens when the parent doesn't inheirit from base; there'd be no virtual onScroll() to follow through, so the top-level parent would have to periodically check to see if any of the child controls had changed value. This would also clutter up other controls, since they may not even have children, or may require different event types like when a list entry object is selected, etc.
A better solution would be to have the child object maintain a generic function pointer (like a callback), which can be set by the parent, and called by the child as necessary. Something like this:
typedef (*ptFuncF)(float);
class glBase {
public:
//position,isVisible,virtual mouseDown(x,y),etc
};
class glDerivedChild : public glBase {
public:
glDerivedChild();
~glDerivedChild();
void changeValue(float fIn) {
Value = fIn; //ignore these forward declaration errors
(*callBack)(fIn);
}
void setCallBack(ptFuncF pIn) {callBack = pIn;}
ptFuncF callBack;
float Value;
};
class glDerivedParent : public glBase {
public:
glDerivedParent() {
child = new glDerivedChild();
child->setCallBack(&onScroll);
}
~glDerivedParent() {delete child;}
void onScroll(float fIn) {
//do something
}
glDerivedChild* child;
};
class someFoo {
public:
someFoo() {
child->setCallBack(&setValue);
}
void setValue(float fIn) {
//do something else
}
glDerivedChild child;
};
I'm kinda new to function pointers, so I know I'm (obviously) doing many things wrong. I suspect it might involve something like "typedef (glBase::*ptFuncF)(float);" with the 'onScroll(f)' being an overridden virtual function, perhaps with a generic name like 'virtual void childCallBack(float)'. I'd prefer to keep the solution as close to vanilla as possible, so I want to avoid external libraries like boost. I've been scratching my head over this one for the better part of 8 hours, and I'm hoping someone can help. Thanks!
I think, what you want is some kind of events or signals mechanism.
You can study, how event processing is organized on Windows, for example. In short, your scrollbar generates new event in the system and then system propagates it to all elements, registered in the system.
More convenient mechanism is signal/slot mechanism. Boost or Qt provides such tools. I'll recomend this solution.
But if you still want to use just callbacks, I'll recommend using std::function (boost::function) (combined with std::bind (boost::bind), when required) instead of raw function pointers.
Use boost::function (or std::function if available). Like this (using your notation):
typedef std::function<void (float)> ptFuncF;
//...
void setCallBack(const ptFuncF &pIn);
//...
child->setCallBack(std::bind(&glDerivedParent::onScroll, this, _1));
//...
child->setCallBack(std::bind(&someFoo::setValue, this, _1));
A function pointer to a member function of a class has such a type:
<return type> (<class name>::*)(<arguments>)
For example:
typedef void (glBase::*ptFuncF)(float);
^^^^
by the way, you have forgot the `void` in your `typedef`
ptFuncF func = &glDerivedChild::onScroll;
And you use it like this:
glDerivedChild c;
(c.*func)(1.2);
In your particular example, the function is a member of the derived class itself, therefore you should call it like this:
(c.*c.callback)(1.2);
the inner c.callback is the function pointer. The rest is exactly as above, which is:
(class_instance.*function_pointer)(arguments);
You might want to take a look at this question also.
Ok, the workaround I came up with has some extra overhead and branching, but is otherwise reasonable.
Basically, each callback function is implemented as a virtual member function that recieves the needed parameters including a void* pointer to the object that made the call. Each derived object also has a base-class pointer that refers to the object that should recieve any events that it emits (typically its parent, but could be any object that inheirits from the base class). In case the control has multiple children, the callback function uses the void* pointer to distinguish between them. Here's an example:
class glBase {
public:
virtual onChildCallback(float fIn, void* caller);
glBase* parent;
};
class glSlider : public glBase {
public:
glSlider(glBase* parentIn);
void changeValue(float fIn) {
Value = fIn;
parent->onChildCallback(fIn, this);
}
float Value;
};
class glButton : public glBase {
public:
glButton(glBase* parentIn);
void onClick() {
parent->onChildCallback(0, this);
}
};
class glParent : public glBase {
public:
glParent(glBase* parentIn) : parent(parentIn) {
childA = new glSlider(this);
childB = new glButton(this);
}
void onChildCallback(float fIn, void* caller) {
if (caller == childA) {
//slider specific actions
} else if (caller == childB) {
//button specific actions
} else {
//generic actions
}
}
glSlider* childA;
glButton* childB;
};
Besides a reasonably small amount of overhead, the scheme is flexible enough that derived classes can ignore certain components or omit them altogether. I may go back to the function pointer idea later (thanks shahbaz), but half the infrastructure is the same for both schemes anyway and the extra overhead is minimal, especially since the number and variety of controls will be rather small. Having the callback function use a nested response is actually a little better since you don't need a separate function for each child object (eg onUpButton, onDownButton, etc).
This has been really killing me for the last couple of days now.
I effectively have something like what Szymon Gatner explained in his fantastic article, found here. (Check out the EventHandler class in the demo code there)
This is one of the few articles I've found on the web that do a good job explaining
how to create a type with an expandable interface. I particularly liked the resulting usage syntax, quite simple to understand.
However, I have one more thing I want to do with this type, and that is to allow it to be decorated. Now, to decorate it with extra data members is one thing, but I'd like to allow the decoration to expand the interface as well, with the function EventHandler::handleEvent being the only method required to be exposed publicly.
Now, unfortunately, the EventHandler::registerEventFunc method is templated.
This means that I cannot define it as a virtual method in some even more base class that EventHandler would inherit from, such as HandlerBase.
My question is whether or not someone has any good ideas on how to solve the problem (making EventHandler decorateable).
I've tried creating methods
1)
void registerEventFunc(boost::function<void()> * _memFn);
and
2)
void registerEventFunc(boost::function<void(*SomeDerivedEvent*)> * _memFn);
and
3)
void registerEventFunc(boost::function<void(EventBase*)> * __memFn);
For 1, if I do that, I lose the typeid of the callback's class Event derived argument type.
For 2, I'd have to overload the function for as many Event callbacks this class plans on registering
For 3, Polymorphism does't work in template parameters ( do correct me if I'm wrong ).
The closest I've come to allowing the function to be made virtual is with 1,
, but I have to bind the argument to the boost::function at the boost::function object's creation and can't use lambda on it later in the body of EventHandler::handleEvent.
class FooEvent : public Event
{
public:
FooEvent(int _val) : Event(), val(_val){}
int val;
};
class MyHandler : public EventHandler
{
public:
MyHandler()
{
registerEventFunc(new boost::function<void()>(boost::bind(boost::mem_fn(&MyHandler::onEvent),this, new FooEvent(5))));
}
void onEvent(const FooEvent * _event)
{
cout << _event->val << endl;
}
};
Ultimately, I don't think that works though ( it can't figure out that whole typeInfo business to create the key for the map lookup)
Any ideas would be greatly appreciated!
If I'm going about this the wrong way, I would be grateful for the mention of alternatives.
The goal in the end of course is to have a decoratable type that can expand it's public interface easily as well as it's data members.
I thought Szymon's stuff was a good starting point since it seemed to have the 2nd half done already.
Thank you ahead of time for any assistance.
Perhaps one option would be to create a templated public function that preserves type information, plus a virtual protected function for actually registering the handler. That is:
class event_source {
protected:
struct EventAdapter {
virtual void invoke(EventBase *) = 0;
virtual ~EventAdapter() { }
};
template<typename EventParam>
struct EventAdapterInst : public EventAdapter {
boost::function<void(const EventParam &)> func_;
EventAdapterInst(const boost::function<void(const EventParam &)> &func)
: func_(func)
{ }
virtual void invoke(EventBase *eb) {
EventParam *param = dynamic_cast<EventParam *>(eb);
assert(param);
func_(*param);
}
};
virtual void register_handler(std::type_info param_type, EventAdapter *ea);
public:
template<typename EventParam>
void register_handler(const boost::function<const EventParam &> &handler)
{
register_handler(typeid(EventParam), new EventAdapterInst(handler));
}
};
Derived classes can override the virtual register_handler to do whatever they like without breaking the type inference properties of the template function.
I'm creating a library that needs to allow the user to set a callback function.
The interface of this library is as below:
// Viewer Class Interface Exposed to user
/////////////////////////////
#include "dataType_1.h"
#include "dataType_2.h"
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2* ) );
private:
dataType_1* (*CallbackFunction) (dataType_2* );
}
In a typical usage, the user needs to access an object of dataType_3 within the callback.
However, this object is only known only to his program, like below.
// User usage
#include "Viewer.h"
#include "dataType_3.h"
// Global Declaration needed
dataType_3* objectDataType3;
dataType_1* aFunction( dataType_2* a)
{
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
myViewer->SetCallbackFunction( &aFunction );
}
My Question is as follows:
How do I avoid using an ugly global variable for objectDataType3 ?
(objectDataType3 is part of libraryFoo and all the other objects dataType_1, dataType_2 & Viewer are part of libraryFooBar) Hence I would like them to remain as separate as possible.
Don't use C in C++.
Use an interface to represent the fact you want a notification.
If you want objects of type dataType_3 to be notified of an event that happens in the viewer then just make this type implement the interface then you can register the object directly with the viewer for notification.
// The interface
// Very close to your function pointer definition.
class Listener
{
public: virtual dataType_1* notify(dataType_2* param) = 0;
};
// Updated viewer to use the interface defineition rather than a pointer.
// Note: In the old days of C when you registered a callback you normally
// also registered some data that was passed to the callback
// (see pthread_create for example)
class Viewer
{
// Set (or Add) a listener.
void SetNotifier(Listener* l) { listener = l; }
// Now you can just inform all objects that are listening
// directly via the interface. (remember to check for NULL listener)
void NotifyList(dataType_2* data) { if (listener) { listener->notify(data); }
private:
Listener* listener;
};
int main()
{
dataType_3 objectDataType3; // must implement the Listener interface
Viewer viewer;
viewer.SetNotifier(&objectDataType3);
}
Use Boost.Function:
class Viewer
{
void SetCallbackFuntion(boost::function<datatype_1* (dataType_2*)> func);
private:
boost::function<datatype_1* (dataType_2*)> CallbackFunction;
}
Then use Boost.Bind to pass the member function pointer together with your object as the function.
If you don't want or can't use boost, the typical pattern around callback functions like this is that you can pass a "user data" value (mostly declared as void*) when registering the callback. This value is then passed to the callback function.
The usage then looks like this:
dataType_1* aFunction( dataType_2* a, void* user_ptr )
{
// Cast user_ptr to datatype_3
// We know it works because we passed it during set callback
datatype_3* objectDataType3 = reinterpret_cast<datatype_3*>(user_ptr);
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
dataType_3 objectDataType3; // No longer needs to be global
myViewer->SetCallbackFunction( &aFunction, &objectDataType3 );
}
The implementation on the other side only requires to save the void* along with the function pointer:
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2*, void*), void* user_ptr );
private:
dataType_1* (*CallbackFunction) (dataType_2*, void*);
void* user_ptr;
}
boost::/std:: function is the solution here. You can bind member functions to them, and in addition functors and lambdas, if you have a lambda compiler.
struct local {
datatype3* object;
local(datatype3* ptr)
: object(ptr) {}
void operator()() {
object->func();
}
};
boost::function<void()> func;
func = local(object);
func(); // calls object->func() by magic.
Something like this is simple to do:
class Callback
{
public:
virtual operator()()=0;
};
template<class T>
class ClassCallback
{
T* _classPtr;
typedef void(T::*fncb)();
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual operator()(){
_classPtr->*_cbProc();
}
};
Your Viewer class would take a callback, and call it using the easy syntax:
class Viewer
{
void SetCallbackFuntion( Callback* );
void OnCallCallback(){
m_cb->operator()();
}
}
Some other class would register the callback with the viewer by using the ClassCallback template specialization:
// User usage
#include "Viewer.h"
#include "dataType_3.h"
main()
{
Viewer* myViewer;
dataType_3 objectDataType3;
myViewer->SetCallbackFunction( new ClassCallback<dataType_3>(&objectDataType3,&dataType_3::DoSomething));
}
You're asking several questions mixed up in here and this is going to cause you lots of confusion in your answers.
I'm going to focus on your issue with dataType_3.
You state:
I would like to avoid declaring or
including dataType_3 in my library as
it has huge dependencies.
What you need to do is make an interface class for dataType_3 that gives the operations -- the footprint -- of dataType_3 without defining everything in it. You'll find tips on how to do that in this article (among other places). This will allow you to comfortably include a header that gives the footprint for dataType_3 without bringing in all of its dependencies. (If you've got dependencies in the public API you may have to reuse that trick for all of those as well. This can get tedious, but this is the price of having a poorly-designed API.)
Once you've got that, instead of passing in a function for callback consider having your "callback" instead be a class implementing a known interface. There are several advantages to doing this which you can find in the literature, but for your specific example there's a further advantage. You can inherit that interface complete with an instantiated dataType_3 object in the base class. This means that you only have to #include the dataType_3 interface specification and then use the dataType_3 instance provided for you by the "callback" framework.
If you have the option of forcing some form of constraints on Viewer, I would simply template that, i.e.
template <typename CallBackType>
class Viewer
{
public:
void SetCallbackFunctor(CallBackType& callback) { _callee = callback; }
void OnCallback()
{
if (_callee) (*_callee)(...);
}
private:
// I like references, but you can use pointers
boost::optional<CallBackType&> _callee;
};
Then in your dataType_3 implement the operator() to do as needed, to use.
int main(void)
{
dataType_3 objectDataType3;
// IMHO, I would construct with the objectDataType3, rather than separate method
// if you did that, you can hold a direct reference rather than pointer or boost::optional!
Viewer<dataType_3> viewer;
viewer.SetCallbackFunctor(objectDataType3);
}
No need for other interfaces, void* etc.
I'm trying to code the following situation:
I have a base class providing a framework for handling events. I'm trying to use an array of pointer-to-member-functions for that. It goes as following:
class EH { // EventHandler
virtual void something(); // just to make sure we get RTTI
public:
typedef void (EH::*func_t)();
protected:
func_t funcs_d[10];
protected:
void register_handler(int event_num, func_t f) {
funcs_d[event_num] = f;
}
public:
void handle_event(int event_num) {
(this->*(funcs_d[event_num]))();
}
};
Then the users are supposed to derive other classes from this one and provide handlers:
class DEH : public EH {
public:
typedef void (DEH::*func_t)();
void handle_event_5();
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
........
}
};
This code wouldn't compile, since DEH::func_t cannot be converted to EH::func_t. It makes perfect sense to me. In my case the conversion is safe since the object under this is really DEH. So I'd like to have something like that:
void EH::DEH_handle_event_5_wrapper() {
DEH *p = dynamic_cast<DEH *>(this);
assert(p != NULL);
p->handle_event_5();
}
and then instead of
func_t f5 = &DEH::handle_event_5;
register_handler(5, f5); // doesn't compile
in DEH::DEH()
put
register_handler(5, &EH::DEH_handle_event_5_wrapper);
So, finally the question (took me long enough...):
Is there a way to create those wrappers (like EH::DEH_handle_event_5_wrapper) automatically?
Or to do something similar?
What other solutions to this situation are out there?
Thanks.
Instead of creating a wrapper for each handler in all derived classes (not even remotely a viable approach, of course), you can simply use static_cast to convert DEH::func_t to EH::func_t. Member pointers are contravariant: they convert naturally down the hierarchy and they can be manually converted up the hierarchy using static_cast (opposite of ordinary object pointers, which are covariant).
The situation you are dealing with is exactly the reason the static_cast functionality was extended to allow member pointer upcasts. Moreover, the non-trivial internal structure of a member function pointer is also implemented that way specifically to handle such situations properly.
So, you can simply do
DEH() {
func_t f5 = &DEH::handle_event_5;
register_handler(5, static_cast<EH::func_t>(f5));
........
}
I would say that in this case there's no point in defining a typedef name DEH::func_t - it is pretty useless. If you remove the definition of DEH::func_t the typical registration code will look as follows
DEH() {
func_t f5 = static_cast<func_t>(&DEH::handle_event_5);
// ... where `func_t` is the inherited `EH::func_t`
register_handler(5, f5);
........
}
To make it look more elegant you can provide a wrapper for register_handler in DEH or use some other means (a macro? a template?) to hide the cast.
This method does not provide you with any means to verify the validity of the handler pointer at the moment of the call (as you could do with dynamic_cast in the wrapper-based version). I don't know though how much you care to have this check in place. I would say that in this context it is actually unnecessary and excessive.
Why not just use virtual functions? Something like
class EH {
public:
void handle_event(int event_num) {
// Do any pre-processing...
// Invoke subclass hook
subclass_handle_event( event_num );
// Do any post-processing...
}
private:
virtual void subclass_handle_event( int event_num ) {}
};
class DEH : public EH {
public:
DEH() { }
private:
virtual void subclass_handle_event( int event_num ) {
if ( event_num == 5 ) {
// ...
}
}
};
You really shouldn't be doing it this way. Check out boost::bind
http://www.boost.org/doc/libs/1_43_0/libs/bind/bind.html
Elaboration:
First, I urge you to reconsider your design. Most event handler systems I've seen involve an external registrar object that maintains mappings of events to handler objects. You have the registration embedded in the EventHandler class and are doing the mapping based on function pointers, which is much less desirable. You're running into problems because you're making an end run around the built-in virtual function behavior.
The point of boost::bindand the like is to create objects out of function pointers, allowing you to leverage object oriented language features. So an implementation based on boost::bind with your design as a starting point would look something like this:
struct EventCallback
{
virtual ~EventCallback() { }
virtual void handleEvent() = 0;
};
template <class FuncObj>
struct EventCallbackFuncObj : public IEventCallback
{
EventCallbackT(FuncObj funcObj) :
m_funcObj(funcObj) { }
virtual ~EventCallbackT() { }
virtual void handleEvent()
{
m_funcObj();
}
private:
FuncObj m_funcObj;
};
Then your register_handler function looks something like this:
void register_handler(int event_num, EventCallback* pCallback)
{
m_callbacks[event_num] = pCallback;
}
And your register call would like like:
register_handler(event,
new EventCallbackFuncObj(boost::bind(&DEH::DEH_handle_event_5_wrapper, this)));
Now you can create a callback object from an (object, member function) of any type and save that as the event handler for a given event without writing customized function wrapper objects.
I'm implementing a CORBA like server. Each class has remotely callable methods and a dispatch method with two possible input, a string identifying the method or an integer which would be the index of the method in a table. A mapping of the string to the corresponding integer would be implemented by a map.
The caller would send the string on the first call and get back the integer with the response so that it simply has to send the integer on subsequent calls. It is just a small optimization. The integer may be assigned dynamically on demand by the server object.
The server class may be derived from another class with overridden virtual methods.
What could be a simple and general way to define the method binding and the dispatch method ?
Edit: The methods have all the same signature (no overloading). The methods have no parameters and return a boolean. They may be static, virtual or not, overriding a base class method or not. The binding must correctly handle method overriding.
The string is class hierarchy bound. If we have A::foo() identified by the string "A.foo", and a class B inherits A and override the method A::foo(), it will still be identified as "A.foo", but the dispatcher will call A::foo if the server is an A object and B::foo if it is a B object.
Edit (6 apr): In other words, I need to implement my own virtual method table (vftable) with a dynamic dispatch method using a string key to identify the method to call. The vftable should be shared among objects of the same class and behave as expected for polymorphism (inherited method override).
Edit (28 apr): See my own answer below and the edit at the end.
Have you considered using a combination of boost::bind and boost::function? Between these two utilities you can easily wrap any C++ callable in a function object, easily store them in containers, and generally expect it all to "just work". As an example, the following code sample works exactly the way you would expect.
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct A { virtual void hello() { cout << "Hello from A!" << endl; } };
struct B : public A { virtual void hello() { cout << "Hello from B!" << endl; } };
int main( int argc, char * argv[] )
{
A a;
B b;
boost::function< void () > f1 = boost::bind( &A::hello, a );
boost::function< void () > f2 = boost::bind( &A::hello, b );
f1(); // prints: "Hello from A!"
f2(); // prints: "Hello from B!"
return 0;
}
It looks like you're looking for something like reflection or delegates -- I'm not 100% sure what you're trying to accomplish, but it seems the best way of doing that is just having a map of function pointers:
typedef size_t (*CommonMethodPointerType)(const unsigned char *);
std::map<std::string, CommonMethodPointerType> functionMapping;
size_t myFunc(const std::string& functionName, const unsigned char * argument) {
std::map<std::string, CommonMethodPointerType>::iterator functionPtrIterator
= functionMapping.find(functionName);
if (FunctionPtrIterator == functionMapping.end())
return ERROR_CODE;
return (*functionPtrIterator)(argument);
}
You could implement some form of optimization similar to your integer by returning the iterator to the client so long as you know the mapping will not change.
If you're looking for "dynamic binding" like that allowed in C# or dynamic languages like PHP, unfortunately you really can't do that -- C++ destroys type information when code is compiled.
Hope that helps!
You might like to rephrase the question slightly as static and dynamic binding actually have a specific meaning in C++.
For example, default values for parameters are determined at compile time so if I have a virtual method in a base class that declares default values for its parameters then those values are set at compile time.
Any new default values for these parameters that are declared in a derived class will be ignored at run time with the result being that the default parameter values in the base class will be used, even though you called the member function in the derived class.
The default parameter values are said to be statically bound.
Scott Meyers discusses this in an item in his excellent book "Effective C++".
HTH
Qt4 has a nice dynamic binding system that's made possible via their "Meta-Object Compiler" (moc). There's a nice writeup on it on their Qt Object Model page.
Here is a way do dynamically load classes from shared libraries on Linux http://www.linuxjournal.com/article/3687?page=0,0
There is also a stackoverflow question on this
C++ Dynamic Shared Library on Linux
The same can be done in Windows by dynamically loading C functions from DLLs and then loading those.
The map part is trivial after you have your dynamic loading solution
The really good book Advanced C++ programming idioms and idioms by James O. Coplien has a section on Incremental loading
Here is an example of my actual method. It Just Works (c) but I'm pretty sure a much cleaner and better way exist. It compiles and runs with g++ 4.4.2 as is. Removing the instruction in the constructor would be great, but I couldn't find a way to achieve this. The Dispatcher class is basically a dispatchable method table and each instance must have a pointer on its table.
Note: This code will implicitly make all dispatched methods virtual.
#include <iostream>
#include <map>
#include <stdexcept>
#include <cassert>
// Forward declaration
class Dispatchable;
//! Abstract base class for method dispatcher class
class DispatcherAbs
{
public:
//! Dispatch method with given name on object
virtual void dispatch( Dispatchable *obj, const char *methodName ) = 0;
virtual ~DispatcherAbs() {}
};
//! Base class of a class with dispatchable methods
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
// Requires a dispatcher singleton assigned in derived class constructor
assert( m_dispatcher != NULL );
m_dispatcher->dispatch( this, methodName );
}
protected:
DispatcherAbs *m_dispatcher; //!< Pointer on method dispatcher singleton
};
//! Class type specific method dispatcher
template <class T>
class Dispatcher : public DispatcherAbs
{
public:
//! Define a the dispatchable method type
typedef void (T::*Method)();
//! Get dispatcher singleton for class of type T
static Dispatcher *singleton()
{
static Dispatcher<T> vmtbl;
return &vmtbl;
}
//! Add a method binding
void add( const char* methodName, Method method )
{ m_map[methodName] = method; }
//! Dispatch method with given name on object
void dispatch( Dispatchable *obj, const char *methodName )
{
T* tObj = dynamic_cast<T*>(obj);
if( tObj == NULL )
throw std::runtime_error( "Dispatcher: class mismatch" );
typename MethodMap::const_iterator it = m_map.find( methodName );
if( it == m_map.end() )
throw std::runtime_error( "Dispatcher: unmatched method name" );
// call the bound method
(tObj->*it->second)();
}
protected:
//! Protected constructor for the singleton only
Dispatcher() { T::initDispatcher( this ); }
//! Define map of dispatchable method
typedef std::map<const char *, Method> MethodMap;
MethodMap m_map; //! Dispatch method map
};
//! Example class with dispatchable methods
class A : public Dispatchable
{
public:
//! Construct my class and set dispatcher
A() { m_dispatcher = Dispatcher<A>::singleton(); }
void method1() { std::cout << "A::method1()" << std::endl; }
virtual void method2() { std::cout << "A::method2()" << std::endl; }
virtual void method3() { std::cout << "A::method3()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
dispatcher->add( "method3", &T::method3 );
}
};
//! Example class with dispatchable methods
class B : public A
{
public:
//! Construct my class and set dispatcher
B() { m_dispatcher = Dispatcher<B>::singleton(); }
void method1() { std::cout << "B::method1()" << std::endl; }
virtual void method2() { std::cout << "B::method2()" << std::endl; }
//! Dispatcher initializer called by singleton initializer
template <class T>
static void initDispatcher( Dispatcher<T> *dispatcher )
{
// call parent dispatcher initializer
A::initDispatcher( dispatcher );
dispatcher->add( "method1", &T::method1 );
dispatcher->add( "method2", &T::method2 );
}
};
int main( int , char *[] )
{
A *test1 = new A;
A *test2 = new B;
B *test3 = new B;
test1->dispatch( "method1" );
test1->dispatch( "method2" );
test1->dispatch( "method3" );
std::cout << std::endl;
test2->dispatch( "method1" );
test2->dispatch( "method2" );
test2->dispatch( "method3" );
std::cout << std::endl;
test3->dispatch( "method1" );
test3->dispatch( "method2" );
test3->dispatch( "method3" );
return 0;
}
Here is the program output
A::method1()
A::method2()
A::method3()
B::method1()
B::method2()
A::method3()
B::method1()
B::method2()
A::method3()
Edit (28 apr): The answers to this related question was enlightening. Using a virtual method with an internal static variable is preferable to using a member pointer variable that needs to be initialized in the constructor.
I've seen both your example and the answer to the other question. But if you talk about the m_dispatcher member, the situation is very different.
For the original question, there's no way to iterate over methods of a class. You might only remove the repetition in add("method", T::method) by using a macro:
#define ADD(methodname) add(#methodname, T::methodname)
where the '#' will turn methodname into a string like required (expand the macro as needed). In case of similarly named methods, this removes a source of potential typos, hence it is IMHO very desirable.
The only way to list method names IMHO is by parsing output of "nm" (on Linux, or even on Windows through binutils ports) on such files (you can ask it to demangle C++ symbols). If you want to support this, you may want initDispatcher to be defined in a separate source file to be auto-generated. There's no better way than this, and yes, it may be ugly or perfect depending on your constraints. Btw, it also allows to check that authors are not overloading methods. I don't know if it would be possible to filter public methods, however.
I'm answering about the line in the constructor of A and B. I think the problem can be solved with the curiously recurring template pattern, applied on Dispatchable:
template <typename T>
class Dispatchable
{
public:
virtual ~Dispatchable() {}
//! Dispatch the call
void dispatch( const char *methodName )
{
dispatcher()->dispatch( this, methodName );
}
protected:
static Dispatcher<T> dispatcher() {
return Dispatcher<T>::singleton();
//Or otherwise, for extra optimization, using a suggestion from:
//http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
static Dispatcher<T>& disp = Dispatcher<T>::singleton();
return disp;
}
};
Disclaimer: I couldn't test-compile this (I'm away from a compiler). You may need to forward-declare Dispatcher, but since it gets a template argument I guess argument-dependant lookup makes that unnecessary (I'm not enough of a C++ guru to be sure of this).
I've added a dispatcher() method for convenience, if it is needed elsewhere (otherwise you can inline it in dispatch()).
The reason CRTP is so simple here and so complicated in the other thread is that here your member was not static. I first thought of making it static, then I thought there was no reason for saving the result of the call to singleton() and waste memory, then I looked it up and found this solution. I'm dubious if the extra reference in dispatcher() does save any extra time.
In any case, if a m_dispatcher member was needed, it could be initialized in the Dispatchable() constructor.
About your example, since initDispatcher() is a template method, I frankly doubt it is necessary to readd method1 and method2. A::initDispatcher(Dispatcher<B> dispatcher) will correctly add B::method1 to dispatcher.
By the way - don't forget that the numeric position of virtual functions dispatched from a vtable correspond identically, with all compilers, to the sequence they appear in the corresponding header file. You may be able to take advantage of that. That is a core principle upon which Microsoft COM technology is based.
Also, you might consider an approach published in "Game Programming Gems" (first volume) by Mark DeLoura. The article is entitled a "generic function binding interface" and is intended for RPC / network binding of functions. It may be exactly what you want.
class Report //This denotes the base class of C++ virtual function
{
public:
virtual void create() //This denotes the C++ virtual function
{
cout <<"Member function of Base Class Report Accessed"<<endl;
}
};
class StudentReport: public Report
{
public:
void create()
{
cout<<"Virtual Member function of Derived class StudentReportAccessed"<<endl;
}
};
void main()
{
Report *a, *b;
a = new Report();
a->create();
b = new StudentReport();
b->create();
}