C++:函數(shù)對(duì)象,STL提供的函數(shù)對(duì)象,函數(shù)適配器詳解
1 函數(shù)對(duì)象
1.函數(shù)對(duì)象是行為類(lèi)似函數(shù)的對(duì)象。一個(gè)類(lèi)對(duì)象,表現(xiàn)出一個(gè)函數(shù)的特征,即通過(guò)對(duì)象名+(參數(shù)列表)的方式使用一個(gè)類(lèi)對(duì)象。
2.使用STL中提供的或自定義的迭代器和**函數(shù)對(duì)象,**配合STL的算法,組合出各種各樣的功能。
3.通過(guò)函數(shù)對(duì)象而不使用函數(shù)指針,可以增加通用性,提高效率。
4.函數(shù)對(duì)象概念:泛化的函數(shù)
①將普通函數(shù)作為函數(shù)對(duì)象:傳遞函數(shù)名
#include <iostream> #include <numeric> //包含accumulate算法 #include <functional> #include <vector> using namespace std; int mult(int a, int b) { return a * b; } int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); //用該式確定數(shù)組長(zhǎng)度,定義為常量 cout << "所有數(shù)累乘為:" << accumulate(a, a + N, 1, mult) << endl; //將普通函數(shù)作為函數(shù)對(duì)象,傳遞函數(shù)名 //指針a,a + N也可以作為迭代器 return 0; }
②將重載了()運(yùn)算符的類(lèi)的對(duì)象作為函數(shù)對(duì)象:傳遞"類(lèi)名()"
#include <numeric> #include <iostream> using namespace std; class MultClass { public: int operator () (int a, int b) const { return a * b; } }; int main() { int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); //確定數(shù)組a的長(zhǎng)度 cout << "所有數(shù)乘積為:" << accumulate(a, a + N, 1, MultClass()) << endl; //傳輸方式是類(lèi)名(),輸出5040 //指針a,a + N也可以作為迭代器 MultClass ss; cout << ss(100, 100); //輸出10000 return 0; }
2 STL提供的函數(shù)對(duì)象
1.系統(tǒng)提供函數(shù)對(duì)象幫助實(shí)現(xiàn)基本功能。
2.accmulate算法接受二元函數(shù)對(duì)象,transform算法接受一元函數(shù)對(duì)象。
①STL庫(kù)的multiplies
#include <iostream> #include <functional> #include <numeric> using namespace std; int main(){ int a[] = { 1, 2, 3, 4, 5, 6, 7 }; const int N = sizeof(a) / sizeof(int); cout << accumulate(a, a + N, 1, multiplies<int>()) << endl;//通過(guò)STL自帶的函數(shù)對(duì)象multiplies實(shí)現(xiàn)乘法,注意要寫(xiě)數(shù)據(jù)類(lèi)型<int> //指針a,a + N也可以作為迭代器 return 0; }
②STL庫(kù)的二元謂詞greater
#include <iostream> #include <algorithm> #include <functional> //包含greater using namespace std; int main() { int arr[] = { 24, 43, 5, 4, 62, 34, 7654, 22 }; const int N = sizeof(arr) / sizeof(int); copy(arr, arr + N, ostream_iterator<int>(cout, "\t")); cout << endl; sort(arr, arr + N, greater<int>()); //包含在<algorithm>中,默認(rèn)是升序 copy(arr, arr + N, ostream_iterator<int>(cout, "\t")); return 0; }
3 函數(shù)適配器
適配器顧名思義,讓函數(shù)適配算法。
Unary Predicate:一元謂詞
binary:二元的
bind:結(jié)合,(使)聯(lián)合在一起
①找出第一個(gè)大于40的數(shù),注意用數(shù)組和vector都可以
#include <iostream> #include <algorithm> #include <functional> #include <vector> using namespace std; int main() { int a[] = { 30, 40, 50, 90, 20, 10 }; const int N = sizeof(a) / sizeof(int); int *c = find_if(a, a + N, bind2nd(greater<int>(), 40)); cout << *c << endl; return 0; }
一般使用數(shù)組初始化向量vector,后續(xù)操作更方便
int main() { int a[] = { 30, 40, 50, 90, 20, 10 }; const int N = sizeof(a) / sizeof(int); vector<int> v (a, a + N); //用數(shù)組初始化vector vector<int>::iterator p = find_if (v.begin(), v.end(), bind2nd(greater<int>(), 40) ); if (p == v.end()) cout << "找不到" << endl; else cout << *p << endl; return 0; }
find_if算法在STL中的原型聲明為: template<class InputIterator, class UnaryPredicate> InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred); 它的功能是查找數(shù)組[first, last)區(qū)間中第一個(gè)pred(x)為真的元素。 InputIterator、UnaryPredicate是用概念來(lái)做模板參數(shù)名
②利用prt_fun、not1、not2產(chǎn)生組合適配器
#include <iostream> #include <functional> #include <algorithm> #include <vector> using namespace std; int g(int x, int y) { //實(shí)現(xiàn)類(lèi)似greater的功能 return x > y; } int main() { int a[] = { 30, 90, 10, 23, 432, 656, 7, 78 }; const int N = sizeof(a) / sizeof(int); vector<int> v(a, a + N); auto p1 = find_if(v.begin(), v.end(), bind2nd(ptr_fun(g), 40)); //找第一個(gè)大于40的數(shù) //ptr_fun將函數(shù)指針轉(zhuǎn)換為函數(shù)對(duì)象,bind2nd將40作為二元函數(shù)對(duì)象的第二個(gè)參數(shù) if (p1 == v.end()) cout << "no element" << endl; else cout << *p1 << endl; auto p2 = find_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(g), 15))); //找第一個(gè)不大于15的數(shù) //not1對(duì)一元函數(shù)對(duì)象取邏輯反,find_if找到第一個(gè)令bind2nd取false的值 if (p2 == v.end()) cout << "no element" << endl; else cout << *p2 << endl; auto p3 = find_if(v.begin(), v.end(), bind2nd(not2(ptr_fun(g)), 15)); // 找第一個(gè)不大于15的數(shù) //not2對(duì)二元函數(shù)取邏輯反 if (p3 == v.end()) cout << "no element" << endl; else cout << *p3 << endl; return 0; }
③成員函數(shù)適配器,類(lèi)的成員函數(shù)要通過(guò)適配器轉(zhuǎn)換為普通函數(shù)對(duì)象
#include <iostream> #include <vector> #include <functional> #include <algorithm> using namespace std; struct Car { int id; Car(int id) { this->id = id; } void display() const { cout << "car " << id << endl; } }; int main() { vector<Car*> pcars; vector<Car> cars; for (int i = 0; i < 5; i++) pcars.push_back(new Car(i)); //push_back() 在Vector最后添加一個(gè)元素(參數(shù)為要插入的值) for (int i = 5; i < 10; i++) cars.push_back(Car(i)); cout << "elements in pcars: " << endl; for_each(pcars.begin(), pcars.end(), mem_fun(&Car::display));//for_each算法對(duì)每一個(gè)迭代器范圍中的元素進(jìn)行函數(shù)對(duì)象計(jì)算 //men_fun適配后函數(shù)對(duì)象的參數(shù)為"對(duì)象的指針" cout << endl; for_each(cars.begin(), cars.end(), mem_fun_ref(&Car::display)); //men_fun_ptr適配后函數(shù)對(duì)象的參數(shù)為"對(duì)象的引用" cout << endl; for (size_t i = 0; i < pcars.size(); ++i) delete pcars[i]; return 0; }
為什么不能同全局函數(shù)一樣直接傳遞函數(shù)名而成員函數(shù)必須以 &類(lèi)名::函數(shù)名 的方式,因?yàn)樾枰紤]static成員函數(shù)的情況。
mem_fun(member適配為function):將成員函數(shù)適配為普通函數(shù)對(duì)象,適配出來(lái)的函數(shù)需要對(duì)象的指針作為參數(shù)。
men_fun_ref:將成員函數(shù)適配為普通函數(shù)對(duì)象,適配出來(lái)的函數(shù)需要對(duì)象的引用作為參數(shù)。
總結(jié)
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++語(yǔ)言實(shí)現(xiàn)開(kāi)心消消樂(lè)
這篇文章主要為大家詳細(xì)介紹了C++語(yǔ)言實(shí)現(xiàn)開(kāi)心消消樂(lè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12C語(yǔ)言實(shí)現(xiàn)數(shù)獨(dú)游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)數(shù)獨(dú)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03C++中事件機(jī)制的簡(jiǎn)潔實(shí)現(xiàn)及需要放棄的特性
事件模型是被廣泛使用的好東西,但是C++標(biāo)準(zhǔn)庫(kù)里沒(méi)有現(xiàn)成的,現(xiàn)在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先進(jìn)設(shè)施組合出一個(gè)輕便的實(shí)現(xiàn)吧感興趣的朋友可以了解下,或許對(duì)你有所幫助2013-02-02C語(yǔ)言實(shí)現(xiàn)對(duì)bmp格式圖片打碼
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)對(duì)bmp格式圖片打碼2016-01-01詳解VS2019 dumpbin查看DLL的導(dǎo)出函數(shù)
這篇文章主要介紹了詳解VS2019 dumpbin查看DLL的導(dǎo)出函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08c++多線(xiàn)程之死鎖的發(fā)生的情況解析(包含兩個(gè)歸納,6個(gè)示例)
這篇文章主要介紹了c++多線(xiàn)程之死鎖的發(fā)生的情況解析(包含兩個(gè)歸納,6個(gè)示例),需要的朋友可以參考下2018-01-01深入探討C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置
本篇文章是對(duì)在C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05