主要的精神在於利用function pointer把真正計算血量的部份,交給專門計算血量的function。達到像Strategy pattern可以隨時抽換實作內容的目的。
一開始看到後面boost時沒什麼fu,主要的原因在於自己對原本c++要怎麼delegate function的實作方式不熟,所以當後面進階的boost::function跟boost::bind的觀念導入後,心中只剩OS:這哪裡方便了?一點都不蝦阿~為了不模糊焦點,我們先不管pattern怎麼用,直接看看function pointer in standard C++的技巧。
typedef of function pointer
基本的function pointer作法
void Test(int iParam) { cout << "Test Invoked\r\n"; } Typedef void (*ptrFunction)(int) ptrFunction pFun = Test; pFun(3); // call test // output Test InvokedDelegate in Standard C++
寫成class 方便日後使用
class NonTypeDelegate : public Delegate { public: void Invoke(); NonTypeDelegate(void (*pfn)(int),int iParam); virtual ~NonTypeDelegate(){} private: void (*m_pfn)(int); int m_iParam; }; ///////////NonTypeDelegate.cpp void NonTypeDelegate::Invoke() { cout << "NonTypeDelegate Invoke\r\n"; m_pfn(m_iParam); }把function pointer 跟準備傳的參數存在NonTypeDelegate 裡透過Invoke呼叫。
NonTypeDelegate nTDelegate(Test,1); nTDelegate.Invoke(); // output Test InvokedHow about class member function?
對某些人來說Global function 跟typedef很醜,還有如果今天目標是class member function怎麼辦?(這也是比較常見的狀況),有一個class A 要把自己的member function提供出去等別人callback(ex:檔案下載的進度)。
class A { public: void Test(int iParam) { cout << "A::Test Invoked\r\n"; } };我們來看看加強版加入Template的class怎麼用(越來越像boost的用法)
template < typename T> class TypeDelegate : public Delegate { public: void Invoke(); TypeDelegate(T &t, void (T::*pfn)(int), int iParam); ~TypeDelegate(){} private: T m_t; void (T::*m_pfn)(int); int m_iParam; }; template < typename T > TypeDelegate < T > ::TypeDelegate(T &t, void (T::*pfn)(int), int iParam):m_t(t), m_pfn(pfn), m_iParam(iParam) { } template < typename T > void TypeDelegate < T > ::Invoke() { cout < < "TypeDelegate Invoke\r\n"; (m_t.*m_pfn)(m_iParam); }所以在main我們可以這樣用它
A a; TypeDelegate < A > tDelegate(a,&A::Test,2); //指定一個a 的物件與下面的member function其input的參數是2 tDelegate.Invoke(); // call A::Test function到這邊這個形式已經很像boost::function了,boost是這樣用的。
boost::function < void(int) > f1 ; f1 = boost::bind(&A::Test, &a, _1);而boost還保留了傳遞參數的自由(也可以把_1改成自己想要固定的int)
f1(3); f1(4); f1(5);這是我目前對boost::function的理解。
題外話 如果有興趣要玩玩看的人 這段code是在Code::Blocks上開發的 vc2005 compiler到boost::bind會crash
Reference
Function Pointers in C/C++ and boost::bind
Delegate in Standard C++
沒有留言:
張貼留言