以标准 C++ 方式实现委托






3.57/5 (8投票s)
2002年1月27日

67575
一种在非托管 C++ 中使用外部多态模式复制 .NET 委托的方法。
引言
微软在 .NET 框架中引入了一个名为 Delegates 的新特性。实际上,它们是一个类,其中包含函数指针列表。只要它们具有相同的函数签名,委托对象就可以保存静态、全局或成员函数指针。现在我将使用外部多态模式以“非托管 C++”的方式执行相同的操作。
- 构造抽象委托基类
//Delegate.h class Delegate {public: virtual void Invoke()=0; protected: Delegate(){} virtual ~Delegate(){} };
- 构造一个派生类,该类接受静态/全局函数指针
//NonTypeDelegate.h #include "Delegate.h" class NonTypeDelegate : public Delegate { public: void Invoke(); NonTypeDelegate(void (*pfn)(int),int iParam); virtual ~NonTypeDelegate(){} private: void (*m_pfn)(int); int m_iParam; }; //NonTypeDelegate.cpp #include "NonTypeDelegate.h" #include <iostream> using namespace std; NonTypeDelegate::NonTypeDelegate(void (*pfn)(int),int iParam) :m_pfn(pfn) ,m_iParam(iParam) { } void NonTypeDelegate::Invoke() { cout << "NonTypeDelegate Invoke\r\n"; m_pfn(m_iParam); }
- 构造另一个派生类,该类接受成员函数指针
//TypeDelegate.hpp #include "Delegate.h" #include <iostream> using namespace std; template <typename T> class TypeDelegate : public Delegate { public: void Invoke(); TypeDelegate(T &t,void (T::*pfn)(int),int iParam); ~TypeDelegate(){} private: T m_t; void (T::*m_pfn)(int); int m_iParam; }; template<typename T> TypeDelegate<T>::TypeDelegate(T &t,void (T::*pfn)(int),int iParam) :m_t(t) ,m_pfn(pfn) ,m_iParam(iParam) { } template<typename T> void TypeDelegate<T>::Invoke() { cout << "TypeDelegate Invoke\r\n"; (m_t.*m_pfn)(m_iParam); }
- 现在将所有内容粘合在一起
#include <iostream> #include "NonTypeDelegate.h" #include "TypeDelegate.hpp" #include <vector> using namespace std; void Test(int iParam) { cout << "Test Invoked\r\n"; } class A { public: void Test(int iParam) { cout << "A::Test Invoked\r\n"; } }; int main(int argc, char* argv[]) { NonTypeDelegate nTDelegate(Test,1); A a; TypeDelegate<A> tDelegate(a,A::Test,2); vector<Delegate*> vecpDelegate; vecpDelegate.push_back(&nTDelegate); vecpDelegate.push_back(&tDelegate); for (vector<Delegate*>::const_iterator kItr=vecpDelegate.begin(); kItr!=vecpDelegate.end(); ++kItr) { (*kItr)->Invoke(); } return 0; }
- 输出是:
NonTypeDelegate Invoke Test Invoked TypeDelegate Invoke A::Test Invoked
最后说明
由于强大的外部多态模式,您还可以派生一个可以接受不同函数指针签名的类。
参考文献
Chris Cleeland, Douglas C.Schmidt 和 Timothy H.Harrison 外部多态:一种用于透明扩展 C++ 具体数据类型的对象结构模式