在构造函数之外创建变量类成员

时间:2013-06-27 18:58:50

标签: c++ class constructor member

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

它需要像这样工作:

#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”不是模板,我需要将其中一个成员函数改为模板。因此,当调用函数时,成员函数可以声明定义的类型的变量(使用模板),并且整个类都需要访问此变量。

所以在一个很好的清单中:

  • class“Callback”不能是模板,
  • 变量CallbackClass必须可供整个类访问, 但仍留在班上。

3 个答案:

答案 0 :(得分: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;
    };

答案 1 :(得分: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();
    }
};

答案 2 :(得分: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是什么。