Consider a following code:
struct X {
void MethodX() {
...
}
};
struct Y {
void MethodY() {
...
}
};
void test () {
X x;
Y y;
Dispatcher d;
d.Register("x", x, &X::MethodX);
d.Register("y", y, &Y::MethodY);
d.Call("x");
d.Call("y");
}
The question is how to implement Dispatcher. I don't mind X and Y may inheriting from something, but Dispatcher should allow further clients (not only X and Y). And I would like to avoid void* pointers if possible :)
Take a look at boost::function, it does this.
To avoid boost usage and implement your own you can take a look at the book
http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design
There is a Loki library described in the book with a good explanation how to make your own smart enough for your need functor.
class Dispather
{
public:
typedef boost::function< void ( void ) > FunctionT;
void Register( const std::string& name, FunctionT function )
{
registered_[ name ] = function;
}
void Call( const std::string& name )
{
RegisterdFunctionsT::const_iterator it =
registered_.find( name );
if ( it == registered_.end() )
throw std::logic_error( "Function is not registered" );
(it->second)();
}
private:
typedef std::map< std::string, FunctionT > RegisterdFunctionsT;
RegisterdFunctionsT registered_;
};
int main()
{
X x;
Y y;
Dispather d;
d.Register( "x", boost::bind( &X::MethodX, &x ) );
d.Register( "y", boost::bind( &Y::MethodY, &y ) );
d.Call( "x" );
d.Call( "y" );
return 0;
}
Take a look at this paper:
http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html
It implements a template based functor in C++. void* is used under the hoods, but it's all type-safe because it's wrapped by template functions that create and unwrap the void*. It would make implementing this easy. It support a variety of call styles that plain method pointers don't (e.g. you can pass a function returning something as a functor returning void and it automatically ignores the return value)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With