прохождение функций - PullRequest
       16

прохождение функций

0 голосов
/ 24 сентября 2010

Хорошо, я давно не писал на C ++.и я никогда не делал ничего тихого на этом высоком уровне.

Так что в принципе мне нужно создать класс.Конструктор для класса должен получить ссылку (или указатель) на метод из другого класса или на функцию.

В основном у меня есть класс, который иногда должен прочитать значение из оценщика fltk (версии 1.1.x), а затем изменить некоторые вещи о себе.Каждый объект будет иметь свой собственный оценщик, связанный с ним.(у них также есть ссылка на другой объект того же родителя, который после обновления сам от оценщика скажет обновить и т. д.)

Итак, как мне передавать функции в конструкторах?*

Ответы [ 3 ]

3 голосов
/ 24 сентября 2010

Вот пример, где метод 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 во время создания Bar, тогда Bar не имеет значения, к какому классу относится метод. Все, что ему нужно - это функтор для последующего вызова, а объект Foo может быть просто связан клиентом.

#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::bind или boost::bind.

1 голос
/ 24 сентября 2010

Самый простой способ сделать это - boost::function. Он может хранить указатели на функции, но также и результат привязки функции-члена к объекту.

Например,

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

позволит вам принять любой источник целых чисел.

1 голос
/ 24 сентября 2010

Ваш конструктор может выглядеть примерно так:


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

Проверьте некоторые веб-ссылки для получения дополнительной информации о синтаксисе указателей на члены. Намного легче, если вы сначала познакомитесь с ним.

В качестве дополнительной заметки ознакомьтесь с функциями mem_fun и mem_fun_ref. Они могут делать то, что вам нужно.

...