Передача функции-члена в качестве обратного вызова, boost::bind, boost::function

Я наткнулся на любопытство, исследуя возможность передачи функций-членов в качестве обратных вызовов с использованием boost::bind и boost::function. Я баловался с моделью двух классов. Первый (Organism) предоставляет свою переменную-член (age) через функцию int(void) (getAge). Второй класс (Biologist) хранит функцию boost:: в качестве члена (callbackFunction) и использует ее для определения (takeNotes) текущего возраста изучаемого животного (он сохраняет возраст в переменной-члене m_notes). Экземпляр (steve_irwin) второго класса должен «наблюдать» (takeNotes) за экземпляром (животным) первого класса.

Вот код, реализующий класс Animal:

class Organism {
public:
    Organism(int = 1);
    void growOlder();
    int getAge(void);
    void tellAge(void);
private:
    int m_age;
};

Organism::Organism(int _age) : m_age(_age) {}

void Organism::growOlder() {
    m_age++;
}

int Organism::getAge(void) {
    return m_age;
}

void Organism::tellAge(void) {
    std::cout << "This animal is : " << m_age << " years old!";
}

Принимая во внимание, что это код, реализующий класс Biologist:

class Biologist {
public:
    void setCallback(boost::function<int(void)>);
    void takeNotes();
    void tellAge();
private:
    boost::function<int(void)> updateCallback;
    int m_notes;
};

void Biologist::setCallback(boost::function<int(void)> _f) {
    updateCallback = _f;
}

void Biologist::takeNotes() {
    m_notes = updateCallback();
}

void Biologist::tellAge() {
    std::cout << "The animal I am studying is : " << m_notes <<
        " years old! WOW!" << std::endl;
}

Основной цикл выглядит следующим образом:

Organism animal(3);
Biologist steve_irwin;

boost::function<int(void)> f = boost::bind(&Organism::getAge, animal);
steve_irwin.setCallback(f);

steve_irwin.takeNotes();
steve_irwin.tellAge();
animal.tellAge();

animal.growOlder();

steve_irwin.takeNotes();
steve_irwin.tellAge();
animal.tellAge();

Я создаю животное, которому 3 года, я говорю Стиву Ирвину посмотреть на него, он правильно называет его возраст после того, как сначала делает записи, но после того, как животное становится старше и снова называет его возраст, он все еще думает, что животному 3 года. Старый.

Вывод программы:

The animal I am studying is : 3 years old! WOW!
This animal is : 3 years old!
The animal I am studying is : 3 years old! WOW!
This animal is : 4 years old!

Я предполагаю, что мне как-то не удалось передать функцию-член в качестве обратного вызова по ссылке, но я не могу определить, где. Можешь мне помочь?


person audio    schedule 18.09.2016    source источник
comment
Как насчет использования boost::ref' (or 'std::ref, если ваша версия C++ поддерживает это)?   -  person Paul Rooney    schedule 18.09.2016


Ответы (1)


Вместо boost::function<int(void)> f = boost::bind(&Organism::getAge, animal); должно быть boost::function<int(void)> f = boost::bind(&Organism::getAge, &animal);, потому что boost::bind создает внутреннюю копию вашего объекта, если вы делаете, как указано выше.

См. документацию по повышению для повышения ::связать

person DogeAmazed    schedule 18.09.2016