函数指针传递的两种环境(全局函数与类成员函数)

本文详细解析了C++中类成员函数指针的使用方法,包括不同类型的函数指针传递方式及其区别,同时提供了丰富的代码示例帮助理解。

转载请标明是引用于 http://blog.youkuaiyun.com/chenyujing1234

欢迎大家提出意见,一起讨论!

最近在代码中看到指针的调用方式,有些疑问,于是在论坛上发了问题

http://topic.youkuaiyun.com/u/20120531/15/904ece4c-013a-4df4-8a7f-41cca854f3e0.html?seed=627050603&r=78731714#r_78731714

现在对这个问题做个总结。

1、 函数指针的传递的两种环境(类成员函数)

运行的结果是:

I am function_One_Instance I am function_Second_Instance

下面是原代码:

// ================================类里的函数指针调用方法==================================== class CTestFun { public: // 测试函数 void testFunction(void) { // 方法一的使用 function_One_User(function_One_Instance); // 方法二的使用 function_Second_User(&CTestFun::function_Second_Instance); } protected: // ================================法一:==================================== /***************************************************************************** 总结:如果函数实例没有定义成static形式,那么: (1)那么函数指针的声明得加类空间名字; (2)在函数实例使用者内部得用this->来引用到函数指针 (3)在函数实例使用者的参数处得使用 CTestFun:来引用函数实例。 */ // 函数类型定义 // 下面两名等价于 typedef void (*PFunction_One)(); typedef void function_One(); typedef function_One *PFunction_One; // 函数实例 static void function_One_Instance() { printf("I am function_One_Instance\n"); } // 函数使用者 void function_One_User(PFunction_One function) { function(); } // ================================法二:===================================== /***************************************************************************** 总结:如果函数实例没有定义成static形式,那么: (1)那么函数指针的声明得加类空间名字; (2)在函数实例使用者内部得用this->来引用到函数指针 (3)在函数实例使用者的参数处得使用 CTestFun:来引用函数实例。 */ // 函数类型定义 // 定义一个原型为BOOL Fun(int a);的函数指针 typedef BOOL (CTestFun::*function_Second)(int); // 函数实例 BOOL function_Second_Instance(int candidate) { printf("I am function_Second_Instance\n"); return TRUE; } // 函数使用者 BOOL function_Second_User(function_Second function) { // function其实是函数的指针 // 这里的"*function"是指找到function在类中的函数地址。 // 不是表明function是函数的指针的指针 // 一句话,使用类成员函数指针必须有“->*”或“.*”的调用 if ( (this->*function)(1) == TRUE ) return FALSE; return TRUE; } }; int main() { CTestFun testFun; testFun.testFunction(); system("pause"); return 0; }


对于上面列出的代码,我的问题是:
1、把
if ( (this->*function)(1) == TRUE )
改为
if ( (/*this->*/*function)(1) == TRUE )
就会报错:
error C2171: “*”: “CTestFun::function_Second”类型的操作数非法
error C2064: 项不会计算为接受 1 个参数的函数

2、
若改为
if ( (/*this->**/function)(1) == TRUE )
就会报错:
error C2064: 项不会计算为接受 1 个参数的函数
这是为什么呢? 为什么一定要加this.

1、2两个问题是同一个问题。

答:

如果函数实例没有定义成static形式,那么:
(1)那么函数指针的声明得加类空间名字,以此具有全局属性。
(2)在函数实例使用者内部得用this->来引用到函数指针
(3)在函数实例使用者的参数处得使用 CTestFun:来引用函数实例。


3、BOOL function_Second_User(function_Second function)
中的形参是函数指针而已。
而调用的时候为什么是
function_Second_User(&CTestFun::function_Second_Instance); (加了& ,即函数的指针的指针)
4、 void function_One_User(PFunction_One function)
中的形参是函数的指针的指针,
而调用时为什么是
function_One_User((PFunction_One)function_One_Instance);
只是函数指针?
3、4 其实是同一个问题。

答:

由于加了CTestFun::来引用类中的函数成员
所以加上 &。一句话,这是类中的规定。

2、 函数指针的传递的两种环境(全局函数)

// ================================全局时函数指针调用方法==================================== /***************************************************************************** 总结:由于在全局的函数都默认是加了static的。 */ // 定义一个原型为int Fun( int a );的函数指针 typedef int (*PTRFUN)(int aPara); // pFun 为函数指针变量名 PTRFUN pFun; // pFun2也是函数指针变量名 int (*pFun2)(int a); // 定义回调函数 int CallBack(int a) { printf("I am CallBack\n"); return ++a; } // 定义回调者函数 void Caller( PTRFUN cb ) // void Caller( int (*cb) ( int ) ) // 也可这样申明 { int nPara = 1; int nRet = cb( nPara ); } // 使用回调 void TestFunP() { Caller(CallBack); // 直接使用回调函数 PTRFUN cb = CallBack; // int (*cb) ( int ); cb = CallBack; int nRet1 = cb( 99 ); // nRet1 = 100; } // ================================函数指针的指针使用======================================== // 定义函数指针的指针 typedef int (**PTRPTRFUN)(int aPara); // 函数指针的指针作为参数 void PtrCaller(PTRPTRFUN cb) // void PtrCaller( PTRFUN* cb ) // 指针申明 // void PtrCaller( int (**cb) ( int ) ) // 原型申明 { int nRet = (*cb)(999); // nRet = 1000; } // 使用函数指针的指针 void TestFunPP() { PTRFUN cb = CallBack; PtrCaller( &cb ); } // ================================函数指针数组的使用======================================== // 函数指针数组的定义 PTRFUN fArray[10]; // int (*fArray[10])(int); // 原型定义 void TestFunPArray() { for ( int i = 0; i < 10; i++ ) { fArray[i] = CallBack; int nRet = fArray[i](i); // nRet = i+1; } } // ================================函数指针与typedef======================================== // 形式一: // 定义了一个指针变量pFun1 // 它是一个指向某种函数的指针 char (*pFun1)(int); // 定义一个函数。 // 函数的函数名实际上就是一个指针,函数名指向该函数的代码在内存中的首地址 char glFun(int a){ return 1;} void testF1() { pFun1 = glFun; // 取pFun1所指向的地址的内容,当然就是取出了glFun()的内容 (*pFun)(2); } // 形式二:typedef 返回类型(*新类型)(参数表) // typedef char (*PTRFUN)(int); // PTRFUN pFun; // char glFun(int a){ return;} // void main() // { // pFun = glFun; // (*pFun)(2); // }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值