`
chenqi210
  • 浏览: 76694 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

c++ Delegate

    博客分类:
  • c++
 
阅读更多

#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

 

1
2
分享到:
评论

相关推荐

    C++中实现委托(delegate)

    网上有很多关于C++ delegate机制的文章,但都讲的是函数指针的内容,上周就C++中实现C#的delegate机制的问题研究了好几天,查看了很多相关资料,才解决了问题,现将我写的C++ delegate测试程序贴出来,希望能帮到有...

    C++实现delegate

    用C++做项目的时候,尤其是写客户端的时候经常会有事件回调的设计,一般的方式是使用虚函数表,用一个虚基类包含...但这种方式和C++11的lamda不兼容,为了更方便的实现事件回调机制,使用delegate是很不错的一种方式。

    C++下实现委托的代码

    C++下实现委托的代码,利用了些编程技巧和大家分享~~

    C++ 委托 fastdelegate使用,实现类函数回调绑定

    NULL 博文链接:https://cooker.iteye.com/blog/1176141

    枚举USB设备接口(C++源代码)

    c++ 实现枚举USB设备接口 涉及函数: SetupDiGetClassDevs SetupDiEnumDeviceInterfaces SetupDiGetDeviceInterfaceDetail

    C#使用委托(delegate)实现在两个form之间传递数据的方法

    关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名方法、lambda表达式。 现在我就从一个最简单最实用的一个小例子出发分析一下Delegate的使用。 现在有两个窗体...

    qml中TreeView自定义数据类型,使在代理(Delegate)中能传递到更多的数据

    qml中TreeView自定义数据类型,使在代理(Delegate)中能传递到更多的数据 具体可以访问博客https://www.jianshu.com/p/dc24d010e5e4

    Simple-Delegate:C++11 实验使用可变模板创建一个简单的委托风格的类

    简单委托C++11 实验使用可变模板创建一个简单的委托风格的类在公共领域许可下获得许可

    C#调用C++ Dll

    delegate 与指针的使用,dll处理数据,调用C#代理函数。

    ModelDelegate-master.zip

    用Delegate的原因 Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是...

    MyGUI的Delegate实现代码

    MyGUI库中的Delegate代码,可以包含进自己项目中使用

    C++的委托实现(MyGUI版本)

    MyGUI的Delegate实现代码,里面的sample.cpp为使用范例。将压缩包里面的delegate.h和delegate_imp.h包含进自己项目中即可使用

    C# 委托(Delegate)

    C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...

    解析.Net 4.0 中委托delegate的使用详解

    .Net中的委托从功能上讲和c语言或者c++中的方法指针类似,可以像调用方法一样调用委托完成某个功能,或返回某类结果。但是.Net毕竟是更高级的语言,委托Delegate也更高级了,委托是一种数据接口,它包含调用目标和...

    深入理解C#中的Delegate

    在c#中,event与delegate是两个非常重要的概念。因为在Windows应用程序中,对事件的使用非常频繁,而事件的实现依赖于delegate。 下面是对网上一些比较好的关于delegage的资料的整理,以及自己的一些想法。 Delegate...

    浅析C# 委托(Delegate)

    C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...

    搜集的一些C++可重用源代码

    这是我在VC++日常开发中收集的一些经常用到的类库,每一款都可以轻松重用,这些类库适用于vs2003及以上的开发环境,其中 Thread 和 Delegate 是从C#中得到的灵感,还有一些是在使用开源代码或其它语言时得到的启发和...

    C++中关于委派(Delegates)的实现示例

    在这篇文章中,我想提出一个简单的 C++ 委派的实现,是用 C++ 成员函数指针和 C++11 的可变模板(variadic templates),目前这套实现方法仅支持 GNU C++ 4.7.0,在 Windows 下可使用 MinGW。 背景 在我的方法中奖提供...

    委托的异步调用 beginInvoke

    使用委托的异步调用 Winform应用程序 委托.BeginInvoke 将当前线程的消息转入后台线程 Form.BeginInvoke 可以将其他线程的消息转入界面线程

    Wu Manber算法代码

    C++下多模匹配算法:Wu Manber的实现 ... It all needs to be redone a bit in order to accept a 'functor' or a 'delegate' so that when a match is found, an appropriate routine can be invoked.

Global site tag (gtag.js) - Google Analytics