1

基本的に、コンストラクターの外部で変数を設定し、クラス全体からアクセスできるようにする必要があります。

次のように動作する必要があります。

#include <iostream>
#include <string>

template <typename MT>
class CallbackFunction
{
    void (*func)(MT);
    MT *data;

  public:
    void SetCallbackData (void (*f)(MT), MT *d)
    {
        func = f;
        data = d;
    }
    void Call()
    {
        func(data);
    }
};

class Callback
{
  public:
    template <typename T>
    void SetCallback(CallbackFunction <T> *func)
    {
        // Need to make this a class member;
        CallbackFunction <T> *CallbackClass = func;
    }
    void Call()
    {
        CallbackClass->Call();
    }
};

template <typename CT>
Callback *NewCallback(void (*func)(CT), CT *data)
{
    Callback *cb;
    CallbackFunction <CT> *cf;
    cf->SetCallbackData(func, data);
    cb->SetCallback <CT> (cf);
    return cb;
};

void Call(Callback *CallbackFunc)
{
    CallbackFunc->Call();
}

void foo(std::string str)
{
    std::cout << str << "\n";
}

int main()
{
    std::string *str;
    str->append("Hello, World!");
    Call( NewCallback(foo, str) );
    return 0;
}

詳細:

バグがあり、コンパイルできないことはわかっています。問題の解決策が見つかったら、それらのバグを整理します。それは次のとおりです。

クラス「Callback」のメンバー関数内でテンプレート変数を宣言する方法を見つける必要があります。クラス「Callback」はテンプレートにすることができず、単純なクラスのままにする必要があるため、これを行う必要があります。クラス「Callback」はテンプレートではないため、代わりにそのメンバー関数の 1 つをテンプレートにする必要があります。そのため、メンバー関数は、関数が呼び出されたときに (テンプレートで) 定義された型の変数を宣言でき、この変数はクラス全体からアクセスできる必要があります。

素敵なリストで:

  • クラス "Callback" をテンプレートにすることはできません。
  • 変数 CallbackClass は、クラス全体からアクセスできる必要がありますが、クラス内にとどまります。
4

3 に答える 3

0

ポリモーフィズムを使用してこれを実装します。あなたのプログラミング スキルは優れているようですので、解決への方向性を大まかに説明します。必要に応じて、さらにサポートを求めてください。

// your callbackobjects inherit from this class, the sole purpose of this 
// class is to provide the Call interface. The derived classes implement
// their custom version of Call(). 

class CallBackObject{
public:
   virtual void Call(){};
};

class Callback
{
  CallBackObject *callBackObject;

  public:

    void SetCallback(CallBackObject *o)
    {
        callBackObject = o;
    }

    void Call()
    {
        callBackObject -> Call();
    }
};
于 2013-06-27T21:42:52.983 に答える
0
    #include <iostream>
    #include <string>
    #include <memory>

    template <typename MT> 
    class CallbackFunction
    {
        typedef void (*func_ptr)(MT);
        func_ptr f_ptr;
        typedef std::shared_ptr<MT> data_ptr;
        data_ptr data_p;
        public:
            void SetCallbackData (func_ptr f_ptr_, MT *d)
            {
                f_ptr = f_ptr_;
                data_p.reset(d);
            }
            void Call()
            {
                if ( f_ptr ) f_ptr(data);
            }
    };
    template<class T>
    class Callback
    {
        public:
            template <typename T>
            void SetCallback(CallbackFunction <T> *func)
            {
                f_ptr.reset(func);
            }
            void Call()
            {
                if ( f_ptr ) f_ptr->Call();
            }
            typedef std::shared_ptr<CallbackFunction<T>> func_ptr;
            static  func_ptr f_ptr;
    };
于 2013-06-27T19:46:41.407 に答える
0

抽象インターフェイス Callback クラスを作成し、これからCallbackFunction<T>継承します。クラスCallbackにこの抽象インターフェイスへのポインターを保持させます。最後に、このポインターCallback::SetCallbackに割り当てます。func

アイデアを説明するためのコードを次に示します。

class ICallback
{
  public:
    virtual ~ICallback() {}
    virtual void Call() = 0;
};

template <typename MT>
class CallbackFunction : public ICallback
{
    typedef void (*callback)(MT);
    callback myfunc;
    MT *data;

  public:
    CallbackFunction (callback f, MT *d) :
        myfunc (f),
        data (d)
        {}
    void Call()
    {
        if(myfunc && data)
        {
          myfunc(*data);
        }
        else throw std::logic_error("Callback function or data is null!");
    }
};

次に、次をCallback保持しICallback*ます。

class Callback
{
    ICallback *mycallback;

  public:
    template <typename T>
    void SetCallback(CallbackFunction <T> *func)
    {
        // Need to make this a class member;
        // CallbackFunction <T> *CallbackClass = func;
        mycallback = func;
    }
    void Call()
    {
        mycallback->Call();
    }
};

アイデアは、インスタンス化されたすべてのテンプレートをCallbackFunction <T>一種のICallback. これで、使用するクラスは、何が何であるかを知る必要なくICallback、任意のクラスを取ることができます。CallbackFunction <T>T

于 2013-06-27T21:53:10.610 に答える