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

更多细节:

我知道它有问题,并且无法编译,当我找到解决问题的方法时,我会整理这些错误。这是:

我需要找到一种在“回调”类的成员函数中声明模板变量的方法。我需要这样做,因为“回调”类不能是模板,它需要保持一个简单的类。因此,因为“回调”类不是模板,所以我需要将其中一个成员函数设为模板。因此,该成员函数可以在调用该函数时声明一个定义类型的变量(使用模板),并且该变量需要可供整个类访问。

所以在一个不错的列表中:

  • “回调”类不能是模板,
  • 变量 CallbackClass 必须可供整个类访问,但仍保留在类内部。
4

3 回答 3

0

I would implement this using polymorphism. Your programming skills seem good so I will just sketch the direction to solution, feel free to ask for more help if needed.

// 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

创建一个抽象接口回调类并从中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 回答
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 回答