理解C++实现委托原理

上一篇 / 下一篇  2010-11-11 21:24:17 / 个人分类:VC++

在C#中有事件委托的概念,  我们可以方便的将一个类中的事件传递到另一个事件处理类中, 其实现的耦合性很底, 两个类之间不需要实例关联,  但在C++中并没有这种内置的功能,  其实仔细想想, C#的这种事件委托机制是可以用C++的成员函数指针来实现的, 只需要加上一个中间类即可,  网上有个FastDelegate的开源库就实现了这种委托机制, 有需要用到C++委托的朋友可以上网找找这个库.  我们这里只是简单介绍下C++实现委托机制的原理, 也是参照了FastDelegate库.

      前面说过, 要实现C++委托, 需要一个中间类, 这个中间类是用来保存函数指针和例实例的, 因为要实现通用性, 所以我们还需要用到C++模板技术, 定义的类如下:

view plaincopy to clipboardprint?
template<typename Y, typename X, typename R>  
class FastDelegate  
{  
public:  
    FastDelegate(Y* y, R (X::*Fun)())  
    {  
        m_pPointer = y;  
        m_fun = Fun;  
    }  
 
    R operator()()  
    {  
        return (m_pPointer->*m_fun)();  
    }  
 
    void CallMemerPointer()  
    {  
        (m_pPointer->*m_fun)();  
    }  
protected:  
private:  
    Y*      m_pPointer;  
    typedef R (X::*Fun)();  
    Fun     m_fun;  
}; 
template<typename Y, typename X, typename R>
class FastDelegate
{
public:
 FastDelegate(Y* y, R (X::*Fun)())
 {
  m_pPointer = y;
  m_fun = Fun;
 }

 R operator()()
 {
  return (m_pPointer->*m_fun)();
 }

 void CallMemerPointer()
 {
  (m_pPointer->*m_fun)();
 }
protected:
private:
 Y*  m_pPointer;
 typedef R (X::*Fun)();
 Fun  m_fun;
};

     在这个中间类里, 我们重载了()操作符来调用成员函数指针,  然后我们还需要一个函数来创建中间类:

view plaincopy to clipboardprint?
template <class X, class Y, class RetType>  
FastDelegate<Y, X, RetType >  
bind(  
     RetType (X::*func)(  ),  
     Y * y,  
     ...)  
{   
    return FastDelegate<Y,X, RetType>(y, func);  

template <class X, class Y, class RetType>
FastDelegate<Y, X, RetType >
bind(
  RetType (X::*func)(  ),
  Y * y,
  ...)
{
 return FastDelegate<Y,X, RetType>(y, func);
}

     现在主要的代码就完成了, 接下来我们看看调用方式:

view plaincopy to clipboardprint?
class FuncPointer  
{  
public:  
    void TestFunc1()  
    {  
        printf("call TestFunc1\r\n");  
 
        m_Fun = FuncPointer::TestFunc2;  
        (this->*m_Fun)();  
    }  
 
    void TestFunc2()  
    {  
        printf("call TestFunc2:\r\n");  
    }  
 
    static void TestFunc3()  
    {  
        printf("call TestFunc3:\r\n");  
    }  
};  
 
int _tmain(int argc, _TCHAR* argv[])  
{  
    FuncPointer* fp = new FuncPointer();  
    bind(&FuncPointer::TestFunc2, fp)();  
 
    return 0;  

class FuncPointer
{
public:
 void TestFunc1()
 {
  printf("call TestFunc1\r\n");

  m_Fun = FuncPointer::TestFunc2;
  (this->*m_Fun)();
 }

 void TestFunc2()
 {
  printf("call TestFunc2:\r\n");
 }

 static void TestFunc3()
 {
  printf("call TestFunc3:\r\n");
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 FuncPointer* fp = new FuncPointer();
 bind(&FuncPointer::TestFunc2, fp)();

 return 0;
}
 

      可以看出, 调用方式是非常简单的,  另外, 对于带参数的成员函数, 原理也是一样的, 具体的可参照FastDelegate自己实现



TAG:

 

评分:0

我来说两句

日历

« 2024-05-11  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 86915
  • 日志数: 218
  • 书签数: 1
  • 建立时间: 2010-11-06
  • 更新时间: 2011-03-21

RSS订阅

Open Toolbar