0

入力データを使用していくつかのジョブを実行し、そのシリーズの次のコールバックを呼び出す一連のコールバックがあります。この簡単な例を見てください (一連の各コールバックがインクリメントされ、値が出力されます)。

#include <stdio.h>
//#include <boost/bind.hpp>
//#include <boost/function.hpp>

//typedef boost::function<void (int i)> DataCallback;
typedef void (*DataCallback)(int i);

class A
{
public:
    DataCallback dataCallback;
    void RegisterCallback(DataCallback callback);
    void Callback(int i);
};

void A::RegisterCallback(DataCallback callback)
{
    dataCallback = callback;
}

void A::Callback(int i)
{    
    dataCallback(++i);
    printf("Callback. i = %i", i);
}

int main (void)
{    
    A a1, a2, a3;

    //a1.RegisterCallback(boost::bind(&A::Callback, &a2));
    //a2.RegisterCallback(boost::bind(&A::Callback, &a3));
    a1.RegisterCallback(a2.Callback);
    a2.RegisterCallback(a3.Callback);

    a3.Callback(1);

    return 0;
}

しかし、私には問題があります。C++ では、クラス メンバー関数をコールバックとして使用できません。私が知っているように、この問題の解決策はコールバック関数を静的にすることです。ただし、この場合、クラス内フィールドは使用できません。それを解決するために、クラスへのコールバック ポインター ( this ) を提供し、それをコールバックで使用できます。しかし、私の場合は、a2 と a1 へのポインターを最下位のコールバック (a3.Callback) に提供する必要があることを意味します。

私の実際のプロジェクトでは、約 6 つのコールバックがあり、6 番目のコールバックに他の 5 つへのポインタを提供します。これは悪い考えだと思います。

だから、私の質問は -この一連のコールバックをどのように実装するのですか?

コードでわかるように、boost::function と boost::bind を使用しようとしましたが、MSVS2005 がコンパイル時にクラッシュし (最適化されたコンパイラが動作を停止しました...)、mem_fn.hpp@318 で C4180 という警告が表示されます。ここで何が問題なのですか?これが私の問題を解決するための最適な方法ですか?

4

1 に答える 1

0

はい、コールバックの代わりにICallbackableクラスをCallback()メソッドで登録しています。ご協力ありがとう御座います。

#include <stdio.h>

class ICallbackable
{
public:
    virtual void Callback(int i) = 0;
};

class A : public ICallbackable
{
public:
    ICallbackable* dataCallback;
    void RegisterCallback(ICallbackable* callback);
    void Callback(int i);
};

void A::RegisterCallback(ICallbackable* callback)
{
    dataCallback = callback;
}

void A::Callback(int i)
{
    printf("Callback. i = %i\n", i);

    if (dataCallback)
    {
        dataCallback->Callback(++i);
    }    
}

int main (void)
{    
    A a1, a2, a3;

    a1.RegisterCallback(NULL);
    a2.RegisterCallback(&a1);
    a3.RegisterCallback(&a2);

    a3.Callback(1);

    return 0;
}
于 2013-09-18T14:02:56.723 に答える