0

わかりました。C++で記述してからしばらく経ちました。そして、私はこれほど高いレベルで静かなことをしたことはありません。

つまり、基本的にクラスを作成する必要があります。クラスのコンストラクターは、別のクラスのメソッドまたは関数への参照(またはポインター)を取得する必要があります。

基本的に、私は時々fltkバリュエーター(バージョン1.1.x)から値を読み取り、それ自体についていくつかのことを変更する必要があるクラスを持っています。各オブジェクトには、独自のバリュエーターが関連付けられています。(同じ親の別のオブジェクトへのリンクもあります。これらのオブジェクトは、更新後に評価者から更新するように指示されます)。

では、コンストラクターで関数を渡すにはどうすればよいですか?

4

3 に答える 3

3

Fooのメソッドがコンストラクターに渡され、Bar後で特定のBarオブジェクトで呼び出される例を次に示します。

struct Foo
{
    int z;

    int add(int x, int y)
    {
        return x + y + z;
    }

    int mul(int x, int y)
    {
        return x * y * z;
    }
};

typedef int (Foo::*foo_method)(int, int);

struct Bar
{
    foo_method m;

    Bar(foo_method m) : m(m) {}

    int call_on(Foo* foo)
    {
        return (foo->*m)(4, 2);
    }
};

int main()
{
    Bar bar(&Foo::add);

    Foo foo = { 123 };
    bar.call_on(&foo);
}

一方、構築時にFooオブジェクトをすでに知っている場合は、メソッドがどのクラスに属しているかは実際には気にしません。必要なのは後で呼び出すファンクターだけで、オブジェクトはクライアントによって簡単にバインドできます。BarBarFoo

#include <functional>

struct Bar
{
    std::function<int (int, int)> f;

    Bar(std::function<int (int, int)> f) : f(f) {}

    int call()
    {
        return f(4, 2);
    }
};

using namespace std::placeholders;

int main()
{
    Foo foo = { 123 };
    Bar bar(std::bind(&Foo::add, &foo, _1, _2));

    bar.call();
}

C ++ 0xコンパイラがない場合は、またはに置き換えてstd::bindください。std::tr1::bindboost::bind

于 2010-09-24T07:28:22.883 に答える
1

コンストラクターは次のようになります。


// convenient typedef. This is for a pointer to a function in Foo
// The function returns void and takes no parameters.
typedef void (Foo::*FooPtr)();

class Bar {
public:
   Bar (FooPtr foo_ptr);
};

メンバーへのポインターの構文の詳細については、いくつかのWebリファレンスを確認してください。最初に慣れれば、はるかに簡単です。

追記として、関数mem_funとmem_fun_refを確認してください。これらはあなたが必要とすることをするかもしれません。

于 2010-09-24T07:28:57.890 に答える
1

これをキャプチャする最も簡単な方法は、を使用することですboost::function。関数ポインタを格納できますが、メンバー関数をオブジェクトにバインドした結果も格納できます。

例えば、

class Foo {
  Foo(boost::function<int(void)>);
};

整数の任意のソースを受け入れることができます。

于 2010-09-24T07:37:34.653 に答える