一起來學習C++的函數(shù)指針和函數(shù)對象_第1頁
一起來學習C++的函數(shù)指針和函數(shù)對象_第2頁
一起來學習C++的函數(shù)指針和函數(shù)對象_第3頁
一起來學習C++的函數(shù)指針和函數(shù)對象_第4頁
一起來學習C++的函數(shù)指針和函數(shù)對象_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第一起來學習C++的函數(shù)指針和函數(shù)對象目錄函數(shù)指針函數(shù)對象總結

函數(shù)指針

以下是cstdlib庫中的一個排序數(shù)組的方法qsort()的函數(shù)原型。

voidqsort(void*base,size_tnum,size_tsize,

int(*compar)(constvoid*,constvoid*));

base--指向要排序的數(shù)組的第一個元素的指針。num--由base指向的數(shù)組中元素的個數(shù)。size--數(shù)組中每個元素的大小,以字節(jié)為單位。compar--用來比較兩個元素的函數(shù)。

對于可以使用常規(guī)關系運算符進行比較的類型,常規(guī)比較函數(shù)可能如下所示:

intcompareMyType(constvoid*a,constvoid*b){

if(*(MyType*)a*(MyType*)b)return-1;

if(*(MyType*)a==*(MyType*)b)return0;

if(*(MyType*)a*(MyType*)b)return1;

}

#includecstdlib

#includeiostream

intcmpfunc(constvoid*a,constvoid*b);

usingnamespacestd;

intmain(){

intvalues[]={88,56,100,2,25};

qsort(values,sizeof(values)/sizeof(int),sizeof(int),cmpfunc);

cout"排序之后的列表:"endl;

for(intn=0;nn++){

coutvalues[n]"";

return0;

intcmpfunc(constvoid*a,constvoid*b){

return(*(int*)a-*(int*)b);

}

Enterastring(emptylinetoquit):|abcEnter

Entermenuchoice:

u)uppercasel)lowercase

t)transposedcaseo)originalcase

n)nextstring

Pleaseenteru,l,t,o,orn:

|uEnter

Entermenuchoice:

u)uppercasel)lowercase

t)transposedcaseo)originalcase

n)nextstring

Pleaseenteru,l,t,o,orn:

|lEnter

abc

#includecstdio

#includecstring

#includestring

#includecctype

#includeiostream

#defineLEN81

charshowmenu();

voidshow(void(*fp)(char*),char*str);

voidToUpper(char*);//把字符串轉換為大寫

voidToLower(char*);//把字符串轉換為小寫

voidTranspose(char*);//大小寫轉置

voidDummy(char*);//不更改字符串

usingnamespacestd;

intmain(){

charline[LEN];

charcopy[LEN];

charchoice;

void(*pfun)(char*);//聲明一個函數(shù)指針,被指向的函數(shù)接受char*類型的參數(shù),無返回值

cout"Enterastring(emptylinetoquit):";

while(cinline){

while((choice=showmenu())!='n'){

switch(choice){//switch語句設置指針

case'u':

pfun=ToUpper;

break;

case'l':

pfun=ToLower;

break;

case't':

pfun=Transpose;

break;

case'o':

pfun=Dummy;

break;

strcpy(copy,line);//為show()函數(shù)拷貝一份

show(pfun,copy);//根據(jù)用戶的選擇,使用選定的函數(shù)

cout"Enterastring(emptylinetoquit):";

cout"Bye!";

return0;

charshowmenu(){

charans;

cout"Entermenuchoice:"endl;

cout"u)uppercasel)lowercase"endl;

cout"t)transposedcaseo)originalcase"endl;

cout"n)nextstring"endl;

ans=getchar();//獲取用戶的輸入

ans=tolower(ans);//轉換為小寫

while(strchr("ulton",ans)==NULL){

cout"Pleaseenteru,l,t,o,orn:"endl;

ans=tolower(getchar());

returnans;

voidshow(void(*fp)(char*),char*str){

(*fp)(str);//把用戶選定的函數(shù)作用于str

coutstrendl;//顯示結果

voidToUpper(char*str){

while(*str){

*str=toupper(*str);

str++;

voidToLower(char*str){

while(*str){

*str=tolower(*str);

str++;

voidTranspose(char*str){

while(*str){

if(islower(*str))

*str=toupper(*str);

elseif(isupper(*str))

*str=tolower(*str);

str++;

voidDummy(char*str){

}//不改變字符串

函數(shù)對象

函數(shù)對象是專門設計用于語法與函數(shù)相似的對象。在C++中,這是通過在類中定義成員函數(shù)operator()來實現(xiàn)的,例如:

structmyclass{

intoperator()(inta){

returna;

}myobject;

intx=myobject(0);

它們通常用作函數(shù)的參數(shù),例如傳遞給標準算法的謂詞或比較函數(shù)。

標準庫預先定義了些functionobject。所謂functionobject,是某種class的實例對象,這類class對functioncall運算符做了重載操作,如此一來可使functionobject被當成一般函數(shù)來使用。

functionobject實現(xiàn)了我們原本可能以獨立函數(shù)加以定義的事物。但又何必如此呢?

主要是為了效率。我們可以令call運算符成為inline,從而消除通過函數(shù)指針來調(diào)用函數(shù)時需要付出的額外代價。

標準庫事先定義了一組functionobject,分為:

算術運算(arithmetic)、關系運算(relational)和邏輯運算(logical)三大類。

以下列表中的type在實際使用時會替換為內(nèi)置類型或class類型:

6個算術運算plustype,minustype,negatetype,

multipliestype,dividestype,modulestype

6個關系運算lesstype,less_equaltype,greatertype,

greater_equaltype,equal_totype,not_equal_totype

3個邏輯運算logical_andtype,logical_ortype,logic_nottype

要使用事先定義的functionobject,首先得包含相關頭文件:functional

默認情況下sort()是升序排列,我們將元素降序排列:

sort(vec.begin(),vec.end(),greaterint

其中的greaterint()會產(chǎn)生一個未命名的classtemplateobject,傳給sort()。

binary_search()期望其搜索對象先經(jīng)過排序,為了正確搜索vector,就必須傳給它某個functionobjectobject,供vector排序使用:

binary_search(vec.begin(),vec.end(),elem,greaterint

我們對Fibonacci數(shù)列可以做些其他操作,如:每個元素和自身相加、和自身相乘、被加到對應的Pell數(shù)列等等。做法之一是使用泛型算法transform()并搭配plusint和multipliesint。

我們必須傳給transform()的參數(shù)有:

?一對iterator,標示出欲轉換的元素范圍;

?一個iterator,所指元素將應用于轉換上,元素范圍同?;

?一個iterator,所指位置(及其后面的空間)用來存放轉換結果;

?一個functionobject,表現(xiàn)出我們想要應用的轉換操作。

以下是將Pell數(shù)列加到Fibonacci數(shù)列的寫法:

transform(fib.begin(),fib.end(),//?

pell.begin(),//?

fib_plus_pell.begin(),//?

plusint//?

transform()的定義:

functiontemplatealgorithmstd::transform

unaryoperation(1)

templateclassInputIterator,classOutputIterator,classUnaryOperation

OutputIteratortransform(InputIteratorfirst1,InputIteratorlast1,

OutputIteratorresult,UnaryOperationop);

binaryoperation(2)

templateclassInputIterator1,classInputIterator2,

classOutputIterator,classBinaryOperation

OutputIteratortransform(InputIterator1first1,InputIterator1last1,

InputIterator2first2,OutputIteratorresult,

BinaryOperationbinary_op);

————————————————————————————————————————————————————

將操作順序應用于一(1)或兩(2)個范圍的元素,并將結果存儲在從結果開始的范圍中。

(1)一元操作

將op應用于[first1,last1]范圍內(nèi)的每個元素,并將每個操作返回的值存儲在從result開始的范圍內(nèi)。

(2)二元操作

使用范圍[first1,last1]中的每個元素作為第一個參數(shù),并使用范圍中從first2開始的各個參數(shù)作為

第二個參數(shù)來調(diào)用binary_op。每個調(diào)用返回的值存儲在從result開始的范圍中。

該函數(shù)允許目標范圍與其中一個輸入范圍相同,以便進行適當?shù)霓D換。

函數(shù)對象適配器:

functionobjectlesstype期望外界傳入兩個值,如果第一個值小于第二個值就返回true。本例中,每個元素都必須和用戶所指定的數(shù)值進行比較。理想情形下,我們需要將lesstype轉化為一個一元(unary)運算符。這可通過將其第二個參數(shù)綁定(bind)至用戶指定的數(shù)值完成。這么一來lesstype便會將每個元素拿出來一一與用戶指定的數(shù)值比較。

真的可以做到這樣嗎?是的。標準庫提供adapter(適配器)便應此而生。

functionobjectadapter會對functionobject進行修改操作。binderadapter(綁定適配器)會將functionobject的參數(shù)綁定至某特定值,使binary(二元)functionobject轉化為unary(一元)functionobject。這正是我們需要的。

標準庫提供了兩個binderadapter:

bind1st會將指定值綁定至第一操作數(shù);

bind2nd將指定值綁定至第二操作數(shù)。

如:ab,則a是第一操作數(shù),b是第二操作數(shù)。

vectorintfilterconstvectorintvec,intval,lessintlt){

vectorintnvec;

vectorint::const_iteratoriter=vec.begin();

while((iter=find_if(iter,vec.end(),bind2nd(lt,val)))!=vec.end()){

nvec.push_back(*iter);

iter++;

returnnvec;

}

bind2nd(less,val);會把val綁定于lessint的第二個參數(shù)身上。于是,lessint會將每個元素拿來和val比較。上例第一操作數(shù)是*iter,第二操作數(shù)就是固定值val。如果*iterval則true。

find_if()的定義如下:

templateclassInputIterator,classUnaryPredicate

InputIteratorfind_if(InputIteratorfirst,InputIteratorlast,UnaryPredicatepred);

●first、last:輸入迭代器到序列的初始和最終位置。使用的范圍是[first,last),它包含first和last之間的所有元素,包括first指向的元素,但不包括last指向的元素。

●pred:接受范圍內(nèi)的元素作為參數(shù)并返回可轉換為bool類型的值的【一元函數(shù)】。返回的值表明該元素是否被認為是此函數(shù)的上下文中的匹配。函數(shù)不能修改它的參數(shù)。它可以是函數(shù)指針,也可以是函數(shù)對象(functionobject)。

●返回值:指向pred不返回false的范圍內(nèi)第一個元素的迭代器。如果pred對所有元素都為false,則函數(shù)返回last。

這個函數(shù)模板的行為相當于:

templateclassInputIterator,classUnaryPredicate

InputIteratorfind_if(InputIteratorfirst,InputIteratorlast,UnaryPredicatepred){

while(first!=last){

if(pred(*first))returnfirst;

++first;

returnlast;

}

下面看一個泛型函數(shù)find_if()的例子:

#includeiostream//std::cout

#includealgorithm//std::find_if

#includevector//std::vector

boolIsOdd(inti){

return((i%2)==1);

intmain(){

std::vectorintmyvector;

myvector.push_back(10);

myvector.push_back(25);

myvector.push_back(40);

myvector.push_back(55);

std::vectorint::iteratorit=

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論