在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自己实现