【问题标题】:Is it possible to create method call dispatcher in C++?是否可以在 C++ 中创建方法调用调度程序?
【发布时间】:2009-03-23 11:57:23
【问题描述】:

考虑以下代码:

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* 指针:)

【问题讨论】:

  • 你可以访问 boost 库吗?
  • 能否请您澄清一下“问题是保存方法指针或函子的数据结构类型。”
  • 我试图用 std::tr1::mem_fun 模板来实现它。但是结果的类型在参数的类型之内。所以我无法制作包含它的异构向量。
  • 你需要一个不带boost的解决方案吗?
  • 其实我可能会使用boost。所以这个问题得到了回答。谢谢。

标签: c++ pointers methods types dispatcher


【解决方案1】:

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

【讨论】:

  • 我没有解决问题。查看更新后的问题。
  • 也许是这样。我正在调查:)
【解决方案2】:

为了避免使用 boost 并实现你自己的,你可以看看这本书 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;
}

【讨论】:

  • 这看起来很棒。它如何将 typeof(&X::MethodX) 转换为 FunctionT?我怎样才能自己实现它并避免使用提升?
  • 为了避免使用 boost ......然后你正在使用 boost::function?
【解决方案3】:

看看这篇论文:

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

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

【讨论】:

    猜你喜欢
    • 2022-08-16
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 2015-09-21
    • 2015-02-05
    相关资源
    最近更新 更多