1  定义一个函数指针且不论语法,有两种不同形式的指针函数:一个是指向普通的C函数的指针和C++的静态成员函数,另外一个是指向C++的非静态成员函数的指针。这两者的基本区别是所有指向非静态成员函数的指针都 需要这个隐含定义:指向本类的一个This指针。注意:这两种函数指针彼此不兼容。既然一个函数指针实际上和一个变量没有什么区别,定义它的时候也就没有什么特殊。下面的例子中我们定义3个函数指针,名字是pt2Function, pt2Member 和 pt2ConstMember. 它们指向的函数,输入一个 float和两个char 类型的变量并返回一个 int 类型的变量. 对于C++程序例子,我们的指针指向的的函数,是一个叫做 TMyClass 的 类的非静态成员函数。// 1 define a function pointer and initialize to NULLint (*pt2Function)(float, char, char) = NULL; // Cint (TMyClass::*pt2Member)(float, char, char) = NULL; // C++int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL; // C++2 函数调用规范通常你不需要考虑一个函数的调用规范:编译器缺省的使用__cdecl,如果你不特别指出用哪个的话。调用规范告诉编译器如何传 递参数以及如何产生函数名。一些其他的调用规范可以举例为:__stdcall, __pascal和__fastcall. 注意:使用不同调用规范的函数指针彼此不兼容。// 2 define the calling conventionvoid __cdecl DoIt(float a, char b, char c); // Borland and Microsoftvoid DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC3 为函数指针分派一个地址将函数的地址分派给函数指针很容易,在函数名字之前冠以取址符&就可以了。// 3 assign an address to the function pointer// Note: Although you may ommit the address operator on most compilers// you should always use the correct way in order to write portable code.// Cint DoIt (float a, char b, char c){ printf("DoIt\n"); return a+b+c; }int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }pt2Function = DoIt; // short formpt2Function = &DoMore; // correct assignment using address operator// C++class TMyClass{public:int DoIt(float a, char b, char c){ cout "TMyClass::DoIt"return a+b+c;};int DoMore(float a, char b, char c) const{ cout "TMyClass::DoMore" return a-b+c; };/* more of TMyClass */};pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operatorpt2Member = &TMyClass::DoIt; // note: may also legally point to &DoMore4 比较函数指针你可以和通常方式一样使用比较符号(==, !=)。下面的例子中我们检查变量 pt2Function 和 pt2Member ,它们分别指向的函数 DoIt 和 TMyClass::DoMore. 如果指向正确就会输出代表争取的字符串。// 4 comparing function pointers// Cif(pt2Function >0){ // check if initializedif(pt2Function == &DoIt)printf("Pointer points to DoIt\n"); }elseprintf("Pointer not initialized!!\n");// C++if(pt2ConstMember == &TMyClass::DoMore)cout "Pointer points to TMyClass::DoMore"5  使用函数指针调用函数在C语言中我们可以通过 * 符号来调用函数指针,也可以不使用函数名而代以函数指针的名字。C++使用两个符号 * 和 ->* 来调用类的非静态函数指针。如果呼叫在其他成员函数中发生,那么就得加上this指针。// 5 calling a function using a function pointerint result1 = pt2Function (12, 'a', 'b'); // C short wayint result2 = (*pt2Function) (12, 'a', 'b'); // CTMyClass instance1;int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be usedTMyClass* instance2 = new TMyClass;int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointerdelete instance2;6  如何像传递一个参数一样传递函数指针你可以在调用一个函数的时候把函数指针当作参数来传递。在回调函数中尤其要使用到这个技术。下边这个例子演示了如何把指针传递给一个函数,这个 函数使用一个 float 和两个 char 类型的参数并有一个int类型的返回值。//------------------------------------------------------------------------------------// 6 How to Pass a Function Pointer// is a pointer to a function which returns an int and takes a float and two charvoid PassPtr(int (*pt2Func)(float, char, char)){int result = (*pt2Func)(12, 'a', 'b'); // call using function pointercout}// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4void Pass_A_Function_Pointer(){cout "Executing 'Pass_A_Function_Pointer'"PassPtr(&DoIt);}7  如何返回一个函数指针看上去有点怪,但是一个函数指针可以作为一个函数的返回值。下面的例子中提供了两种把函数指针作为返回值的解决方案。这个函数输入两个float类 型的参数,返回一个float类型的值。//------------------------------------------------------------------------------------// 7 How to Return a Function Pointer// 'Plus' and 'Minus' are defined above. They return a float and take two float// Direct solution: Function takes a char and returns a pointer to a// function which is taking two floats and returns a float.// specifies which function to returnfloat (*GetPtr1(const char opCode))(float, float){if(opCode == '+')return &Plus;elsereturn &Minus; // default if invalid operator was passed}// Solution using a typedef: Define a pointer to a function which is taking// two floats and returns a floattypedef float(*pt2Func)(float, float);// Function takes a char and returns a function pointer which is defined// with the typedef above. specifies which function to returnpt2Func GetPtr2(const char opCode){if(opCode == '+')return &Plus;elsereturn &Minus; // default if invalid operator was passed}// Execute example codevoid Return_A_Function_Pointer(){cout "Executing 'Return_A_Function_Pointer'"// define a function pointer and initialize it to NULLfloat (*pt2Function)(float, float) = NULL;pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'cout 2, 4) // call function using the pointerpt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'cout 2, 4) // call function using the pointer}8  如何使用函数指针数组使用函数指针数组非常有意思,这个技术提供了一种从索引中选择函数的方法。实现的语法看上去很复杂,经常导致理解错误。下面的例子中我们可以看 到两种定义和使用函数指针数组的方法。前一种使用 typedef ,后一种直接定义数组。使用哪一种全凭你的兴趣。//------------------------------------------------------------------------------------// 8 How to Use Arrays of Function Pointers// C ---------------------------------------------------------------------------------// type-definition: 'pt2Function' now can be used as typetypedef int (*pt2Function)(float, char, char);// illustrate how to work with an array of function pointersvoid Array_Of_Function_Pointers(){printf("\nExecuting 'Array_Of_Function_Pointers'\n");// define arrays and ini each element to NULL, and are arrays// with 10 pointers to functions which return an int and take a float and two char// first way using the typedefpt2Function funcArr1[10] = {NULL};// 2nd way directly defining the arrayint (*funcArr2[10])(float, char, char) = {NULL};// assign the function's address - 'DoIt' and 'DoMore' are suitable functions// like defined above in 1-4funcArr1[0] = funcArr2[1] = &DoIt;funcArr1[1] = funcArr2[0] = &DoMore;/* more assignments */// calling a function using an index to address the function pointerprintf("%d\n", funcArr1[1](12, 'a', 'b')); // short formprintf("%d\n", (*funcArr1[0])(12, 'a', 'b')); // "correct" way of callingprintf("%d\n", (*funcArr2[1])(56, 'a', 'b'));printf("%d\n", (*funcArr2[0])(34, 'a', 'b'));}// C++ -------------------------------------------------------------------------------// type-definition: 'pt2Member' now can be used as typetypedef int (TMyClass::*pt2Member)(float, char, char);// illustrate how to work with an array of member function pointersvoid Array_Of_Member_Function_Pointers(){cout "Executing 'Array_Of_Member_Function_Pointers'"// define arrays and ini each element to NULL, and are// arrays with 10 pointers to member functions which return an int and take// a float and two char// first way using the typedefpt2Member funcArr1[10] = {NULL};// 2nd way of directly defining the arrayint (TMyClass::*funcArr2[10])(float, char, char) = {NULL};// assign the function's address - 'DoIt' and 'DoMore' are suitable member// functions of class TMyClass like defined above in 2.1-4funcArr1[0] = funcArr2nd use an array offunction pointers in C and C++. The first way uses a typedef, thesecond way directly defines the array. It's up to you which way youprefer.[1] = &TMyClass::DoIt;funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;/* more assignments */// calling a function using an index to address the member function pointer// note: an instance of TMyClass is needed to call the member functionsTMyClass instance;cout 1])(12, 'a', 'b')cout 0])(12, 'a', 'b')cout 1])(34, 'a', 'b')cout 0])(89, 'a', 'b')}
02-05 21:53