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 に答える