0

サブジェクト オブザーバー パターンを拡張して、静的関数ではなくクラスから関数を取得しようとしています。シンプルなオブザーバー パターン c++11の juanchopanza EXCELLENT の例に従いまし た。単純な関数ではなく、登録されたコールバックとしてクラス メンバー関数を渡したいと思います。

次のように 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);
}

の最初のパラメーターは、それが呼び出されたクラスになるためです。私はまさに私が望むものを手に入れます:

  • バー()
  • A2_バー()
  • A1_バー()

しかし今、私はまた、通知がオブザーバー クラスにいくつかの情報を渡すようにしたいと考えています。したがって、コードを次のように変更しました。

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

私が欠けているものやこれを行う方法を誰かが助けてくれますか? Observer クラスを関数インターフェイスに追加して、Subject クラスに Observer クラスを認識させたくありません。ありがとう

4

1 に答える 1

0

オブジェクト A2 と A1 をコピーするため、コードを使用bindすると問題が発生する可能性があります。元のオブジェクトを参照する場合は、&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); });
于 2014-09-18T03:47:17.880 に答える