函数指针

全局函数指针的基本使用方法

//函数类型   
typedef int fun1( int );  
//函数指针类型   
typedef int (*fun2)( int );  
//函数指针   
int (*g_fun)(int);  
  
int fun( int n )  
{  
    return n * n;   
}  
  
void main()  
{  
    int nRes = 0;  
    fun1* f1 = fun;  
    fun2  f2 = fun;  
    g_fun = fun;  
    nRes = f1( 1 );  
    nRes = f2( 2 );  
    nRes = g_fun(3);  
    nRes = (*g_fun)(4);  
}  
#include <string>
#include <vector>
#include <iostream>
using namespace std; 

/**********************************************************
定义函数对象:重载()运算符. 
仿函数的方式类似指针函数。
***********************************************************/ 
//为了通用性,使用模板。
//通常,函数对象不定义构造函数和析构函数。因此,在创建和销毁过程中就不会发生任何问题。
struct GenericNegate
{
 GenericNegate(){};
 ~GenericNegate(){};
 //返回值类型和参数类型都是T的运算符重载。
 template <class T> T operator() (T t) const {return -t;}
}; 
void functioner(int n, GenericNegate & afun) 
{
 int val = afun(n); //调用重载的操作符"()". 
 cout << val<<endl;
}
 void main_function()
 {
  GenericNegate obj;
  functioner(3,obj);
 } 
/**********************************************************
 静态函数指针.
 由于类成员函数有this指针做为一个参数,所以不能使用。
 以下使用了全局函数和类的静态成员函数
***********************************************************/
typedef int (*GlobalFunType)(int n);
int gFun(int n) { return -n; } 
class CFunBase
{
public:
 void SetFun( GlobalFunType pFun ){ m_pFun = pFun;}
 GlobalFunType GetFun() { return m_pFun; }
 static int mFun(int n){ return 6 ;} //成员函数是__thiscall调用方式,这里必须使用静态成员函数
 GlobalFunType m_pFun;
}; 
void main_staticfun()
{
 int nres = 0;
 CFunBase obj;
 obj.SetFun(gFun);
 nres = obj.GetFun()(100); 
 obj.SetFun(&CFunBase::mFun);
 nres = obj.GetFun()(0);
} 

/************************************************************************/
/*  静态类成员指针函数    
 
 原理同上。举个例子来注意类成员指针函数的静态定义和非静态定义的表示方式*/
/************************************************************************/
class CFunBase
{
public:
 typedef int (*FunType)(int n); //表示静态成员函数指针类型
 void SetFun( FunType pFun ){ m_pFun = pFun;}
 /*virtual*/ static int RealFun(int n){ return 0 ;}
 FunType m_pFun;
}; 
void main()
{
 CFunBase * obj = new CFunBase();
 obj->SetFun(&CFunBase::RealFun);
 int n = obj->m_pFun(5);
 
 getchar();
} 
/************************************************************************/
/* 类成员指针函数                                                                     */
/************************************************************************/ 
class CFunBase
{
public:
 typedef int (CFunBase::*FunType)(int n); //非静态成员函数指针类型
 void SetFun( FunType pFun ){ m_pFun = pFun;}
 FunType GetFun() { return m_pFun; }
 virtual int RealFun(int n){ return 0 ;}
 FunType m_pFun;
}; 
class CFunDrive : public CFunBase
{
public:
 virtual int RealFun( int n ) { return n*2 ;}
 int TestFun(int n) { return 100; }
}; 
void main_memberfunptr()
{
 int nres = 0; 
 //基类 普通的使用方式
 CFunBase * obj = new CFunBase();
 obj->SetFun(&CFunBase::RealFun);
 nres = (obj->*(obj->m_pFun))(5); 
 nres = (obj->*(obj->GetFun()))(5);
 delete obj;
 obj = NULL; 
 //多态 如果传入的是虚函数,会有多态效果。
 //因为非静态成员函数指针类型有this指针传递,能找到真正的对象.
 //但是人为的传递派生类指针 编译都不能通过。
 //例如:obj->SetFun(&CFunDrive::RealFun);
 obj = new CFunDrive();
 obj->SetFun(&CFunBase::RealFun); //这里虽然传入的是CFunBase::RealFun而实际调用的是CFunDrive::RealFun
 nres = (obj->*(obj->m_pFun))(5); 
 nres = (obj->*(obj->GetFun()))(5);
 delete obj;
 obj = NULL; 
 //如果非要使用派生类的指针函数,需要强制转换
 obj = new CFunDrive();
 obj->SetFun(static_cast<CFunBase::FunType>(&CFunDrive::TestFun));
 nres = (obj->*(obj->m_pFun))(5); 
 nres = (obj->*(obj->GetFun()))(5);
 delete obj;
 obj = NULL; 
 getchar();
} 
/************************************************************************/
/* 模板类成员指针函数   与 委托                                                                  */
/************************************************************************/
//*
//保存函数指针和参数的辅助类
//目地是:用于参数个数和类型都不确定的函数指针
class SBaseDelegateHelper
{
public:
 virtual void Execute(){;}
 virtual void operator() ( ){;}
}; 
template<typename T>
class SDelegateHelper2 : public SBaseDelegateHelper
{
public:
 T* m_at;
 void (T::*m_pFun)(); 
 SDelegateHelper2(T* pThis,void (T::*pFun)())
 {
  m_at = pThis;
  m_pFun = pFun;
 } 
 virtual void operator() ( ) 
 {
  Execute();
 } 
 void Execute(){
  (m_at->*m_pFun)();
 }
}; 
template<typename T,typename P>
class SDelegateHelper : public SBaseDelegateHelper
{
public:
 T* m_at;
 P  m_aUserData;
 P (T::*m_pFun)(P); 
 SDelegateHelper(T* pThis,P (T::*pFun)(P),P aPrarm)
 {
  m_at = pThis;
  m_aUserData = aPrarm;
  m_pFun = pFun;
 }
 void Execute(){
  (m_at->*m_pFun)(m_aUserData);
 } 
 template<typename P>
 void Execute(P p){
  (m_at->*m_pFun)(p);
 } 
}; 

class CDelegate
{
public:
 template <typename T,typename P>
 void Excute(T * pObj, P (T::*pFun)(P) , P pParam){
  P t= pParam;
  t = (pObj->*pFun)(pParam); 
 } 
 template <typename T,typename P>
 void SetFun(T * pObj, P (T::*pFun)(P) ,P Param){
  m_pFun = new SDelegateHelper<T,P>(pObj,pFun,Param);
 } 
 template <typename T>
 void SetFun(T * pObj, void (T::*pFun)() ){
  m_pFun = new SDelegateHelper2<T>(pObj,pFun);
 } 
 SBaseDelegateHelper* m_pFun;
}; 
class CFunBase
{
public:
 virtual int  RealFun(int n){ return 0 ;}
 virtual void RealFun2() { ; }
}; 
class CFunDrive : public CFunBase
{
public:
 virtual int  RealFun( int n ) { return n*2 ;}
 virtual void RealFun2() { ; }
 int TestFun(int n) { return 100; }
}; 

template <typename T, typename P>
P gExcute(T * pObj,P (T::*pFun)(P) ,P aParam )
{
 return (pObj->*pFun)(aParam);
} 
int main(int argc, char* argv[])
{ 
 CFunBase* pObj = new CFunDrive();
 int n = gExcute(pObj,&CFunBase::RealFun,100); //多态,没问题 
 CDelegate aDelegete;
 aDelegete.Excute(pObj,&CFunBase::RealFun,100); 
 aDelegete.SetFun(pObj,&CFunBase::RealFun,100);
 aDelegete.m_pFun->Execute(); 

 CFunDrive* pTest = new CFunDrive();
 CDelegate aDelegete2;
 aDelegete2.SetFun(pTest,&CFunDrive::RealFun2);
 aDelegete2.m_pFun->Execute(); 

 getchar();
 return 0;
} 
//*/

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值