I want to fill a map with class name and method, a unique identifier and a pointer to the method.
typedef std::map
You can try using factory or abstract factory design patterns for the class, and a function pointer for the function.
I found the following 2 web pages with implementations when I was searching for solutions for a similar problem:
Factory
Abstract factory
Perhaps you're looking for member function pointers.
Basic usage:
class MyClass
{
public:
void function();
};
void (MyClass:*function_ptr)() = MyClass::function;
MyClass instance;
instance.*function_ptr;
As stated in the C++ FAQ Lite, macros and typedef
s would greatly increase readability when using member function pointers (because their syntax isn't common in code).
You can also use dynamic loading of the functions:
Use GetProcAddress in Windows, and dlsym in Unix.
Go for Subject-Observer design pattern.
If you do not want to use member function pointers, you can use statics which take an argument of the class instance. For example:
class MyClass
{
public:
void function();
static void call_function(MyClass *instance); // Or you can use a reference here.
};
MyClass instance;
MyClass::call_function(&instance);
This requires more work on the coder and causes maintainability issues (since if you update the signature of one, you must update that of the other as well).
You could also use a single static function which calls all your member functions:
class MyClass
{
public:
enum Method
{
fp_function,
};
void function();
static void invoke_method(MyClass *instance, Method method); // Or you can use a reference here.
};
void MyClass::invoke_method(MyClass *instance, Method method)
{
switch(method)
{
default:
// Error or something here.
return;
case fp_function:
instance->function();
break;
// Or, if you have a lot of methods:
#define METHOD_CASE(x) case fp_##x: instance->x(); break;
METHOD_CASE(function);
#undef METHOD_CASE
}
// Free logging! =D
}
MyClass instance;
MyClass::invoke_method(instance, MyClass::fp_function);
I think the most important thing to find out here is, do all of your methods have the same signature? If they do, this is a trivial use of boost bind(if you're into that), functors are an option(the static, duck type kind), or just plain ole virtual inheritance is an option. Inheritance isnt currently in vogue but its pretty easy to understand and I dont think it complicates things anymore then using boost bind(imho best for small non systemic functors).
here is a sample implementation
#include<iostream>
#include<map>
#include<string>
using std::map;
using std::string;
using std::cout;
using std::pair;
class MVCHandler
{
public:
virtual void operator()(const string& somekindofrequestinfo) = 0;
};
class MyMVCHandler : public MVCHandler
{
public:
virtual void operator()(const string& somekindofrequestinfo)
{
cout<<somekindofrequestinfo;
}
};
void main()
{
MyMVCHandler myhandler;
map<string, MVCHandler*> handlerMap;
handlerMap.insert(pair<string, MVCHandler*>("mysuperhandler", &myhandler));
(*handlerMap["mysuperhandler"])("somekindofrequestdata");
}