5

考虑以下代码:

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

问题是如何实现 Dispatcher。我不介意 X 和 Y 可能从某些东西继承,但是 Dispatcher 应该允许更多的客户端(不仅是 X 和 Y)。如果可能的话,我想避免使用 void* 指针:)

4

3 回答 3

5

看看boost::function,它就是这样做的。

于 2009-03-23T11:58:52.643 回答
2

为避免提高使用率并实现您自己的,您可以查看本书 http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design

书中描述了一个 Loki 库,它很好地解释了如何让你自己的函数足够聪明,以满足你需要的函子。

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;
}
于 2009-03-23T12:33:02.123 回答
1

看看这篇论文:

http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html

它在 C++ 中实现了一个基于模板的仿函数。void* 在幕后使用,但它都是类型安全的,因为它由创建和解包 void* 的模板函数包装。这将使实现这一点变得容易。它支持普通方法指针不支持的各种调用样式(例如,您可以传递一个返回某些东西的函数,作为返回 void 的函子,它会自动忽略返回值)

于 2009-03-23T12:03:07.437 回答