1、定义一个函数指针
有两种不同类型的函数指针,一种是指向普通C函数或者C++静态成员函数的指针,另外一种是指向非静态的成员函数指针。基本的区别是指向非成员函数的指针需要一个隐藏参数:this指针。永远记住,这两类函数指针不兼容。由于函数指针其实就是一个变量,所以必须像往常一样定义。
//define a function pointer and initialize to NULL 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、调用惯例 正常来讲不用考虑函数的调用惯例,如果不作特别声明,编译器默认是__cdecl的方式。调用惯例通知编译器 诸如如何传递参数或者如何产生函数名称。其他的方式如__stdcall, __pascal 和 __fastcall。使用不同调 用的函数和函数指针不互相兼容!//define the calling convention void __cdecl DoIt(float a, char b, char c); // Borland and Microsoft void DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC
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.
// C
int 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 form
pt2Function = &DoMore; // correct assignment using address operator
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
4、比较函数指针
可以像往常一样使用比较操作符。
// comparing function pointers
// C
if(pt2Function >0){ // check if initialized
if(pt2Function == &DoIt)
printf("Pointer points to DoIt/n"); }
else
printf("Pointer not initialized!!/n");
// C++
if(pt2ConstMember == &TMyClass::DoMore)
cout << "Pointer points to TMyClass::DoMore" << endl;
5、通过函数指针调用函数
在C语言里,你可以显示使用*操作符来解引用函数指针,另外的方法就是只用函数指针的名字取代函数的名字。在C++里,.*和->*这两个操作符可以用来调用类实例的非静态成员函数。如果调用发生在另外一个成员函数里,你可以使用this指针。
// calling a function using a function pointer
int result1 = pt2Function (12, 'a', 'b'); // C short way
int result2 = (*pt2Function) (12, 'a', 'b'); // C
TMyClass instance1;
int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++
int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be used
TMyClass* instance2 = new TMyClass;
int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointer
delete instance2;
6、怎么样将函数指针作为一个参数传递
// How to Pass a Function Pointer
// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}
// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}
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. <opCode>
// specifies which function to return
float (*GetPtr1(const char opCode))(float, float)
{
if(opCode == '+')
return &Plus;
else
return &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 float
typedef float(*pt2Func)(float, float);
// Function takes a char and returns a function pointer which is defined
// with the typedef above. <opCode> specifies which function to return
pt2Func GetPtr2(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
// Execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;
// define a function pointer and initialize it to NULL
float (*pt2Function)(float, float) = NULL;
pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
}
8、怎么样使用函数指针数组
这是非常有趣的作法,语法看起来较难,而且经常引起混淆。下面是两种方式定义和使用,究竟用哪个取决于你。
// How to Use Arrays of Function Pointers
// C ---------------------------------------------------------------------------------
// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);
// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
printf("/nExecuting 'Array_Of_Function_Pointers'/n");
// define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are arrays
// with 10 pointers to functions which return an int and take a float and two char
// first way using the typedef
pt2Function funcArr1[10] = {NULL};
// 2nd way directly defining the array
int (*funcArr2[10])(float, char, char) = {NULL};
// assign the function's address - 'DoIt' and 'DoMore' are suitable functions
// like defined above in 2.1-4
funcArr1[0] = funcArr2[1] = &DoIt;
funcArr1[1] = funcArr2[0] = &DoMore;
/* more assignments */
// calling a function using an index to address the function pointer
printf("%d/n", funcArr1[1](12, 'a', 'b')); // short form
printf("%d/n", (*funcArr1[0])(12, 'a', 'b')); // "correct" way of calling
printf("%d/n", (*funcArr2[1])(56, 'a', 'b'));
printf("%d/n", (*funcArr2[0])(34, 'a', 'b'));
}
// C++ -------------------------------------------------------------------------------
// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(float, char, char);
// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;
// define arrays and ini each element to NULL, <funcArr1> and <funcArr2> are
// arrays with 10 pointers to member functions which return an int and take
// a float and two char
// first way using the typedef
pt2Member funcArr1[10] = {NULL};
// 2nd way of directly defining the array
int (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-4
funcArr1[0] = funcArr2nd use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.
[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 functions
TMyClass instance;
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;
}