- 浏览: 76694 次
- 性别:
- 来自: 上海
文章分类
#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
发表评论
-
pthread_rwlock_t 未定义的问题
2016-08-06 15:02 1364最近在linux上次编译时出现pthread_rwlock ... -
二级指针 const 参数
2013-01-11 22:33 1981http://www.parashift.com/c++-fa ... -
tricks
2012-12-31 14:21 715#include <typeinfo> #inc ... -
多输出带前缀输出流
2012-10-29 11:37 945http://stackoverflow.com/questi ... -
inherit the ostream
2012-10-26 16:02 801class cdebug_stream :public ost ... -
模板参数 函数指针
2011-12-22 13:12 2329http://stackoverflow.com/questi ... -
event
2011-08-19 14:42 736#ifndef ODBCLIB_CORE_EVENT_EVEN ... -
Nullable (bug)
2011-06-26 23:45 894#ifndef NULLABLE_H #define ... -
C++ 接异常时的注意
2011-06-24 23:55 807void test1() { try { ... -
类成员函数模板特化 默认参数
2011-06-19 11:23 2424#ifndef MEMORYBLOCK_H #defi ... -
关于抛出异常和清栈
2011-06-18 22:10 1114构造函数中异常: 1.在无继承关系的前提下,构造函数中 ... -
类成员函数模板特化
2011-06-12 20:20 2807//header file namespace odb ...
相关推荐
网上有很多关于C++ delegate机制的文章,但都讲的是函数指针的内容,上周就C++中实现C#的delegate机制的问题研究了好几天,查看了很多相关资料,才解决了问题,现将我写的C++ delegate测试程序贴出来,希望能帮到有...
用C++做项目的时候,尤其是写客户端的时候经常会有事件回调的设计,一般的方式是使用虚函数表,用一个虚基类包含...但这种方式和C++11的lamda不兼容,为了更方便的实现事件回调机制,使用delegate是很不错的一种方式。
C++下实现委托的代码,利用了些编程技巧和大家分享~~
NULL 博文链接:https://cooker.iteye.com/blog/1176141
c++ 实现枚举USB设备接口 涉及函数: SetupDiGetClassDevs SetupDiEnumDeviceInterfaces SetupDiGetDeviceInterfaceDetail
关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名方法、lambda表达式。 现在我就从一个最简单最实用的一个小例子出发分析一下Delegate的使用。 现在有两个窗体...
qml中TreeView自定义数据类型,使在代理(Delegate)中能传递到更多的数据 具体可以访问博客https://www.jianshu.com/p/dc24d010e5e4
简单委托C++11 实验使用可变模板创建一个简单的委托风格的类在公共领域许可下获得许可
delegate 与指针的使用,dll处理数据,调用C#代理函数。
用Delegate的原因 Qt中当用到QTreeView和QTableView等用于显示item的视图时,你要编辑一个item用到的编辑工具可能是除了默认文字编辑lineEdit以外的工具,例如button,spinBox,甚至Slider,ProgressBar,也有可能是...
MyGUI库中的Delegate代码,可以包含进自己项目中使用
MyGUI的Delegate实现代码,里面的sample.cpp为使用范例。将压缩包里面的delegate.h和delegate_imp.h包含进自己项目中即可使用
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...
.Net中的委托从功能上讲和c语言或者c++中的方法指针类似,可以像调用方法一样调用委托完成某个功能,或返回某类结果。但是.Net毕竟是更高级的语言,委托Delegate也更高级了,委托是一种数据接口,它包含调用目标和...
在c#中,event与delegate是两个非常重要的概念。因为在Windows应用程序中,对事件的使用非常频繁,而事件的实现依赖于delegate。 下面是对网上一些比较好的关于delegage的资料的整理,以及自己的一些想法。 Delegate...
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...
这是我在VC++日常开发中收集的一些经常用到的类库,每一款都可以轻松重用,这些类库适用于vs2003及以上的开发环境,其中 Thread 和 Delegate 是从C#中得到的灵感,还有一些是在使用开源代码或其它语言时得到的启发和...
在这篇文章中,我想提出一个简单的 C++ 委派的实现,是用 C++ 成员函数指针和 C++11 的可变模板(variadic templates),目前这套实现方法仅支持 GNU C++ 4.7.0,在 Windows 下可使用 MinGW。 背景 在我的方法中奖提供...
使用委托的异步调用 Winform应用程序 委托.BeginInvoke 将当前线程的消息转入后台线程 Form.BeginInvoke 可以将其他线程的消息转入界面线程
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.