Вы находитесь на странице: 1из 3

10/19/2016

TheFunctionPointerTutorialsSyntax

newty.de About Download Links Disclaimer Index

Contact

TheFunctionPointerTutorials

ExtensiveIndex

1.IntroductiontoFunctionPointers

2.TheSyntaxofCandC++FunctionPointers

3.HowtoImplementCallbacksinCandC++?

4.FunctorstoencapsulateCandC++FunctionPointers

5.TopicSpecificLinks

2.TheSyntaxofCandC++FunctionPointers

2.1DefineaFunctionPointer
2.2CallingConvention
2.3AssignanAddresstoaFunctionPointer
2.4ComparingFunctionPointers
2.5CallingaFunctionusingaFunctionPointer
2.6HowtoPassaFunctionPointerasanArgument?
2.7HowtoReturnaFunctionPointer?
2.8HowtoUseArraysofFunctionPointers?

2.1DefineaFunctionPointer

Regarding their syntax, there are two different types of function pointers: On the one hand there are pointers to ordinary C functions or to static C++ member
functions.OntheotherhandtherearepointerstononstaticC++memberfunctions.Thebasicdifferenceisthatallpointerstononstaticmemberfunctionsneeda
hiddenargument:Thethispointertoaninstanceoftheclass.Alwayskeepinmind:Thesetwotypesoffunctionpointersareincompatiblewitheachother.
Sinceafunctionpointerisnothingelsethanavariable,itmustbedefinedasusual.Inthefollowingexamplewedefinethreefunctionpointersnamedpt2Function,
pt2Memberandpt2ConstMember.Theypointtofunctions,whichtakeonefloatandtwocharandreturnanint.IntheC++exampleitisassumed,thatthefunctions,
ourpointerspointto,are(nonstatic)memberfunctionsofTMyClass.

//2.1defineafunctionpointerandinitializetoNULL
int(*pt2Function)(float,char,char)=NULL;//C
int(TMyClass::*pt2Member)(float,char,char)=NULL;//C++
int(TMyClass::*pt2ConstMember)(float,char,char)const=NULL;//C++

2.2CallingConvention

Normallyyoudon'thavetothinkaboutafunction'scallingconvention:Thecompilerassumes__cdeclasdefaultifyoudon'tspecifyanotherconvention.Howeverif
youwanttoknowmore,keeponreading...Thecallingconventiontellsthecompilerthingslikehowtopasstheargumentsorhowtogeneratethenameofafunction.
Someexamplesforothercallingconventionsare__stdcall,__pascaland__fastcall.Thecallingconventionbelongstoafunction'ssignature:Thus functions and
function pointers with different calling convention are incompatible with each other! For Borland and Microsoft compilers you specify a specific calling
conventionbetweenthereturntypeandthefunction'sorfunctionpointer'sname.FortheGNUGCCyouusethe__attribute__keyword:Writethefunctiondefinition
followedbythekeyword__attribute__andthenstatethecallingconventionindoubleparentheses.Ifsomeoneknowsmore:Letmeknow)Andifyouwanttoknow
howfunctioncallsworkunderthehoodyoushouldtakealookatthechapterSubprogramsinPaulCarter'sPCAssemblyTutorial.
//2.2definethecallingconvention
void__cdeclDoIt(floata,charb,charc);//BorlandandMicrosoft
voidDoIt(floata,charb,charc)__attribute__((cdecl));//GNUGCC

2.3AssignanaddresstoaFunctionPointer

It'squiteeasytoassigntheaddressofafunctiontoafunctionpointer.Yousimplytakethenameofasuitableandknownfunctionormemberfunction.Althoughit's
optionalformostcompilersyoushouldusetheaddressoperator&infrontofthefunction'snameinordertowriteportablecode.Youmayhavegottousethecomplete
nameofthememberfunctionincludingclassnameandscopeoperator(::).Alsoyouhavegottoensure,thatyouareallowedtoaccessthefunctionrightinscope
whereyourassignmentstands.
//2.3assignanaddresstothefunctionpointer
//Note:Althoughyoumayommittheaddressoperatoronmostcompilers
//youshouldalwaysusethecorrectwayinordertowriteportablecode.
//C
intDoIt(floata,charb,charc){printf("DoIt\n");returna+b+c;}
intDoMore(floata,charb,charc)const{printf("DoMore\n");returnab+c;}
pt2Function=DoIt;//shortform
pt2Function=&DoMore;//correctassignmentusingaddressoperator

//C++
classTMyClass
{
public:
intDoIt(floata,charb,charc){cout<<"TMyClass::DoIt"<<endl;returna+b+c;};
intDoMore(floata,charb,charc)const
{cout<<"TMyClass::DoMore"<<endl;returnab+c;};
/*moreofTMyClass*/
};
pt2ConstMember=&TMyClass::DoMore;//correctassignmentusingaddressoperator
pt2Member=&TMyClass::DoIt;//note:<pt2Member>mayalsolegallypointto&DoMore

2.4ComparingFunctionPointers

Youcanusethecomparisonoperators(==,!=)thesamewayasusual.Inthefollowingexampleitischecked,whetherpt2Functionandpt2Memberactuallycontain
theaddressofthefunctionsDoItandTMyClass::DoMore.Atextisshownincaseofequality.
//2.4comparingfunctionpointers

http://www.newty.de/fpt/fpt.html

1/3

10/19/2016

TheFunctionPointerTutorialsSyntax

//C
if(pt2Function>0){//checkifinitialized
if(pt2Function==&DoIt)
printf("PointerpointstoDoIt\n");}
else
printf("Pointernotinitialized!!\n");
//C++
if(pt2ConstMember==&TMyClass::DoMore)
cout<<"PointerpointstoTMyClass::DoMore"<<endl;

2.5CallingaFunctionusingaFunctionPointer

InCyoucallafunctionusingafunctionpointerbyexplicitlydereferencingitusingthe*operator.Alternativelyyoumayalsojustusethefunctionpointer'sinsteadof
thefuntion'sname.InC++thetwooperators.*resp.>*areusedtogetherwithaninstanceofaclassinordertocalloneoftheir(nonstatic)memberfunctions.Ifthe
calltakesplacewithinanothermemberfunctionyoumayusethethispointer.
//2.5callingafunctionusingafunctionpointer
intresult1=pt2Function(12,'a','b');//Cshortway
intresult2=(*pt2Function)(12,'a','b');//C
TMyClassinstance1;
intresult3=(instance1.*pt2Member)(12,'a','b');//C++
intresult4=(*this.*pt2Member)(12,'a','b');//C++ifthispointercanbeused
TMyClass*instance2=newTMyClass;
intresult4=(instance2>*pt2Member)(12,'a','b');//C++,instance2isapointer
deleteinstance2;

2.6HowtoPassaFunctionPointerasanArgument?

Youcanpassafunctionpointerasafunction'scallingargument.Youneedthisforexampleifyouwanttopassapointertoacallbackfunction.Thefollowingcode
showshowtopassapointertoafunctionwhichreturnsanintandtakesafloatandtwochar:
//
//2.6HowtoPassaFunctionPointer
//<pt2Func>isapointertoafunctionwhichreturnsanintandtakesafloatandtwochar
voidPassPtr(int(*pt2Func)(float,char,char))
{
intresult=(*pt2Func)(12,'a','b');//callusingfunctionpointer
cout<<result<<endl;
}
//executeexamplecode'DoIt'isasuitablefunctionlikedefinedabovein2.14
voidPass_A_Function_Pointer()
{
cout<<endl<<"Executing'Pass_A_Function_Pointer'"<<endl;
PassPtr(&DoIt);
}

2.7HowtoReturnaFunctionPointer?

It'salittlebittrickybutafunctionpointercanbeafunction'sreturnvalue.Inthefollowingexampletherearetwosolutionsofhowtoreturnapointertoafunctionwhich
istakingtwofloatargumentsandreturnsafloat.Ifyouwanttoreturnapointertoamemberfunctionyouhavejustgottochangethedefinitions/declarationsofall
functionpointers.
//
//2.7HowtoReturnaFunctionPointer
//'Plus'and'Minus'aredefinedabove.Theyreturnafloatandtaketwofloat
//Directsolution:Functiontakesacharandreturnsapointertoa
//functionwhichistakingtwofloatsandreturnsafloat.<opCode>
//specifieswhichfunctiontoreturn
float(*GetPtr1(constcharopCode))(float,float)
{
if(opCode=='+')
return&Plus;
else
return&Minus;//defaultifinvalidoperatorwaspassed
}
//Solutionusingatypedef:Defineapointertoafunctionwhichistaking
//twofloatsandreturnsafloat
typedeffloat(*pt2Func)(float,float);
//Functiontakesacharandreturnsafunctionpointerwhichisdefined
//withthetypedefabove.<opCode>specifieswhichfunctiontoreturn
pt2FuncGetPtr2(constcharopCode)
{
if(opCode=='+')
return&Plus;
else
return&Minus;//defaultifinvalidoperatorwaspassed
}
//Executeexamplecode
voidReturn_A_Function_Pointer()
{
cout<<endl<<"Executing'Return_A_Function_Pointer'"<<endl;
//defineafunctionpointerandinitializeittoNULL
float(*pt2Function)(float,float)=NULL;
pt2Function=GetPtr1('+');//getfunctionpointerfromfunction'GetPtr1'
cout<<(*pt2Function)(2,4)<<endl;//callfunctionusingthepointer
pt2Function=GetPtr2('');//getfunctionpointerfromfunction'GetPtr2'
cout<<(*pt2Function)(2,4)<<endl;//callfunctionusingthepointer
}

2.8HowtoUseArraysofFunctionPointers?

http://www.newty.de/fpt/fpt.html

2/3

10/19/2016

TheFunctionPointerTutorialsSyntax

Operatingwitharraysoffunctionpointersisveryinteresting.Thisoffersthepossibilitytoselectafunctionusinganindex.Thesyntaxappearsdifficult,whichfrequently
leads to confusion. Below you find two ways of how to define and use an array of function pointers in C and C++. The first way uses a typedef, the second way
directlydefinesthearray.It'suptoyouwhichwayyouprefer.
//
//2.8HowtoUseArraysofFunctionPointers
//C
//typedefinition:'pt2Function'nowcanbeusedastype
typedefint(*pt2Function)(float,char,char);
//illustratehowtoworkwithanarrayoffunctionpointers
voidArray_Of_Function_Pointers()
{
printf("\nExecuting'Array_Of_Function_Pointers'\n");
//definearraysandinieachelementtoNULL,<funcArr1>and<funcArr2>arearrays
//with10pointerstofunctionswhichreturnanintandtakeafloatandtwochar
//firstwayusingthetypedef
pt2FunctionfuncArr1[10]={NULL};
//2ndwaydirectlydefiningthearray
int(*funcArr2[10])(float,char,char)={NULL};
//assignthefunction'saddress'DoIt'and'DoMore'aresuitablefunctions
//likedefinedabovein2.14
funcArr1[0]=funcArr2[1]=&DoIt;
funcArr1[1]=funcArr2[0]=&DoMore;
/*moreassignments*/
//callingafunctionusinganindextoaddressthefunctionpointer
printf("%d\n",funcArr1[1](12,'a','b'));//shortform
printf("%d\n",(*funcArr1[0])(12,'a','b'));//"correct"wayofcalling
printf("%d\n",(*funcArr2[1])(56,'a','b'));
printf("%d\n",(*funcArr2[0])(34,'a','b'));
}
//C++
//typedefinition:'pt2Member'nowcanbeusedastype
typedefint(TMyClass::*pt2Member)(float,char,char);
//illustratehowtoworkwithanarrayofmemberfunctionpointers
voidArray_Of_Member_Function_Pointers()
{
cout<<endl<<"Executing'Array_Of_Member_Function_Pointers'"<<endl;
//definearraysandinieachelementtoNULL,<funcArr1>and<funcArr2>are
//arrayswith10pointerstomemberfunctionswhichreturnanintandtake
//afloatandtwochar
//firstwayusingthetypedef
pt2MemberfuncArr1[10]={NULL};
//2ndwayofdirectlydefiningthearray
int(TMyClass::*funcArr2[10])(float,char,char)={NULL};
//assignthefunction'saddress'DoIt'and'DoMore'aresuitablemember
//functionsofclassTMyClasslikedefinedabovein2.14
funcArr1[0]=funcArr2nduseanarrayoffunctionpointersinCandC++.Thefirstwayusesatypedef,thesecondwaydirectlydefinesthearray.It'suptoyouwhichwayyouprefer.
[1]=&TMyClass::DoIt;
funcArr1[1]=funcArr2[0]=&TMyClass::DoMore;
/*moreassignments*/
//callingafunctionusinganindextoaddressthememberfunctionpointer
//note:aninstanceofTMyClassisneededtocallthememberfunctions
TMyClassinstance;
cout<<(instance.*funcArr1[1])(12,'a','b')<<endl;
cout<<(instance.*funcArr1[0])(12,'a','b')<<endl;
cout<<(instance.*funcArr2[1])(34,'a','b')<<endl;
cout<<(instance.*funcArr2[0])(89,'a','b')<<endl;
}

YoucandownloadaPostscriptoraPDFofthetutorialsaboutFunctionPointers,CallbacksandFunctors!
VouspouveztlchargeruneversionPostscriptouPDFdeceturorielsurlespointeursdefonctions,lesfonctionderappeletlesfunctors!
Youcanalsodownloadthezippedsourcefileswithallexamplesofthetutorials!

Visitorssince24.05.2001
lastupdated:01January201120002005byLarsEngelfried
ThesourcecodepresentedwashighlightedusingmyfreeSourcetoHTMLConvertertool.

http://www.newty.de/fpt/fpt.html

3/3

Вам также может понравиться