Trying to avoid repetitively call a function - c++

I have a very simple class definition as follows:
#include "../bshttp/controllers.h"
#include <iostream>
#include <string>
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this)
{
m_urlRules["print"] = REG_NAME &DerivedController::print;
//regController(REG_NAME &DerivedController::print,"print");
regController(REG_NAME &DerivedController::printView,"printView");
}
void * print()
{
return NULL;
}
void * printView()
{
cout<<"Print view!"<<endl;
return NULL;
}
};
where either
m_urlRules["print"] = REG_NAME &DerivedController::print;
or
regController(REG_NAME &DerivedController::printView,"printView");
has to be called for all of the member functions. What it does it that it takes the member function pointer of the class and maps with a string, so later on the function can be identified with a string.
Everything is all well and working, but when the class structure gets bigger, the programmer will have to repetitively call this function for every single member function. Is there anyway to use the preprocessor, or any preprocessing library such as the boost-wave, so that the programmer doesn't have to do these repetitive calling?
EDIT:
Sorry for the confusion, I clearly did not describe the problem well enough here.
I am mapping strings to member function pointer;
m_urlRules is a std::map with string as the key, and member function pointer as value
regController is basically a setter function for m_urlRules, so both statements effectively does the same thing, which maps a string to a member function.
REG_NAME is a macro to replace a very ugly typecast.
what I am trying to do is that, if the class where to have the following structure,
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this);
void * print();
void * print2();
void * print3();
void * print4();
};
I dont have to do the following in the constructor:
m_urlRules["print"] = REG_NAME &DerivedController::print;
m_urlRules["print1"] = REG_NAME &DerivedController::print1;
m_urlRules["print2"] = REG_NAME &DerivedController::print2;
m_urlRules["print3"] = REG_NAME &DerivedController::print3;
m_urlRules["print4"] = REG_NAME &DerivedController::print4;

Well, you're trying to build the runtime type information (RTTI) on your own, so no there is no preprocessor macro for this. Mainly because preprocessor macros expand to a single place, and the place where you declare, and the place, where you register your functions are different.
Qt and qmake, does something like this, it finds the functions marked signals/slots, and builds a moc object for RTTI. That's about the best you can get with c++. Other languages like java, and delphi, has more RTTI, than c++, and makes it possible to query functions at runtime.

I am not exactly sure I understood completely your problem, but why don't use the built-in data structure, such as map, in which you can map it to a key (your string).
Here some examples

I would first work on removing the ugly typecast (even in macro form). This can be done by moving the m_urlRules out of BS_Controllers and into an intermediate (or proxy) template class. The template is used to resolve the map to the right derived type. (I didn't know how you defined BS_Controllers, so I made one up.)
class BS_Controllers {
protected:
virtual ~BS_Controllers () {}
public:
virtual void * invokeRule (const std::string &) = 0;
};
template <typename D>
class BS_Proxy : public BS_Controllers {
typedef std::map<std::string, void *(D::*)()> UrlRuleMap;
static UrlRuleMap & urlRules () {
static UrlRuleMap urlRules_;
return urlRules_;
}
void * invokeRule (const std::string &s) {
typename UrlRuleMap::iterator i = urlRules().find(s);
if (i == urlRules().end()) return 0;
return (dynamic_cast<D *>(this)->*(i->second))();
}
protected:
static void regController (void *(D::*m)(), const std::string &s) {
urlRules()[s] = m;
}
};
Now, the DerivedController can be initialized fairly easily, by invoking the regController method of the proxy class.
#define REG_RULE(D, x) BS_Proxy<D>::regController(&D::x, #x)
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
REG_RULE(DerivedController, print);
REG_RULE(DerivedController, printView);
}
};
public:
DerivedController() {
static Populate populate_;
}
void * print() { return NULL; }
void * printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
};
You can view a demo of the above code.
If you want to make the population semi-automatic, you still have to define the list of methods somewhere. You could list them out in a file.
// DerivedController rules
DERIVED_RULE_INC(print)
DERIVED_RULE_INC(printView)
//...
And then change your DerivedController class to use this file:
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
#define DERIVED_RULE_INC(x) REG_RULE(DerivedController, x);
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
}
};
public:
DerivedController() {
static Populate populate_;
}
#define DERIVED_RULE_INC(x) void * x ();
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
};
void * DerivedController::print() { return NULL; }
void * DerivedController::printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
Now, if you add another rule to the file, the registration code and the method declaration is automatic. But the definition of the method needs to be implemented, or a linker error will be generated about the missing method definition.

I believe you want to use this feature for logging reasons, to see where problems appear.
I think you're searching for something like:
urlRules ("<function name>");
regController("<function name>");
Instead of
m_urlRules["<function name>"] = REG_NAME &DerivedController::print;
regController(REG_NAME &DerivedController::printView,"<function name>");
You can define such makros like so:
#define urlRules(x) { m_urlRules[(x)] = REG_NAME &DerivedController::print; }
#define regController(x) { regController(REG_NAME &DerivedController::printView,(x)); }
Attention: I have not tested it, it might not work but in my understanding it should.
EDIT:
Ah now I understand, you want calls for every function within the constructor.
Actually, the constructor is the wrong place, because it gets called for every object you create, but you only have to assign this pointers once. (on startup for example)
See, the functions of a class only exist once in memory, and the thing that is connected to the pointer is the yield data, so all member variables.
There is no simple way to get all class members by name and then run over them, sorry.
At least not as I know of.
But you should keep in mind that the function pointers won't change for any given object.
An external function which does the work would be more intelligent. Called on startup.

Related

Set class methods as functions defined externally

I am implementing a hashtable, and I have written the following (fragment of a) class definition:
template <typename KEY, typename VAL>
class ExtendibleHashTable {
/* Main hash function used. Initially, the identity function. */
size_t hash(KEY key) {
return key;
}
I want to further add a public method, that allows one to set a custom hash function. I do know about function pointers, so I tried something like this (underneath, in the same class definition):
/* Set new hash. */
void set_hash(size_t new_hash(KEY)) {
this -> hash = new_hash;
}
However, this does not compile.
Can you tell me the best way to achieve this effect? I have looked at the <functional> header but it doesn't seem to be the answer I need (or maybe I haven't understood its purpose).
You cannot replace member functions dynamically in C++. Nor can you dynamically add member functions.
You can, however, have a class that contains function pointers or std:: function objects that you can change at run-time. So, you could for example do something like this:
class ExtendibleHashTable {
private:
std::function<size_t (KEY)> m_hash_func;
public:
size_t hash(KEY key) {
if (m_hash_func) {
return m_hash_func(key);
}
return key;
}
void set_hash(const std::function<size_t (KEY)>& func) {
m_hash_func = func;
}
};
In the above, the hash function will by default just return key if no specific function has been set. But, if set_hash has been called with an appropriate hash function (free standing function, function object or lambda), then it will instead call that function and return its result.

avoiding if statements on a static boolean for logic decision making

I have a class whose member itemType is only set once and never modified but it is used in many if-statements to decide which function to call.
Since itemType is only set once is there way to avoid the if statements else where in the class. This will simplify and clean the code and as a bonus will also save the overhead of if checks.
I was thinking about function a pointer taht I can initiatlize in the constructor based on the itemType value.
Is there any alternate and a better way of doing that?
Please note the original class and code base is large and I cant go around creating child classes based on itemtype.
enum ItemTypes
{
ItemTypeA,
ItemTypeB,
};
class ItemProcessing
{
public:
//This function is called hundreds of times
void ProcessOrder(Order* order)
{
//This member itemType is set only once in the constructor and never modified again
//Is there a way to not check it all the time??
if (itemtype == ItemTypes::ItemTypeA )
{
ProcessTypeA(order)
}
else if (itemtype == ItemTypes::ItemTypeB )
{
ProcessTypeB(order)
}
}
ItemProcessing(ItemTypes itype)
{
itemtype = itype; //can I do something here like setting a function pointer so I dont have to check this property in ProcessOrder() and call the relevant function directly.
}
private:
ItemTypes itemtype;
void ProcessTypeA(Order*);
void ProcessTypeB(Order*);
};
Use an array of function pointers, indexed by itemtype, like this:
typedef void(*ProcessType_func_t)(Order *);
ProcessType_func_t processType_f[] = {
ProcessTypeA,
ProcessTypeB
};
Then you can do:
void ProcessOrder(Order *order) {
ProcessType_f[itemtype](order);
}
If you have lots of different functions that need to be dispatched like this, you can use a structure.
struct {
ProcessType_func_t processType_f,
OtherType_func_t otherType_f,
...
} dispatchTable[] = {
{ ProcessTypeA, OtherTypeA, ... },
{ ProcessTypeB, OtherTypeB, ... }
};
Then you would use it as:
dispatchTable[itemtype].processType_f(order);
Finally, you could do the fully object-oriented method, by defining new classes:
class Processor { // abstract base class
public:
virtual void Process(Order *order) = 0;
};
class ProcessorA {
public:
void Process(Order *order) {
ProcessTypeA(order);
}
}
class ProcessorB {
public:
void Process(Order *order) {
ProcessTypeB(order);
}
}
Then you can have a member variable
Processor *processor;
and you initialize it when you set itemtype
ItemProcessing(ItemTypes itype)
{
itemtype = itype;
if (itemtype == ItemTypeA) {
processor = new ProcessorA;
} else {
processor = new ProcessorB;
}
}
Then you would use it as:
processor->Process(order);
This is easily expanded to support more functions that need to dispatch on itemtype -- they all become methods in the classes.
I hope I got the syntax right, I don't actually do much C++ OO programming myself.
You can consider to use either a couple of pointers to member methods or the state pattern.
The former solution has probably higher performance, while the latter is more elegant and flexible (at least from my point of view).
For further details on the state pattern, see here. This pattern fits well with your problem, even though you have to refactor a bit your classes.
I guess the first suggestion is indeed quite clear and does not require further details.
In c++ pointer to function should be mimic with virtual function and inheritance. (Polymorphism)
Define a virtual class including a pure virtual methods
processOrder ( Order* ordre);
And define subclass for each value of your enum.
You can use abstract factory pattern to creat those object or either if needed.
I can write the code if wish.

Choosing a member function based on a string

I have a set of hardware handler classes, all derived from a base class, which have to respond to an incoming data packet. Part of this packet is an ASCII string, which determined which member function of the hardware handler is used to process the packet (for example "fan" would execute the ToggleFan() function.
class HardwareHandler {
virtual void dispatchCommand(const String& cmd) = 0;
}
class FooblerHandler : public HardwareHandler {
void toogleFan();
void dispatchCommand(const String& cmd) {
//is this a "good" way to do this?
if (cmd == "fan")
toggleFan();
}
}
I am using JUCE as a framework, which means I have things like templated HashMaps and String.
However, I'm having trouble coming up with a tidy way of selecting the right handler function based on this string. The construct
if (str == "hello")
FooCommand();
else if (str == "bar")
BarCommand();
looks pretty ugly to me conceptually as there are a lot of relatively expensive string comparisons in there. However, the code is easy to write and the logic is kept in a single place per class.
Another alternative I have tried is to make a hash-map of the strings to an enum and use that a the switch statement:
switch (str.getHash())
{
case CmdFoo:
FooCommnad();
break;
....and so on
}
However this also requires me to set up a static hash-map, as well as maintain the switch to match.
Something else I tried is a hash-map form the string to the member function pointer itself, hoping to be able to jump directly from the string to the member function without having list them in a case statement, and also allows a very generic dispatch function, as it just needs to look up in the hash-map, it doesn't even need to know all the options - they can be contained solely in the hash-map, allowing me to maybe push the dispatch function into the base handler class and not repeat myself in each specific device handler. However, this method has stumped me as I can't quite work out how to do it correctly, or even if it is possible to do this with a static hash-map and member-functions.
Is there an idiomatic way to dispatch to member functions based on a string (or similar hard-to-compare type), preferably with as much logic able to be genericised and moved to the parent class as possible?
Here is my try. You can encapsulate the mapping mechanism into a class:
#include <iostream>
#include <string>
#include <functional>
#include <map>
class X;
template<class X>
class handler_factory;
template<>
class handler_factory<X>
{
private:
using HandlerType = void (X::*)();
public:
handler_factory();
HandlerType get(const std::string& name) const
{
if (handlers.find(name) == handlers.end())
return nullptr;
else
return (*handlers.find(name)).second;
}
private:
std::map<std::string, HandlerType> handlers;
};
class X
{
public:
friend class handler_factory<X>;
private:
void f();
void h();
};
handler_factory<X>::handler_factory()
{
handlers["f"] = &X::f;
handlers["h"] = &X::h;
}
void X::f() { std::cout << "X::f();"; }
void X::h() { std::cout << "X::h();"; }
And your dispatch method can be implemented as:
void dispatch_method(const std::string& name)
{
if (find_handler(name))
(this->*find_handler(name))();
}
int main()
{
X().dispatch_method("f");
}
Where find_handler is defined as a private helper method:
private:
auto find_handler(const std::string& name)
-> decltype(handler_factory<X>().get(name))
{
return handler_factory<X>().get(name);
}
I think the most efficient way to deal with the problem is creating a std::map that would map your strings into appropriate functions. The method is fast (due to the logarithmic searching algorithm), easy and safe.
class FooblerHandler : public HardwareHandler {
typedef void (HardwareHandler::*function)();
map<string,function> commandMap;
void dispatchCommand(const string& cmd) {
if(commandMap.count(cmd))
(this->*commandMap.find(cmd)->second)();
else
cout << "No command found with name \"" <<cmd<< "\"." << endl;
}
};
And of course you should init the map inside the constructor (or somewhere before using it):
commandMap["fan"] = &FooblerHandler::toogleFan;
commandMap["someOtherCommand"] = &FooblerHandler::otherFunction;
Maps and included in the Standard Template Library (STL) which nearly all IDE's supply.
EDIT:
I didn't quite read the text at the end. Well - now you know the syntax :)

handling pointer to member functions within hierachy in C++

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.

Dynamic binding in C++

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();
}