Click here to Skip to main content
Click here to Skip to main content
Go to top

Delegates in a standard C++ way

, 26 Jan 2002
Rate this:
Please Sign up or sign in to vote.
A method to duplicate .NET delegates in unmanaged C++ using the External polymorphism pattern.
<!-- Add the rest of your HTML here -->

Introduction

Microsoft introduced a new feature called Delegates in the .NET framework. These are actually a class which holds a list of function pointers. As long as they have the same function signature, the delegate object can hold static, global or member function pointer. Now I'm going to do the same in an 'unmanaged C++' way by using the External polymorphism pattern.

  1. Construct the abstract delegate base class
     //Delegate.h
    
    class Delegate {public:
        virtual void Invoke()=0;
    protected:
        Delegate(){}
        virtual ~Delegate(){}
    };
  2. Construct a derived class which accepts a static/global function pointer
    //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. Construct another derived class which accepts a member function pointer
    //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. Now glue up everything
    #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. And the output is
    NonTypeDelegate Invoke
    Test Invoked
    TypeDelegate Invoke
    A::Test Invoked

Final Note

You can also derive a class which can accept different signature of functions pointer thanks to the powerful External polymorphism pattern.

References

Chris Cleeland, Douglas C.Schmidt and Timothy H.Harrison External Polymorphism : An Object Structural Pattern for Transparently Extending C++ Concrete Data Types

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ben Chan

Hong Kong Hong Kong
No Biography provided

Comments and Discussions

 
GeneralTake a look at sigslot PinmemberChryler24-Feb-03 8:01 
GeneralRe: Take a look at sigslot PinmemberKlaus Nowikow19-Mar-03 2:08 
QuestionWorth it? Pinmemberswinefeaster30-Jan-02 0:54 
AnswerWorth it? Never PinmemberTW23-May-03 0:10 
GeneralRe: Worth it? Never PinmemberYuetKent24-Aug-04 22:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 27 Jan 2002
Article Copyright 2002 by Ben Chan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid