связать функцию класса наблюдателя c ++ 11

0

Я пытаюсь расширить шаблон наблюдателя субъекта, чтобы взять функцию из класса, а не статическую функцию. Я следовал примеру juan chopanza EXCELLENT в Simple Observer Pattern С++ 11 Теперь я хотел бы передать функцию члена класса как зарегистрированный обратный вызов, а не просто функцию.

Я понял, что я могу вызвать члена класса, используя bind (& class :: member, instance) в соответствии со следующим:

class A {
public:
    void A_Bar() { std::cout << "A" << m_nTest << "_bar()" << std::endl; }
    void A_Foo(int n) { std::cout << "A" << m_nTest << "_Foo(" << n << ")" << std::endl; }
    int m_nTest;
};

int main(int argc, _TCHAR* argv[])
{
    A A1; A1.m_nTest = 1;
    A A2; A2.m_nTest = 2;
    Subject<EventType> s;
    s.registerObserver(EventType::GREEN, bar);
    s.registerObserver(EventType::GREEN, std::bind(&A::A_Bar, A2));
    s.registerObserver(EventType::GREEN, std::bind(&A::A_Bar, A1));
    s.notify(EventType::GREEN);
}

Поскольку первый параметр on становится классом, из которого он вызвал. Я получаю именно то, что мне хотелось бы:

  • бар()
  • A2_bar()
  • A1_bar()

Но теперь я хочу, чтобы уведомление передало некоторую информацию классу наблюдателя. Таким образом, я изменил код на следующее:

template <typename Event>
class Subject
{...
  void notify(const Event& event, int nParameter) const
  {
      for (const auto& obs : observers_.at(event)) obs(nParameter);
  }
 private:
  std::map<Event, std::vector<std::function<void(int)>>> observers_;
};

И теперь я хочу зарегистрироваться:

    s.registerObserver(EventType::GREEN, std::bind(&A::A_Foo, A2));

Может ли кто-нибудь помочь мне в том, что мне не хватает или как это сделать. Я не хочу, чтобы мой класс Subject знал о классе Observer, добавляя его в интерфейс функции. благодаря

Теги:
c++11
observer-pattern
stdbind

1 ответ

0
Лучший ответ

Ваш код с использованием bind может быть проблематичным, поскольку он копирует объекты A2 и A1, вы можете использовать & A2 и & A2, если хотите ссылаться на исходные объекты. Чтобы ответить на ваш вопрос, вы можете использовать:

s.registerObserver(EventType::GREEN, std::bind(&A::A_Foo, &A2, std::placeholders::_1));

Или используйте лямбда, который я бы рекомендовал:

s.registerObserver(EventType::GREEN, [&](int i){ A2.A_Foo(i); });
  • 0
    БИНГО!! Работает как шарм. Одна вещь, которую я понял, моя реализация функции для объекта register должна была быть в файле hpp, потому что он шаблонизирован. Вызывает головную боль для меня, когда я пытаюсь реализовать ее в файле cpp и сообщение об ошибке очень хаотично

Ещё вопросы

Сообщество Overcoder
Наверх
Меню