5 vector中實(shí)現(xiàn)for_each算法
本項(xiàng)目GitHub: HuangCheng72/HCSTL: 我的STL實(shí)現(xiàn) (github.com): https://github.com/HuangCheng72/HCSTL
進(jìn)入正文。
for each是一種遍歷數(shù)組或者鏈表或者各種集合的算法,實(shí)現(xiàn)簡(jiǎn)單,應(yīng)用廣泛。百度百科可以查到:“foreach 語(yǔ)句用于循環(huán)訪問集合以獲取所需信息,但不應(yīng)用于更改集合內(nèi)容以避免產(chǎn)生不可預(yù)知的副作用。” 它在Java中的實(shí)現(xiàn)有增強(qiáng)for循環(huán)語(yǔ)句,在C#中的實(shí)現(xiàn)有for_each語(yǔ)句,在C++ STL中,它也是一種算法,其作用是在遍歷的同時(shí)執(zhí)行一定的操作。
下面我們就在 vector 中實(shí)現(xiàn)for_each遍歷輸出整個(gè)數(shù)組的數(shù)據(jù),先默認(rèn)數(shù)據(jù)全是POD類型數(shù)據(jù),暫時(shí)不考慮non-POD類型數(shù)據(jù)。
vector.h:
這是非常簡(jiǎn)單的一個(gè)算法,很容易實(shí)現(xiàn)。
在main.cpp中測(cè)試一下:
那么,拓展到non-POD類型數(shù)據(jù),該怎么做?
在我們的main.cpp里面,我們一直用來(lái)測(cè)試的myclass類,有一個(gè)getter函數(shù),但是不是所有的類都有g(shù)etter函數(shù)。而且,不能只是輸出,用戶可能還要進(jìn)行其他的操作,實(shí)現(xiàn)其他的功能。
讓for_each算法實(shí)現(xiàn)更多的功能,而不是只能輸出,我們要讓用戶決定到底要對(duì)數(shù)據(jù)做什么。
在C語(yǔ)言中,讓用戶決定對(duì)數(shù)據(jù)做什么,我們可以用函數(shù)指針的方法。同樣的數(shù)據(jù),我們可以傳入不同的函數(shù)指針,實(shí)現(xiàn)不一樣的執(zhí)行結(jié)果。在C++中這個(gè)方法也是適用的。
但是C++中,運(yùn)算符可以重載這一特性,給了我們另一種實(shí)現(xiàn)的思路。
我們知道,在C語(yǔ)言和C++中,調(diào)用函數(shù)的方式一樣,如下:
所以我們有一個(gè)思路,能不能在一個(gè)類或者結(jié)構(gòu)體中,重載小括號(hào)(或者叫圓括號(hào))運(yùn)算符,讓對(duì)象用起來(lái)像函數(shù)一樣。這就是所謂的函數(shù)對(duì)象,也叫仿函數(shù)。以下就是一個(gè)仿函數(shù)的例子。
函數(shù)對(duì)象首先是一個(gè)對(duì)象,它具備類與對(duì)象對(duì)象的所有特點(diǎn),函數(shù)對(duì)象的類可以有構(gòu)造器,并且在構(gòu)造函數(shù)對(duì)象的時(shí)候,可以用不同的值初始化,進(jìn)而執(zhí)行不同的行為,比起函數(shù)指針來(lái)它的代碼可讀性更好。以下是同一個(gè)函數(shù)對(duì)象類new出來(lái)的兩個(gè)對(duì)象,同樣參數(shù)可以輸出不同的結(jié)果的例子。
而對(duì)于函數(shù)指針來(lái)說(shuō),這是不可能的,只要參數(shù)固定,結(jié)果必然是固定的。因此,函數(shù)對(duì)象比函數(shù)指針更加靈活。
我們使用函數(shù)對(duì)象來(lái)修改vector中for_each這一算法,就可以讓for_each對(duì)數(shù)據(jù)實(shí)現(xiàn)更多的功能。
vector.h:
而后在main.cpp中,進(jìn)行測(cè)試:
順利運(yùn)行,結(jié)果正確。
歡迎訪問本項(xiàng)目的GitHub倉(cāng)庫(kù),如果對(duì)您有幫助,麻煩給項(xiàng)目一個(gè)star,謝謝!
HuangCheng72/HCSTL: 我的STL實(shí)現(xiàn) (github.com): https://github.com/HuangCheng72/HCSTL