2

たとえば、2 つのクラスがあるとします。

class A
{
  public:
    void foo( /* ............. */ );
};

class B
{
   public:
      void bar();
};

fooメソッドのポインターをメソッドに渡すことさえ可能であるかどうかを知りたいのですが、それをbarに保存して後でA実行します。つまり、どのクラスのメンバーかはわかりません。barAAbar

トピックの複雑な説明ではない構文またはリンクを教えていただければ幸いです。

説明observerC++ のパターンを設計しています。Bのいくつかのイベントを購読したいですA。たとえば、このコードは次のインスタンスにある必要がありますB

   // pseudo code    
   A* observable = new A();
   observable->addEventListener ( 'eventTitle' , functionName );

そして、の呼び出しがeventTitle発生したときAfunctionNameB

4

4 に答える 4

2

メンバー関数へのポインターを呼び出して、その起点を隠す方法はいくつかあります。

  • std::functionとstd::bind:を使用します

    class B {    
        double Sqrt(int what) { return std::sqrt((double)what); }
    };   
    
    // in A:
    std::tr1::function<double (int)> fn; 
    fn = std::tr1::bind(&B::Sqrt, &operations, std::tr1::placeholders::_1);
    fn(3.1415);
    
  • ファンクターを使用します。ファンクターは、メンバー関数へのポインターと、それが呼び出されるオブジェクトであるtogeterをラップします。(ただし、これは少し複雑であり、原則としてstd :: functionの機能のサブセットにすぎません)。

  • 抽象インターフェースIFnからBを導き出し、FooへのIFn参照としてBを渡します。Fooは何を呼び出すかを知っています-インターフェースの仮想Do()関数。
于 2012-08-20T13:05:06.657 に答える
2

何も知らずAにメンバー関数を使用するにはどうすればよいですか? それを呼び出すには、o タイプ(またはサブタイプ) でなければならないBオブジェクトが必要なので、この知識が必要です。BA

静的関数を作成bar()する場合は、通常の関数ポインタ ( void (*)()) またはstd::function<void ()>(boost::function古い C++ の場合) を使用できますが、後者を強くお勧めします。

于 2012-08-20T12:55:50.720 に答える
2

が のメンバーbarとして宣言されていない限り、これは機能しません。非静的メソッドを呼び出すには、 のインスタンスが必要になることを考慮する必要があります。staticBB

(より深い説明については、メンバー関数へのポインターに関する C++ FAQ の章を確認してください。)

UPDATE : オブザーバー パターンを実装する場合は、インターフェイス (純粋な抽象クラス) を宣言できます。たとえばObserverAポインターからメンバーへの関数を認識して使用し、イベントを対応するObserverメソッドにマップします。

例:

   A observable;
   observable.addEventListener ( 'eventTitle' , &B::functionName );
   B observer;
   observable.registerObserver(&observer);
于 2012-08-20T12:53:01.677 に答える
1

次のようなものを使用します。

class A
{
public:
  void foo( /* ............. */ );
  void SetObs(CObs *pObs)
  {
    m_pObs = pObs;
  }

private:
  CObs *m_pObs;
};

class B : public class CObs
{
public:
  virtual void bar();
};

class CObs
{
public:
  virtual void bar() = 0;
};

また、bar() 関数が必要なときはいつでも m_pObs->bar() を呼び出します。また、B のようなすべてのスラスを CObs から派生させ、関数 bar() をオーバーライドします。

于 2012-08-20T12:57:48.033 に答える