详细认识函数指针

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值