2014年4月18日 星期五

delegate 元件

相當於 c# 的 delegate、boost 的 function,下載點:

https://www.dropbox.com/s/2qwqb516v7fi47s/delegate%202.1.7z
http://pan.baidu.com/s/1kT0rOLx

- 須搭配 CxxlMan 程式庫
- 可代理一般函數指標或成員函數指標,參數最多 10 個
- 對於有回傳值的的格式,只能 bind 一筆函數指標,若多次呼叫
  Bind(), 後者會取代前者,若無 bind,執行函數物件叫用(operator())將
  會 throw DelegateErr_NoBind
- 對於無回傳值的的格式,可以 bind 多筆函數指標資料,用 Bind() 會
  傳回一個 DelegateID,此 ID 可給 Unbind() 刪除用

以下是示範程式,
若用 gcc 編譯,須在專案中加入 CxxlMan 程式庫的
C:\CxxlMan\lib\libcxxlcommon.dll.a
C:\CxxlMan\lib\libcxxlobject.dll.a
C:\CxxlMan\lib\libcxxlcontainer.dll.a

若是用 vs2008 編譯,須在專案中加入 CxxlMan 程式庫的
C:\CxxlMan\lib\cxxlcommon.lib
C:\CxxlMan\lib\cxxlobject.lib
C:\CxxlMan\lib\cxxlcontainer.lib


#include <iostream>
#include <C:\delegate 2.1\DELEGATE.HPP>

using namespace std;
using namespace CxxlMan;

// 無回傳值的函數
void VoidFunc1(int i, float f)
{
  cout << "VoidFunc1()" << endl;
}

// 有回傳值的函數
double ValueFunc1(int i, float f)
{
  cout << "ValueFunc1()" << endl;
  return i + f;
}

// 提供無回傳值和有回傳值的成員函數
class tagObj:virtual public cxxlObject
{
public:
  // Constructor
  tagObj()
   :cxxlObject(Spirit_Easy)
  {
  }

  double ValueFunc(int i, float f)
  {
    cout << "tagObj::ValueFunc()" << endl;
    return i - f;
  }

  void VoidFunc(int i, float f)
  {
    cout << "tagObj::VoidFunc()" << endl;
  }
};

int main()
{
  Smart_Ptr<tagObj> tagObj_Ptr = new tagObj;

  // 可放入無回傳值的函數指標
  Smart_Ptr<delegate<void(int,float)> > VoidDelegate_Ptr =
    new delegate<void(int,float)>;

  // 可放入有回傳值的函數指標
  Smart_Ptr<delegate<double(int,float)> > ValueDelegate_Ptr =
    new delegate<double(int,float)>;

  cout << "先測試 VoidDelegate_Ptr" << endl;

  (*VoidDelegate_Ptr)(50,100); // 尚未 bind 函數指標,什麼事也沒發生

  cout << "放進兩筆函數指標到 VoidDelegate_Ptr" << endl;
  DelegateID ID1 = VoidDelegate_Ptr->Bind(VoidFunc1);
  DelegateID ID2 = VoidDelegate_Ptr->Bind(tagObj_Ptr,&tagObj::VoidFunc);
  (*VoidDelegate_Ptr)(5,10); // 可看到兩筆都有運行

  cout << "從 VoidDelegate_Ptr 中 unbind 一筆" << endl;
  VoidDelegate_Ptr->Unbind(ID1);
  (*VoidDelegate_Ptr)(15,10); // 只剩一筆在運行

  cout << "清空 VoidDelegate_Ptr" << endl;
  VoidDelegate_Ptr->Clear();
  (*VoidDelegate_Ptr)(105,10); // 一樣什麼也沒發生

  cout << "測試 ValueDelegate_Ptr" << endl;
  try
  {
    cout << (*ValueDelegate_Ptr)(5,7) << endl; // 尚未 bind 函數指標,會被 catch
  }
  catch(DelegateErr_NoBind Err)
  {
    cout << "ValueDelegate_Ptr 未 bind 函數指標" << endl;
  }

  cout << "放進兩筆函數指標到 ValueDelegate_Ptr" << endl;
  ValueDelegate_Ptr->Bind(ValueFunc1);
  ValueDelegate_Ptr->Bind(tagObj_Ptr,&tagObj::ValueFunc);
  try
  {
    cout << (*ValueDelegate_Ptr)(5,7) << endl; // 只看到最後一筆在運行
  }
  catch(DelegateErr_NoBind Err)
  {
    cout << "ValueDelegate_Ptr 未 bind 函數指標" << endl;
  }

  cout << "清空 ValueDelegate_Ptr" << endl;
  ValueDelegate_Ptr->Clear();
  try
  {
    cout << (*ValueDelegate_Ptr)(5,7) << endl; // 函數指標被 Clear 了,會被 catch
  }
  catch(DelegateErr_NoBind Err)
  {
    cout << "ValueDelegate_Ptr 未 bind 函數指標" << endl;
  }

  cout << "Hello world!" << endl;
  return 0;
}



沒有留言:

張貼留言