2013-06-27 55 views
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”类不是模板,所以我需要将它的一个成员函数作为模板。因此,该成员函数可以在调用该函数时声明一个定义类型的变量(使用模板),并且此变量需要可供整个类访问。

因此,在一个漂亮的列表:

  • 类“回调”不能是一个模板,
  • 变量CallbackClass必须能够访问到整个班级, 但仍类的内部。
+1

好的,你可以重复一遍为什么你不能达到你想要的,你到底想要什么。你想让CallbackClass成为一个类成员吗?为什么它不能成为班级成员?因为回调类也必须模板化,或者由于其他问题? – ondrejdee

+0

@thephpdev你可以更准确地确定你想要解决什么问题吗?你目前的解释不清楚,所提供的代码没有澄清任何事情。注意你是代码示例,因为它访问未初始化的指针。 – greatwolf

+0

我知道它是越野车,当我找到解决我的问题的解决方案时,我会理清这些错误。这是: 我需要找到一种方法来声明类“成员函数的回调”中的模板变量。我需要这样做,因为类“回调”不能作为模板,它需要保持简单的类。因此,因为“Callback”类不是模板,所以我需要将它的一个成员函数作为模板。因此,该成员函数可以在调用该函数时声明一个定义类型的变量(使用模板),并且此变量需要可供整个类访问。 – thephpdev

回答

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

有一个问题,Callback类不能作为模板,它必须保持简单的类。这是因为将此类作为参数的函数不知道您的情况下是回调还是回调。 – thephpdev

+0

不想过于苛刻,但如果你在开始时说过这样会节省用户2496553的一些工作。从你的问题来看,这些限制是什么并不明确,你描述的问题的核心是什么。 – ondrejdee

+0

是的,我很抱歉,我通常不会寻求帮助,我通常会自己尝试完成。所以我觉得我只是不习惯寻求帮助。 – thephpdev

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

相关问题