使用tr1的bind函式模板
就我個人理解的這個新標準來看,藉由這兩個模板,我們將能更靈活的使用函式指標,比如函式指標的呼叫和使用回撥機制等。通過使用佔位符,我們將可以使用成員函式來進行回撥,不得不說,這讓我們的程式設計方式得以更加現代化。
如程式碼所示:
typedef std::tr1::function<void (int)> Functor;
如上,通過std::tr1::function
我們定義了Functor的函式型別,該類函式的返回值為void ,引數為int型別,
void showNum(int param)
{
std::cout << "param is : "<<param <<std::endl;
}
void testSimpleFunctional()
{
Functor namedFunc = Functor(&showNum);
Functor namedFunc2 = bind(&showNum,std::tr1::placeholders::_1);
namedFunc(22);
namedFunc2(33);
}
返回的結果如你所料:
param is : 22
param is : 33
首先,我們定義了一個void int型別的函式showNum,然後將函式以模板HandlerEvent賦值給namedFunc,然後呼叫namedFunc,而namedFunc2 則使用bind模板,將showNum繫結到namedFunc2上,使用佔位符std::tr1::placeholders::_1
那麼,使用std::tr1::function的場景在哪裡呢,答案之一是事件回撥,答案之二是委託;
事件回撥
回撥算是老生常談了,在非同步非阻塞的事件驅動的程式設計模型中,回撥機制屬於一等公民,像Nodejs這樣的平臺,回撥已經內嵌為基本實現了,這裡不展開說明了。為了實現回撥,以前,我們經常使用的就是函式指標。現在,讓我們使用bind來實現下:
Show Me The Code
class CallBackCls
{
public:
void setCallback(const Functor& callBackFunc){
m_callBackFunc = callBackFunc;
}
private:
Functor m_callBackFunc;
public:
void run(int param){
//below to do the opetration
std::cout << "callcls handle it done and call" << std::endl;
//operation done and notify the callee
if(m_callBackFunc){
m_callBackFunc(param);
}
}
};
class MainCls
{
public:
MainCls(int x):m_x(x){
m_callBackCls.setCallback(std::tr1::bind(&MainCls::onCallBack,this,x));
}
void mainRun(){
m_callBackCls.run(m_x);
}
private:
void onCallBack(int param){
std::cout << "after callback parm callBackFunc in Main is:"<<param <<std::endl;
}
CallBackCls m_callBackCls;
int m_x;
};
//在Main函式中測試
MainCls cd = MainCls(555);
cd.mainRun();
結果:
callcls handle it done and call:
parm callBackFunc in Main is:555
分析可知:通過bind將MainCls的成員函式onCallBack以及其引數繫結為回撥函式,執行run後,CallBackCls的run函式將在執行完自己的任務後回撥MainCls的成員函式onCallBack,通過這種方式,可以很好的達到非阻塞的目的。
另外,通過類的繼承,虛擬函式等,我們可以向深挖掘更多高階的用法,這裡不展開了。
委託
委託(delegate)在C#裡風生水起,而在C++裡卻是相對沉寂,因為C++沒有,只有類似的委託。可參考長文
面向物件的函式指標也被稱為閉包(closures) 或委託(delegates), 在類似的語言中已經體現出了它的價值. 在 Delphi(Object Pascal) 中, 他們是 VCL (Borland's Visual Component Library, 寶藍視覺化元件) 的基礎. 最近的 C# 讓委託的概念更為流行, 這也成為 C# 成功的因素之一. 在許多程式中, 委託可以簡化由鬆耦合物件組成的高階設計模式(觀察者模式, 策略模式, 狀態模式)的使用. 毫無疑問, 委託在 C++ 中也是非常有用的.
理論上說,委託應該算是回撥的一種,即 委託機制的本質就是呼叫成員函式的函式指標,實現回撥。事實上,本文開篇的例子已經算是委託的一種了,但是沒有涉及到具體的類,顯示有些多餘,而一旦使用了類的成員函式,我們就將物件的狀態以及類的成員變數都彙集在一起,函式指標的可用性被大大增強了。例子有機會再補充吧。