函數對象實質上是一個實現了operator()--括號操做符重載--的類。它與函數指針用法同樣,可是它有一個優勢,函數指針不能夠傳遞附加數據過去,可是在函數對象中,咱們能夠傳遞附加數據過去。ios
先講解下運算符重載吧,對於運算符函數咱們有兩種定義方式,算法
1,若是此函數是屬於一個類的成員函數,那麼咱們是這麼定義的:參考<< ,以下:函數
ostream & operator<<(const string & str);spa
咱們能夠經過這樣的形式來調用:cout << str ;指針
注意:按正常狀況下,對於一個類A中的函數,咱們應該這樣調用此類中的成員函數:A.func() ,可是對於運算符重載函數,咱們並非這樣,如同cout << str ,cout就是調用<<運算符的一個對象,這裏沒有點號了。code
2,若是此函數並不是另外一個類中的成員函數,而是一個普通函數,那麼咱們應該這麼定義:對象
type operator(a, b); type是返回類型string
咱們能夠這樣使用:a operator b;it
因此對於重載了()運算符的函數對象類,若是經過函數對象類定義了一個對象a,那麼咱們這樣使用對象a的「()」運算符重載:io
a();
對,就這樣,代表此「()」是對象a中的成員函數
若是要傳遞參數的話,能夠這樣:a(type name, ......); name就是傳遞到「()」重載函數中的參數
下面看兩個例子:
第一個是演示函數對象怎麼使用的:
#include <iostream> #include <string> using namespace std; class funObject {//定義一個函數對象 public: funObject(const char *name) : str(name)//構造函數,在構造函數中傳遞一個參數過來 { cout << str << endl; } void operator()(char *name) {//重載()運算符 if (!str.empty()) cout << str;//打印函數對象中私有的數據 cout << name << endl;//打印()函數中傳遞過來的實參 } private: string str; }; int main() { //funObject("hello");//僅僅調用了一下函數對象的構造函數 funObject obj("hello");//定義了一個函數對象類的一個對象,並傳遞了一個附加數據 obj(" kitty");調用obj對象的()函數,實參是"kitty". return 0; }
運行結果:
[chengyang@localhost functionObject]$ ./test2 hello hello kitty
函數對象常常用於C++標準算法中,做爲一個操做函數參數傳遞
另外,函數對象還有一個函數指針沒法匹敵的用法:能夠用來封裝類成員函數指針!
由於函數對象能夠攜帶附加數據,而成員函數指針缺乏一個類實體(類實例)指針來調用,所以,能夠把類實體指針給函數對象保存起來,就能夠用於調用對應類實體成員函數了。
看以下代碼:
#include <iostream> using namespace std; class A { public: void print(const char *name) //一個類中的函數,咱們要經過函數對象將其封裝 {cout << "hello " << name << "!" << endl;} }; template<typename T> class funObject {//函數對象 public: funObject(void(T::*f)(const char *), T *obj) : pFunc(f), pObj(obj){}//構造函數,傳遞附加數據 void operator()(const char *name)//經過此函數封裝某一個類的函數 { (pObj->*pFunc)(name);//調用某一個類的一個對象的一個函數成員,這就是封裝 } private: void(T::*pFunc)(const char *);//儲存某一個類中的函數 T *pObj;//儲存某一個類的一個對象 }; int main() { A a; funObject<A> call(&A::print, &a);//定義一個函數對象類的對象,傳遞一個類的對象和一個類的某個成員函數進去 call("kitty");//調用封裝對象某個對象的()函數,在此函數中,咱們又進而經過某一個類的一個對象調用此類的一個成員函數 return 0; }
運算結果以下:
[chengyang@localhost functionObject]$ ./test1 hello kitty!