詳細請看《C++ Primer plus》(第六版中文版)
http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html
備注:
函數對象:
盡管函數指針被廣泛用於實現函數回調,但C++還提供了一個重要的實現回調函數的方法,那就是函數對象。函數對象(也稱“函數符”)是重載了“()”操作符的普通類對象。因此從語法上講,函數對象與普通的函數行為類似。
用函數對象代替函數指針有幾個優點:
- 首先,因為對象可以在內部修改而不用改動外部接口,因此設計更靈活,更富有彈性。函數對象也具備有存儲先前調用結果的數據成員。在使用普通函數時需要將先前調用的結果存儲在全程或者本地靜態變量中,但是全程或者本地靜態變量有某些我們不願意看到的缺陷。
- 其次,在函數對象中編譯器能實現內聯調用,從而更進一步增強了性能。這在函數指針中幾乎是不可能實現的。
- C++11還提供了limbda表達式來實現函數的靈活調用。詳見《C++ Primer Plus》第18章。
----------------------------------------------------------------------------------------------------------------------------------------------------------
function<bool (int, float)> f;
下面簡要介紹一下function的比較重要的幾個接口。
--------------------------------------------------------------------------------
function();
template <typename F> function(F g);
這個泛型的構造函數接受一個兼容的函數對象,即這樣一個函數或函數對象,它的返回類型與被構造的function的返回類型或者一樣,或者可以隱式轉換,並且它的參數也要與被構造的function的參數類型或者一樣,或者可以隱式轉換。
注意,也可以使用另外一個function實例來進行構造。這樣做,並且function g為空,則被構造的function也為空。使用空的函數指針和空的成員函數指針也會產生空的function。如果這樣做,並且function g為空,則被構造的function也為空。使用空的函數指針和空的成員函數指針也會產生空的function。
--------------------------------------------------------------------------------
template <typename F> function(reference_wrapper<F> g);
function& operator=(const function& g);
template<typename F> function& operator=(F g);
bool empty() const;
void clear();
result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const;
1 int Add(int x, int y) 2
3 { 4 return x+y; 5 } 6 function<int (int,int)> f = Add; 7 int z = f(2, 3);
2、函數對象
1 class CStudent 2 { 3 public: 4 void operator() (string strName, int nAge) 5 { 6 cout << strName << " : " << nAge << endl; 7 } 8 }; 9
10 CStudent stu; 11 function<void (string, int)> f = stu; 12 f("Mike", 12);
3、類的成員函數
1 struct TAdd 2 { 3 int Add(int x,int y) 4 { 5 return x+y; 6 } 7 }; 8
9 function<int (TAdd *, int, int)> f = TAdd::Add; 10 TAdd tAdd; 11 f(&tAdd, 2, 3); // 如果前面的模板參數為傳值或引用,直接傳入tAdd即可
接下來我們來看看使用function來保存函數對象狀態的情況。考慮下面的代碼:
1 class CAdd 2 { 3 public: 4 CAdd():m_nSum(0) { NULL; } 5 int operator()(int i) //重載 () 運算符 6 { 7 m_nSum += i; 8 return m_nSum; 9 } 10
11 int Sum() const
12 { 13 return m_nSum; 14 } 15
16 private: 17 int m_nSum; 18 }; 19
20 int main() 21 { 22 CAdd add; 23 function<int (int)> f1 = add; 24 function<int (int)> f2 = add; 25 cout << f1(10) << "," << f2(10) << "," << add.Sum() << endl; 26 return 0; 27 }
C++ 11中提供了ref和cref函數,來提供對象的引用和常引用的包裝。要使function能夠正確地保存函數對象的狀態,我們可以這樣來修改代碼:
1 CAdd add; 2 function<int(int)> f1 = ref(add); 3 function<int(int)> f2 = ref(add);