使变量类成为构造函数之外的成员

Make variable class member outside of constructor

本文关键字:成员 构造函数 变量      更新时间:2023-10-16

基本上,我需要在构造函数之外设置一个变量,并使其可供整个类访问。

它需要这样工作:

#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必须可访问整个类,但仍保持在班级内部
    #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;
    };

我将使用多态性来实现这一点。你的编程技能似乎很好,所以我只会勾画出解决方案的方向,如果需要,可以随时寻求更多帮助。

// 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();
    }
};

创建一个抽象接口回调类,并从中继承CallbackFunction<T>。让你的Callback类持有一个指向这个抽象接口的指针。最后,让您的Callback::SetCallbackfunc分配给该指针。

这里有一些代码来说明这个想法:

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是什么。