65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.57/5 (8投票s)

2002年1月27日

viewsIcon

67575

一种在非托管 C++ 中使用外部多态模式复制 .NET 委托的方法。

引言

微软在 .NET 框架中引入了一个名为 Delegates 的新特性。实际上,它们是一个类,其中包含函数指针列表。只要它们具有相同的函数签名,委托对象就可以保存静态、全局或成员函数指针。现在我将使用外部多态模式以“非托管 C++”的方式执行相同的操作。

  1. 构造抽象委托基类
     //Delegate.h
    
    class Delegate {public:
        virtual void Invoke()=0;
    protected:
        Delegate(){}
        virtual ~Delegate(){}
    };
  2. 构造一个派生类,该类接受静态/全局函数指针
    //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);
    }
  3. 构造另一个派生类,该类接受成员函数指针
    //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);
    }
  4. 现在将所有内容粘合在一起
    #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;
    }
     
  5. 输出是:
    NonTypeDelegate Invoke
    Test Invoked
    TypeDelegate Invoke
    A::Test Invoked

最后说明

由于强大的外部多态模式,您还可以派生一个可以接受不同函数指针签名的类。

参考文献

Chris Cleeland, Douglas C.Schmidt 和 Timothy H.Harrison 外部多态:一种用于透明扩展 C++ 具体数据类型的对象结构模式

© . All rights reserved.