我們在介紹容器set的時候就涉及到了函式物件這個概念,本節就是在原來的基礎之上,系統深入的談一談STL中的函式物件。
函式物件的基本概念
- 函式物件本質上是一個類而不是一個函式
- 函式物件過載了運算子(),從而使物件能夠像函式一樣的被呼叫
函式物件與普通函式的對比
函式物件超出了普通函式的功能,能夠儲存函式呼叫狀態(如果使用全域性變數儲存函式呼叫次數,要給程式加鎖,解鎖。所以不推薦使用全域性變數;而函式物件則能夠很好的解決該問題。)
#include <iostream> using namespace std; class compare{ public: int cnt = 0; //可以記錄函式呼叫次數 bool operator()(int i, int j){ this->cnt ; return i > j; } }; bool compare_fun(int i, int j){ return i > j; } int main(){ compare a, b; cout<<a(1, 2)<<" "<<compare_fun(1,2)<<endl; cout << b(4, 3) << " " << compare_fun(2, 1) << endl; a(3, 4); a(5, 6); a(7, 8); cout << "函式物件a呼叫次數: " << a.cnt << " " << "函式物件b呼叫次數: " <<b.cnt << endl; return 0; }
函式物件可以做引數,做返回值
利用for_each實現列印容器vector中的所有元素#include <iostream> #include <vector> #include <algorithm> using namespace std; class print{ public: int cnt = 0; void operator()(int i){ cout << i << " "; cnt ; } }; int main(){ vector<int> v; for (int i = 0; i < 10; i ){ v.push_back(i); } print p1; p1=for_each(v.begin(), v.end(), p1); //函式物件做函式引數和函式返回值,這是普通函式無法實現的 cout << endl; cout << p1.cnt << endl; return 0; }
STL中預定義的函式物件
STL中的函式物件都封裝在functional標頭檔案中。下面以plus為例子,講解一下STL封裝的函式物件如何使用。
#include <iostream> #include <vector> #include <string> #include <functional> #include <algorithm> using namespace std; int main(){ plus<int> plus_int; int ret = plus_int(10, 20); cout << ret << endl; plus<string> plus_str; string a = "aaa"; string b = "bbb"; string c = plus_str(a, b); cout << c << endl; cout << plus<int>()(1, 2) << endl; //匿名物件 return 0; }
一元函式物件,二元函式物件,一元謂詞,二元謂詞
函式物件接收一個引數,稱為一元函式物件;函式物件接收兩個引數,則稱為二元函式物件。
函式物件或者普通函式接收一個引數,並且返回值是bool資料型別,稱為一元謂詞;函式物件或者普通函式接收兩個引數,並且返回值是bool資料型別,則稱為二元謂詞。
我們下面以for_each(),find_if(),transform()和sort為例子,分別講解一元函式物件,一元謂詞,二元函式物件,二元謂詞。#include <iostream> #include <vector> #include <string> #include <functional> #include <algorithm> using namespace std; template<class T> class print{ public: int ret = 0; void operator()(T i){ cout << i << " "; ret ; } }; class compare{ public: bool operator()(int i){ return i > 7; } }; class sort_int{ public: bool operator()(int v1, int v2){ return v1 > v2; } }; void test01(){ //一元函式物件 for_each vector<int> v; for (int i = 0; i < 100; i ){ v.push_back(i 1); } print<int> print_int; print_int = for_each(v.begin(), v.end(), print_int); cout << endl; cout << print_int.ret << endl; } void test02(){ //一元謂詞 find_if vector<int> v; v.push_back(1); v.push_back(7); v.push_back(8); vector<int>::iterator i = find_if(v.begin(), v.end(), compare()); if (i == v.end()){ cout << "cannot find!!!" << endl; } else{ cout << "find : " << *i << endl; } } void test03(){ //transform() 對兩個容器進行操作,將結果存放在第三個容器中 vector<int> v1,v2,v3; for (int i = 0; i < 10; i ){ v1.push_back(i); v2.push_back(i 1); } //v3在transform之前要先開闢記憶體空間 v3.resize(100); transform(v1.begin(),v1.end(),v2.begin(),v3.begin(),plus<int>()); for (int i = 0; i < v3.size(); i ){ cout << v3.at(i) << " "; } cout << endl; } void test04(){ //二元謂詞 sort vector<int> v1; v1.push_back(3); v1.push_back(2); v1.push_back(9); v1.push_back(6); for_each(v1.begin(), v1.end(), print<int>()); cout << endl; sort(v1.begin(), v1.end(), sort_int()); for_each(v1.begin(), v1.end(), print<int>()); cout << endl; } int main(){ test01(); test02(); test03(); test04(); return 0; }
写评论
很抱歉,必須登入網站才能發佈留言。