準(zhǔn)確地講,本文所涉及的內(nèi)容是C++中較難理解的,本文的目的不是在于將它們解釋清楚,因?yàn)檫@需要你循序漸進(jìn)地做很多練習(xí)才可以。看下面一個(gè)例子:
int (*func(bool real))(int, int)
你覺(jué)得它的返回值是什么?
這里就涉及到了如何理解指向函數(shù)的指針的問(wèn)題了。一些來(lái)自C++教材的建議是從里向外解讀這個(gè)表達(dá)式,這里所謂的里面就是func(bool real),那么剩下的部分就是所謂的返回值了?有點(diǎn)生硬吧。下面就讓我們循序漸進(jìn)地看看如何理解更好?
為什么會(huì)對(duì)這個(gè)表達(dá)式的返回值產(chǎn)生疑問(wèn)?
要解決問(wèn)題通常需要找出問(wèn)題所在,這里是基于這樣一種思維定勢(shì),那就是我們通常習(xí)慣于這樣一種聲明變量的方式:
int a;
這里我們聲明a是一個(gè)int類型的變量。而對(duì)于返回值,我們通常也是采用類似的方式,如一個(gè)返回值為int類型的函數(shù)通常可以以下面的方式進(jìn)行聲明:
int func([params]);
因此我們慣性地認(rèn)為返回值就是最左側(cè)的一個(gè)類型名,雖然這通常是對(duì)的,但是針對(duì)上面的那個(gè)例子則顯得十分尷尬。
讓我們看看一個(gè)指向函數(shù)的指針的聲明式:
int (*pCompare)(int, int);
這個(gè)指針的名字就是pCompare,令人奇怪的是pCompare并不是在整個(gè)聲明式的最右邊,類型也肯定不是int,而是一個(gè)復(fù)雜的表達(dá)式。讓我們用typedef來(lái)聲明就會(huì)發(fā)現(xiàn)typedef的使用也不太一樣。
typedef int (*PF)(int, int);
我們發(fā)現(xiàn)跟慣用的typedef *** ???;的方式也截然不同,在上面這個(gè)typedef過(guò)后,整個(gè)表達(dá)式可以被簡(jiǎn)化成:
PF pCompare;
現(xiàn)在我們似乎就一見(jiàn)如故了,現(xiàn)在的表達(dá)式看起來(lái)中規(guī)中矩,普通的聲明都是類型名加變量名完成聲明,而函數(shù)指針的聲明則是在一個(gè)表達(dá)式中一個(gè)固定的位置進(jìn)行聲明。
int (* )(int, int);
在上文中劃線的部分即為聲明的部分,也就是這點(diǎn)不同讓我們逐漸迷失了方向。
現(xiàn)在讓我們寫一個(gè)返回指向函數(shù)的指針的函數(shù),也就是返回值是PF的函數(shù),這就像我們從返回int類型的變量到返回int類型值的函數(shù)一樣,因此使用以下方式即可:
PF func([params]);
現(xiàn)在讓我們擴(kuò)展PF,將它還原,也就是把右側(cè)的func([params])部分移到那個(gè)橫線的位置上?,F(xiàn)在我們就可以很輕松地理解本文開(kāi)頭的那個(gè)函數(shù),原來(lái)是返回值為int (*)(int, int)的函數(shù)
int (*func(bool real))(int, int)
以上劃線的部分也就是一個(gè)函數(shù)扣除返回值的部分。也就等價(jià)于
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;
}