首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

一个CallBack函数模板解决方法

2012-03-09 
一个CallBack函数模板工作中经常需要调用一些老的库函数,这些库函数又常常需要提供某种回调函数(callback)

一个CallBack函数模板
工作中经常需要调用一些老的库函数,   这些库函数又常常需要提供某种
回调函数(callback).比如在oldlib.h中定义了如下的函数:

            //oldlib.h
            typedef   double   (*Func)   (double);
            double   _mean_value(double   x0,   double   x1,   Func   f);
           
在使用_mean_value时,   我们需要提供一个Func型的回调函数。
 
现在假设我们开发了某个类SomeEngine
 
            class   SomeEngine
            {
            public:
                    ...........
                    double   EngineFunction(double   x)  
                    {
                            return   x+mX;                                                        
                    };
                    double   UseMeanValue()
                    {
                            return   _mean_value(0,   1,   EngineFunction);   //(1)
                    }
                private:                
                        double   mX;
            };
           
我们希望在语句(1)中调用_mean_value时传递一个成员函数作为回调函数。然而  
不幸的是(1)不能通过编译。虽然EngineFunction看起来与Func具有相同的参数
和返回值,   然而实际上它们是不同的函数类型,   EngineFunction隐含了一个this指针。
   
现在我们来考虑如何饶过这个this指针问题。我们知道类的静态成员是不含this指针
的。好象我们可以这样写:
   
            class   SomeEngine
            {
            public:
                    ...........
                    static   double   sEngineFunction(double   x)
                    {
                            return   EngineFunction(x);                                                         //(2)
                    }
                   
                    double   EngineFunction(double   x)
                    {
                              return   x+mX;


                    }
                   
                    double   UseMeanValue()
                    {
                            return   _mean_value(0,   1,   sEngineFunction);  
                    }
            private:                
                    double   mX;
            };
           
现在(2)不能通过编译了,   因为静态成员函数不能访问非静态成员函数。如果我们能在(2)中获得this指针就好了,   这样   return   this-> EngineFunction(x)就没问题了。但是   静态成员函数不含this指针呀。(这个this真是麻烦:()。  
       
办法总是有的,   现在我们给SomeEngine添加一个静态的指向自己的指针mspTHIS:
                 
            class   SomeEngine
            {
            public:
                    ...........
                    static   double   sEngineFunction(double   x)
                    {
                        return   mspTHIS-> EngineFunction(x);                                                        
                    }
                   
                    double   EngineFunction(double   x)
                    {
                              return   x+mX;
                    }
                   
                    double   UseMeanValue()
                    {
                            mspTHIS   =   this;
                            return   _mean_value(0,   1,   sEngineFunction);  
                            mspTHIS   =   NULL;
                    }
            private:                
                        double   mX;
                        static   SomeEngine*   mspTHIS;


            };
                       
            SomeEngine*   SomeEngine::mspTHIS   =   NULL;
           
好了,   现在编译没有问题了,   程序也能够达到我们最初的目标。   不过回头看看,
仅仅为了传一个成员函数,   我们对SomeEngine的改动也太多了点(一个静态成员函数,   一个静态指针)。如果有另一个类也需要使用调用_mean_value(),   我们又得费一翻工夫,   重复劳动了。
           
  这回我们要动用模板了。   下面给一个模板类,   来达到同样的目的,   具体细节就
  不解释了.
           
//================================================================
//   CLASS  
//CallBackFunction <T,   RT,   PT>
//   DESCRIPTION
//This   template   class   is   used   as   a   convient   wrapper  
//     for   passing   a   non-static   member   function   to   an   old   C   routine  
//   which   requires   a   callback   function.
//     =============================================================
template  
<  
  typename   T,            
  typename   ReturnT,        
  typename   ParamT  
>
class   CallBackFunction
{
public:
      typedef   ReturnT   (T::*MemberCallBackFunction)(ParamT);
      typedef   ReturnT   (*CallBackFunc)   (ParamT);

      CallBackFunction(T*   pT,   MemberCallBackFunction   memberCallBack)
      {
            mspT   =   pT;
            mMemberCallBack   =   memberCallBack;
      }

      ~CallBackFunction()
      {
            mspT   =   NULL;
            mspTHIS   =   NULL;
      }

    operator   CallBackFunc()  
    {
          mspTHIS   =   this;
          return   CallBack;
    }

private:
    static   ReturnT   CallBack(ParamT   x)  
    {
          return   (mspT-> *(mspTHIS-> mMemberCallBack))(x);
    }

    MemberCallBackFunction   mMemberCallBack;
    static   T*   mspT;
    static   CallBackFunction*   mspTHIS;

//   no   implementations
    CallBackFunction();          
    CallBackFunction(const   CallBackFunction&   rhs);
    CallBackFunction <T,   ReturnT,   ParamT> &   operator=(CallBackFunction <T,       ReturnT,   ParamT> &   rhs);    
};

template <typename   T,   typename   ReturnT,   typename   ParamT>
T*   CallBackFunction <T,   ReturnT,   ParamT> ::mspT   =   NULL;

template <typename   T,   typename   ReturnT,   typename   ParamT>
CallBackFunction <T,   ReturnT,   ParamT> *   CallBackFunction <T,   ReturnT,   ParamT> ::mspTHIS=NULL;



现在回到SomeEngine类,   看看如何使用上面的CallBackFunction <> 。  

            class   SomeEngine
            {
            public:
                    ...........
                    double   EngineFunction(double   x)  
                    {
                            return   x+mX;                                                        
                    };
                    double   UseMeanValue()
                    {
                            CallBackFunction <SomeEngine,   double,   double>   engineFunction(this,   &SomeEngine::EngineFunction);
                            return   _mean_value(0,   1,   engineFunction);  
                    }
                private:                
                        double   mX;
            };  
           
  与最初的的SomeEngine比,   我们只添加了一行代码。这就是变化:
            return   _mean_value(0,   1,   EngineFunction)
            ======>
            CallBackFunction <SomeEngine,   double,   double>   engineFunction(this,   &SomeEngine::EngineFunction);
            return   _mean_value(0,   1,   engineFunction);    
没有static函数,   没有static指针,   世界清净了;   可以在任何类中使用,   可以偷懒了:))      
 
  ///ps.
  如果你使用了上述模板:
        1。   如果你的机器爆了,   请你不要投诉我
        2。   如果你中了500万大彩,   请给CSDN捐250万
:))))))))
       


[解决办法]
这个模板要想真有实用价值,代码量就是boost function库的大小,文件加起来一共62K,还不算调的boost库其它组件的大小。
[解决办法]
没没看完...
[解决办法]

[解决办法]
mark.
[解决办法]
好麻烦啊
[解决办法]
MARK!

热点排行