c++ Delegate

#ifndef DUMMYCLASS_H
#define DUMMYCLASS_H

namespace delegate
{
	class DummyClass{};
}

#endif
 

#ifndef METHODSTORAGE_H
#define METHODSTORAGE_H

#include "DummyClass.h"

namespace delegate
{
	class MethodStorage
	{
	public:
		typedef DummyClass GenericClass;
		typedef void (GenericClass::*GenericMemberFunctionPtr)();
		typedef void (*GenericFunctionPtr)();

		MethodStorage()
			:m_obj(0),
			m_member_fnptr(0),
			m_fnptr(0)
		{
		
		}

		inline bool operator == (MethodStorage const& other) const{return this->equals(other);}
		inline bool operator != (MethodStorage const& other) const{return !this->equals(other);}

		inline bool equals(MethodStorage const& other) const
		{
			return m_obj == other.m_obj 
				&& m_member_fnptr == other.m_member_fnptr
				&& m_fnptr == other.m_fnptr;
		}

	//protected:
		GenericClass *m_obj;
		GenericMemberFunctionPtr m_member_fnptr;
		GenericFunctionPtr m_fnptr;
	};
};

#endif
 

#ifndef METHODWRAPPER_H
#define METHODWRAPPER_H

#include "MethodStorage.h"

namespace delegate
{
	///This "Signature" is not a complete function pointer
	///corresponding signature to void (*)(int) is void(int)
	///and void (SomeClassType::*)(int) is void(int) as well
	template<typename Signature>
	class MethodWrapper;

	template<>
	class MethodWrapper< void () >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(void) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
		}

		MethodWrapper(void (*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)() >;
		}

		void operator()()
		{
			(this->*internal_call)(m_method.m_obj);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void*);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		void executeMemberFunction(void* obj)
		{
			(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
		}

		template<typename ClassType,typename FunctionPtrType>
		void executeFunction(void* obj)
		{
			(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
		}
	};
	template<typename ReturnType> 
	class MethodWrapper< ReturnType () >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(void) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
		}

		MethodWrapper(ReturnType (*ptr)(void))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , ReturnType (*)() >;
		}

		ReturnType operator()()
		{
			return (this->*internal_call)(m_method.m_obj);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeMemberFunction(void* obj)
		{
			return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
		}

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeFunction(void* obj)
		{
			return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
		}
	};
	template<typename ArgType0> 
	class MethodWrapper< void ( ArgType0 ) >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		MethodWrapper(void (*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
		}

		void operator()(ArgType0 arg0)
		{
			(this->*internal_call)(m_method.m_obj, arg0);
		}
	private:
		typedef void (MethodWrapper::*internal_call_type)(void*,ArgType0);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		void executeMemberFunction(void* obj,ArgType0 arg0)
		{
			(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
		}

		template<typename ClassType,typename FunctionPtrType>
		void executeFunction(void* obj,ArgType0 arg0)
		{
			(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
		}
	};
	template<typename ReturnType,typename ArgType0> 
	class MethodWrapper< ReturnType ( ArgType0 ) >
	{
	public:
		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0) const)
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0)const )
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		template<typename ClassType,typename MemberFunctionClass>
		MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
		}

		MethodWrapper(ReturnType (*ptr)(ArgType0))
		{
			m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
			m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
			internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
		}

		ReturnType operator()(ArgType0 arg0)
		{
			return (this->*internal_call)(m_method.m_obj,arg0);
		}
	private:
		typedef ReturnType (MethodWrapper::*internal_call_type)(void*,ArgType0);
		MethodStorage m_method;

		internal_call_type internal_call;

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeMemberFunction(void* obj,ArgType0 arg0)
		{
			return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
		}

		template<typename ClassType,typename FunctionPtrType>
		ReturnType executeFunction(void* obj,ArgType0 arg0)
		{
			return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
		}
	};
}

#endif
 

 

 

compiler:MinGW 4.5.2 / VC++2010

 

 

C#式的delegate的重点之一是省略掉类型信息.

http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx 写道
class delegate
{
public:
    delegate()
        : object_ptr(0)
        , stub_ptr(0)
    {}

    template <class T, void (T::*TMethod)(int)>
    static delegate from_method(T* object_ptr)
    {
        delegate d;
        d.object_ptr = object_ptr;
        d.stub_ptr = &method_stub<T, TMethod>; // #1

        return d;
    }

    void operator()(int a1) const
    {
        return (*stub_ptr)(object_ptr, a1);
    }

private:
    typedef void (*stub_type)(void* object_ptr, int);

    void* object_ptr;
    stub_type stub_ptr;

    template <class T, void (T::*TMethod)(int)>
    static void method_stub(void* object_ptr, int a1)
    {
        T* p = static_cast<T*>(object_ptr);
        return (p->*TMethod)(a1); // #2

    }
};
 

 非常巧妙地隐藏掉了类型信息。但是本人对虚继承的委托还没有好的解决方法,也理解不了虚继承的成员函数的hack:http://www.codeproject.com/KB/cpp/FastDelegate.aspx

 

你可能感兴趣的:(delegate)