2013-06-27 53 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

相關問題