3

より多くのコールバックを必要とするクラスがあります。インターフェイスを使用してそれらを実装しようとしています。

class CallbacksInterface
{
public:
     virtual bool mycallback1() = 0;
     virtual bool mycallback2() = 0;
     virtual bool mycallback3() = 0;
};

Class BusImplementation{
public:
    addRequest(bool (CallbacksInterface::*callback)());

}

コールバックはaddRequest()メソッドのパラメーターであり、インターフェースメソッドへのポインターとして定義されます。だからリクエストを追加したいです。

//class with callbacks
class Main:CallbacksInterface{
public:
      bool mycallback1(){..};
      bool mycallback2(){..};
      bool mycallback3(){..};
      //.. 
}

BusImplemantation bus;
Main main;   

bus.addRequest(main.mycallback1);          
bus.addRequest(main.mycallback2);
bus.addRequest(main.mycallback3);

しかし、BusImplemantationクラスにコールバックを渡すことはできません

error: argument of type 'bool (Main::)()' does not match 'bool (CallbacksInterface::*)()'

テンプレートを使用した解決策があると思いますが、組み込みデバイスをプログラミングしていて、コンパイラーが制限されています。

4

2 に答える 2

9

より簡単なアプローチは、関数を表す単一のインターフェースタイプを定義することです。

struct ICallback
{
  virtual bool operator()() const = 0;
};

必要な回数だけ実装します。

struct Foo : ICallback
{
  virtual bool operator()() const { return true;}
};

struct Bar : ICallback
{
  virtual bool operator()() const { return false;}
};

次に、バスの実装はコールバックインターフェイスを取ることができます。

class BusImplemantation{
public:
    void addRequest(const ICallback* callback) { .... }
};

それから

BusImplemantation bus;
Foo foo;  // can be called: bool b = foo();
Bar bar;   // can be called: bool b = bar();

bus.addRequest(&foo);          
bus.addRequest(&bar);

std :: functionを使用して、共通インターフェースを完全に回避することも調査できます。

于 2012-09-12T13:13:35.463 に答える
1

また、抽象的なインターフェイスを使用することを強くお勧めします。ただし、何らかの理由で元のアプローチが本当に必要な場合は、次のようなものが必要です。

void addRequest(bool (CallbacksInterface::*callback)(), CallbacksInterface* pTarget) {...}
...
bus.addRequest(&CallbacksInterface::mycallback1, &main); 
// ! Not &Main::mycallback1 - that wouldn't compile
...
// calling a callback
(pTarget->*callback)();
于 2012-09-12T13:57:37.363 に答える