指向函數(shù)的指針的一點理解 (轉(zhuǎn))
Posted on 2009-02-01 21:59 S.l.e!ep.¢% 閱讀(314) 評論(0) 編輯 收藏 引用 所屬分類: C++指向函數(shù)的指針的一點理解
準(zhǔn)確地講,本文所涉及的內(nèi)容是C++中較難理解的,本文的目的不是在于將它們解釋清楚,因為這需要你循序漸進(jìn)地做很多練習(xí)才可以??聪旅嬉粋€例子:
int (*func( bool real))( int , int )
你覺得它的返回值是什么?
這里就涉及到了如何理解指向函數(shù)的指針的問題了。一些來自C++教材的建議是從里向外解讀這個表達(dá)式,這里所謂的里面就是func(bool real),那么剩下的部分就是所謂的返回值了?有點生硬吧。下面就讓我們循序漸進(jìn)地看看如何理解更好?
為什么會對這個表達(dá)式的返回值產(chǎn)生疑問?
要解決問題通常需要找出問題所在,這里是基于這樣一種思維定勢,那就是我們通常習(xí)慣于這樣一種聲明變量的方式:
int a;
這里我們聲明a是一個int類型的變量。而對于返回值,我們通常也是采用類似的方式,如一個返回值為int類型的函數(shù)通??梢砸韵旅娴姆绞竭M(jìn)行聲明:
int func([params]);
因此我們慣性地認(rèn)為返回值就是最左側(cè)的一個類型名,雖然這通常是對的,但是針對上面的那個例子則顯得十分尷尬。
讓我們看看一個指向函數(shù)的指針的聲明式:
int (* pCompare)( int , int );
這個指針的名字就是pCompare,令人奇怪的是pCompare并不是在整個聲明式的最右邊,類型也肯定不是int,而是一個復(fù)雜的表達(dá)式。讓我們用typedef來聲明就會發(fā)現(xiàn)typedef的使用也不太一樣。
typedef int (* PF )( int , int );
我們發(fā)現(xiàn)跟慣用的typedef *** ???;的方式也截然不同,在上面這個typedef過后,整個表達(dá)式可以被簡化成:
PF pCompare;
現(xiàn)在我們似乎就一見如故了,現(xiàn)在的表達(dá)式看起來中規(guī)中矩,普通的聲明都是類型名加變量名完成聲明,而函數(shù)指針的聲明則是在一個表達(dá)式中一個固定的位置進(jìn)行聲明。
?
int (* )( int , int );
在上文中劃線的部分即為聲明的部分,也就是這點不同讓我們逐漸迷失了方向。
現(xiàn)在讓我們寫一個返回指向函數(shù)的指針的函數(shù),也就是返回值是PF的函數(shù),這就像我們從返回int類型的變量到返回int類型值的函數(shù)一樣,因此使用以下方式即可:
PF func([params]);
現(xiàn)在讓我們擴(kuò)展PF,將它還原,也就是把右側(cè)的func([params])部分移到那個橫線的位置上?,F(xiàn)在我們就可以很輕松地理解本文開頭的那個函數(shù),原來是返回值為int (*)(int, int)的函數(shù)
int (*func( bool real))( int , int )
以上劃線的部分也就是一個函數(shù)扣除返回值的部分。也就等價于
PF func( bool real)
至此你應(yīng)該能夠分析更加復(fù)雜的表達(dá)式了。
下面的示例旨在幫助理解本文:
?*?main.cc
?*
?*??Created?on:?2009-2-1
?*??????Author:?Volnet
? */
#include? < stdlib.h >
#include? < iostream >
using ?std::cout;
using ?std::endl;
int ?myCompare1(
???????? int ?a,? int ?b,
???????? int ?( * Compare)( int ,? int ));
int ?realCompare( int ?a,? int ?b);
int ?fakeCompare( int ?a,? int ?b);
typedef? int ?( * PF)( int ,? int );
int ?myCompare2(
???????? int ?a,? int ?b,
????????PF?Compare);
PF?getAPointerFunc1( bool ?real);
int ?( * getAPointerFunc2( bool ?real))( int ,? int );
int ?main( void ){
???? int ?typeDeclared;
????typeDeclared? = ? 1 ;
???? // PF?pCompare;
???? int ?( * pCompare)( int ,? int );
???? if (pCompare? == ?NULL)
????????cout << " pCompare?==?NULL " << endl;
???? else
????{
????????cout << " pCompare?!=?NULL " << " ?pComapre?=? " << pCompare << endl;
????}
????cout << " Compare?the?pointer?function. " << endl;
????cout << " The?compare?result?is?:? " <<
????????myCompare1( 6 ,? 5 ,?realCompare) << endl;
????cout << " It's?the?same?to?invoke?realCompare?&?*realCompare?:? " <<
????????myCompare1( 6 ,? 5 ,? * realCompare) << endl;
????cout << " Using?the?typedef?to?predigest?definition?:? " <<
????????myCompare2( 8 ,? 7 ,?realCompare) << endl;
????cout << " Return?a?pointer?from?a?function?:? " <<
????????myCompare2( 10 ,? 20 ,?getAPointerFunc1( true )) << endl;
????cout << " Return?a?pointer?from?a?function?:? " <<
????????myCompare2( 20 ,? 30 ,?getAPointerFunc2( false )) << endl;
???? return ?EXIT_SUCCESS;
}
int ?myCompare1(
???????? int ?a,? int ?b,
???????? int ?( * Compare)( int ,? int )){
???? return ?Compare(a,?b);
}
int ?realCompare( int ?a,? int ?b){
????cout << " The?realCompare?has?be?invoked. " << endl;
???? if (a? == ?b)
???????? return ? 0 ;
???? if (a? < ?b)
???????? return ? - 1 ;
???? else
???????? return ? 1 ;
}
int ?fakeCompare( int ?a,? int ?b){
????cout << " The?fackCompare?has?be?invoked. " << endl;
???? return ? 200 ;
}
int ?myCompare2(
???????? int ?a,? int ?b,
????????PF?Compare){
???? return ?Compare(a,?b);
}
PF?getAPointerFunc1( bool ?real){
???? if (real)
???????? return ?realCompare;
???? else ? return ?fakeCompare;
}
int ?( * getAPointerFunc2( bool ?real))( int ,? int ){
???? if (real)
???????? return ?realCompare;
???? else ? return ?fakeCompare;
}
?


