
在C++中实现delegate
发布日期:2021-05-09 04:09:36
浏览次数:19
分类:博客文章
本文共 19134 字,大约阅读时间需要 63 分钟。
delegate.h #ifndef WAN_DELEGATE_H#define WAN_DELEGATE_H /** * @author Kevin Wan <> * @date 06/30/2005 * Copyright (C) Kevin Wan */#include"threadingmodel.h" namespace wan{namespacelocal{template <typename> class ICallback;template<typename> class NativeCallback;template <typename, typename>class MemberCallback;} // namespace local
template <typename, typename LockType = void> class delegate;
#define DELEGATE_GENERATOR(TEMPLATE_LIST, TYPE_LIST, TYPE_PARAM_LIST,PARAM_LIST) \namespace local \{ \template <typename ReturnTypeTEMPLATE_LIST> \class ICallback<ReturnType(TYPE_LIST)> \{\ typedef ICallback<ReturnType(TYPE_LIST)> SelfType;\\public: \ virtual ~ICallback() {} \\ virtualReturnType invoke(TYPE_LIST) const = 0; \ virtual bool equals(constSelfType* pDelegate) const = 0; \ virtual SelfType* clone() const = 0;\}; \\template <typename ReturnType TEMPLATE_LIST> \classNativeCallback<ReturnType(TYPE_LIST)> \ : publicICallback<ReturnType(TYPE_LIST)> \{ \ typedefICallback<ReturnType(TYPE_LIST)> SuperType; \ typedefNativeCallback<ReturnType(TYPE_LIST)> SelfType; \ typedefReturnType (*FunctionPtr)(TYPE_LIST); \\public: \ explicitNativeCallback(FunctionPtr ptr) \ : m_handler(ptr) \ {\ } \\ NativeCallback(const SelfType& rhs) \ :ICallback<ReturnType(TYPE_LIST)>(rhs) \ ,m_handler(rhs.m_handler) \ { \ } \\ ReturnTypeinvoke(TYPE_PARAM_LIST) const \ { \ return(*m_handler)(PARAM_LIST); \ } \\ bool equals(const SuperType*pDelegate) const \ { \ const SelfType* pRhs =dynamic_cast<const SelfType*>(pDelegate); \ if (pRhs == 0)return false; \ if (m_handler == pRhs->m_handler) return true;\ return false; \ } \\ SelfType* clone() const\ { \ return new SelfType(*this); \ }\\private: \ FunctionPtr m_handler; \}; \\template<typename ObjectType, typename ReturnType TEMPLATE_LIST> \classMemberCallback<ObjectType, ReturnType(TYPE_LIST)> \ : publicICallback<ReturnType(TYPE_LIST)> \{ \ typedefICallback<ReturnType(TYPE_LIST)> SuperType; \ typedefMemberCallback<ObjectType, ReturnType(TYPE_LIST)> SelfType; \ typedef ReturnType (ObjectType::*FunctionPtr)(TYPE_LIST); \ typedefReturnType (ObjectType::*ConstFunctionPtr)(TYPE_LIST) const; \\ enum{ CONST_POINTER, NEED_DELETE, DONT_DELETE }; \ struct ObjectManager\ { \ bool equals(const ObjectManager& rhs) \ {\ return object.pObject == rhs.object.pObject; \ }\\ union { ObjectType* pObject; const ObjectType* pConstObject; }object; \ int property; \ int refCount; \ }; \\public: \ MemberCallback(ObjectType* t, FunctionPtr ptr, bool needDelete = false)\ : m_isConstMemFunc(false) \ { \ m_pObjectManager= new ObjectManager(); \ m_pObjectManager->object.pObject = t;\ m_pObjectManager->property = needDelete ? NEED_DELETE :DONT_DELETE; \ m_pObjectManager->refCount = 0; \ m_handler.ptr = ptr; \ incrementRefCount(); \ } \\ MemberCallback(ObjectType* t, ConstFunctionPtr ptr, bool needDelete = false)\ : m_isConstMemFunc(true) \ { \ m_pObjectManager =new ObjectManager(); \ m_pObjectManager->object.pObject = t;\ m_pObjectManager->property = needDelete ? NEED_DELETE :DONT_DELETE; \ m_pObjectManager->refCount = 0; \ m_handler.constPtr = ptr; \ incrementRefCount(); \ }\\ MemberCallback(const ObjectType* t, ConstFunctionPtr ptr)\ : m_isConstMemFunc(true) \ { \ m_pObjectManager =new ObjectManager(); \ m_pObjectManager->object.pConstObject = t;\ m_pObjectManager->property = CONST_POINTER; \ m_pObjectManager->refCount = 0; \ m_handler.constPtr = ptr;\ incrementRefCount(); \ } \\ MemberCallback(constSelfType& rhs) \ : ICallback<ReturnType(TYPE_LIST)>(rhs)\ , m_pObjectManager(rhs.m_pObjectManager) \ ,m_handler(rhs.m_handler) \ , m_isConstMemFunc(rhs.m_isConstMemFunc)\ { \ incrementRefCount(); \ } \\ virtual~MemberCallback() \ { \ decrementRefCount(); \ }\\ MemberCallback& operator=(const SelfType& rhs) \ {\ if (this == &rhs) \ return *this; \ decrementRefCount(); \ m_pObjectManager = rhs.m_pObjectManager;\ m_handler = rhs.m_handler; \ m_isConstMemFunc =rhs.m_isConstMemFunc; \ incrementRefCount(); \ return*this; \ } \\ ReturnType invoke(TYPE_PARAM_LIST) const\ { \ if (m_isConstMemFunc) \ { \ if(m_pObjectManager->property == CONST_POINTER) \ return(m_pObjectManager->object.pConstObject->*(m_handler.constPtr))(PARAM_LIST);\ return(m_pObjectManager->object.pObject->*(m_handler.constPtr))(PARAM_LIST);\ } \ return(m_pObjectManager->object.pObject->*(m_handler.ptr))(PARAM_LIST); \ } \\ bool equals(const SuperType* pDelegate) const \ {\ const SelfType* pRhs = dynamic_cast<constSelfType*>(pDelegate); \ if (pRhs == 0) return false; \ if (m_pObjectManager->equals(*pRhs->m_pObjectManager) \ && m_isConstMemFunc == pRhs->m_isConstMemFunc \ && m_handler.ptr == pRhs->m_handler.ptr) \ returntrue; \ return false; \ } \\ SelfType* clone()const \ { \ return new SelfType(*this); \ }\\private: \ void incrementRefCount() \ { \ ++m_pObjectManager->refCount; \ } \\ voiddecrementRefCount() \ { \ if (--m_pObjectManager->refCount== 0) \ { \ if (m_pObjectManager->property ==NEED_DELETE) \ delete m_pObjectManager->object.pObject;\\ delete m_pObjectManager; \ } \ }\\private: \ ObjectManager* m_pObjectManager; \ union {FunctionPtr ptr; ConstFunctionPtr constPtr; } m_handler; \ bool m_isConstMemFunc; \}; \} /* namespace local */\\template <typename ReturnType TEMPLATE_LIST, typename LockType>\class delegate<ReturnType(TYPE_LIST), LockType> \ : publiclocal::ICallback<ReturnType(TYPE_LIST)> \ , publicThreadingModel<LockType> \{ \ typedeflocal::ICallback<ReturnType(TYPE_LIST)> SuperType; \ typedefdelegate<ReturnType(TYPE_LIST), LockType> SelfType; \ typedefThreadingModel<LockType> ThreadingModelType; \ structCallbackHolder \ { \ SuperType* instance; \ CallbackHolder* prev; \ ReturnType call(TYPE_PARAM_LIST) \ { \ if (prev != 0) prev->call(PARAM_LIST); \ return instance->invoke(PARAM_LIST); \ } \ };\\public: \ delegate() : m_pHolder(0) {} \\ explicitdelegate(ReturnType (*ptr)(TYPE_LIST)) \ : m_pHolder(0) \ {\ this->add(ptr); \ } \\ template <typenameObjectType> \ delegate(const ObjectType* t,ReturnType(ObjectType::*ptr)(TYPE_LIST) const) \ : m_pHolder(0)\ { \ this->add(t, ptr); \ } \\ template<typename ObjectType> \ delegate(ObjectType* t,ReturnType(ObjectType::*ptr)(TYPE_LIST), \ bool needDelete =false) \ : m_pHolder(0) \ { \ this->add(t, ptr,needDelete); \ } \\ template <typename ObjectType>\ delegate(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST) const,\ bool needDelete = false) \ : m_pHolder(0) \ {\ this->add(t, ptr, needDelete); \ } \\ template<typename FunctorType> \ explicit delegate(const FunctorType*pFunctor) \ : m_pHolder(0) \ { \ this->add(pFunctor); \ } \\ template <typenameFunctorType> \ explicit delegate(FunctorType* pFunctor, boolneedDelete = false) \ : m_pHolder(0) \ { \ this->add(pFunctor, needDelete); \ } \\ delegate(constSelfType& rhs) \ :local::ICallback<ReturnType(TYPE_LIST)>(rhs) \ ,ThreadingModelType() \ { \ copyFrom(rhs); \ }\\ SelfType& operator=(const SelfType& rhs) \ {\ if (this == &rhs) \ return *this; \ this->release(); \ copyFrom(rhs); \ return *this;\ } \\ ~delegate() \ { \ release(); \ } \\ void release() \ { \ typenameThreadingModelType::Lock guard(*this); \ CallbackHolder* ptr =m_pHolder; \ while (ptr != 0) \ { \ CallbackHolder* prev = ptr->prev; \ delete ptr->instance;\ delete ptr; \ ptr = prev; \ }\ m_pHolder = 0; \ } \\ ReturnTypeoperator()(TYPE_PARAM_LIST) \ { \ returnthis->invoke(PARAM_LIST); \ } \\ ReturnTypeinvoke(TYPE_PARAM_LIST) const \ { \ typenameThreadingModelType::Lock guard(*this); \ if (m_pHolder == 0) returnReturnType(); \ return m_pHolder->call(PARAM_LIST); \ }\\ bool equals(const SuperType* pDelegate) const \ {\ const SelfType* pRhs = dynamic_cast<constSelfType*>(pDelegate); \ if (pRhs == 0) return false;\\ SelfType* temp = 0; \ const SelfType* pClone;\ cloneForComparison(pRhs, pClone, temp, typenameThreadingModelType::ThreadTag()); \\ typenameThreadingModelType::Lock guard(*this); \ CallbackHolder* ptr1 =m_pHolder; \ CallbackHolder* ptr2 = pClone->m_pHolder;\ while (ptr1 != 0 && ptr2 != 0) \ {\ if (!ptr1->instance->equals(ptr2->instance))\ break; \ ptr1 = ptr1->prev;\ ptr2 = ptr2->prev; \ } \ delete temp;\ return (ptr1 == 0 && ptr2 == 0); \ } \\ SelfType* clone() const \ { \ SelfType* pClone = newSelfType(); \ typename ThreadingModelType::Lock guard(*this);\ CallbackHolder* ptr = m_pHolder; \ CallbackHolder*pReverse = 0; \ while (ptr != 0) \ { \ CallbackHolder* pHolder = new CallbackHolder(); \ pHolder->instance = ptr->instance->clone(); \ pHolder->prev = pReverse; \ pReverse = pHolder;\ ptr = ptr->prev; \ } \\ CallbackHolder* prev = 0; \ while (pReverse != 0) \ {\ CallbackHolder* next = pReverse->prev; \ pReverse->prev = prev; \ prev = pReverse; \ pReverse = next; \ } \ pClone->m_pHolder = prev;\\ return pClone; \ } \\ void add(ReturnType(*ptr)(TYPE_LIST)) \ { \ SuperType* pNew = newlocal::NativeCallback<ReturnType(TYPE_LIST)>(ptr); \ this->addImpl(pNew); \ } \\ template <typenameObjectType> \ void add(const ObjectType* t,ReturnType(ObjectType::*ptr)(TYPE_LIST) const) \ { \ SuperType* pNew = new local::MemberCallback<ObjectType,ReturnType(TYPE_LIST)>(t, ptr); \ this->addImpl(pNew); \ } \\ template <typename ObjectType> \ voidadd(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST), bool needDelete =false) \ { \ SuperType* pNew = newlocal::MemberCallback<ObjectType, ReturnType(TYPE_LIST)>\ (t, ptr, needDelete); \ this->addImpl(pNew);\ } \\ template <typename ObjectType> \ voidadd(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST) const,\ bool needDelete = false) \ { \ SuperType*pNew = new local::MemberCallback<ObjectType, ReturnType(TYPE_LIST)>\ (t, ptr, needDelete); \ this->addImpl(pNew);\ } \\ template <typename FunctorType> \ voidadd(FunctorType* pFunctor, bool needDelete = false) \ { \ this->add(pFunctor, &FunctorType::operator(), needDelete); \ }\\ template <typename FunctorType> \ void add(constFunctorType* pFunctor) \ { \ this->add(pFunctor,&FunctorType::operator()); \ } \\ void add(constSelfType& rhs) \ { \ SelfType* pClone = rhs.clone();\ this->addImpl(pClone); \ } \\ voidremove(ReturnType (*ptr)(TYPE_LIST)) \ { \ SuperType* pNew =new local::NativeCallback<ReturnType(TYPE_LIST)>(ptr); \ this->removeImpl(pNew); \ } \\ template <typenameObjectType> \ void remove(const ObjectType* t,ReturnType(ObjectType::*ptr)(TYPE_LIST) const) \ { \ SuperType* pNew = new local::MemberCallback<ObjectType,ReturnType(TYPE_LIST)>(t, ptr); \ this->removeImpl(pNew);\ } \\ template <typename ObjectType> \ voidremove(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST), bool needDelete =false) \ { \ SuperType* pNew = newlocal::MemberCallback<ObjectType, ReturnType(TYPE_LIST)> \ (t, ptr, needDelete); \ this->removeImpl(pNew); \ }\\ template <typename ObjectType> \ voidremove(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST) const,\ bool needDelete = false) \ { \ SuperType*pNew = new local::MemberCallback<ObjectType, ReturnType(TYPE_LIST)>\ (t, ptr, needDelete); \ this->removeImpl(pNew);\ } \\ template <typename FunctorType> \ voidremove(FunctorType* pFunctor, bool needDelete = false) \ { \ this->remove(pFunctor, &FunctorType::operator(), needDelete); \ }\\ template <typename FunctorType> \ void remove(constFunctorType* pFunctor) \ { \ this->remove(pFunctor,&FunctorType::operator()); \ } \\ void remove(constSelfType& rhs) \ { \ this->remove(rhs, typenameThreadingModelType::ThreadTag()); \ } \\private: \ voidcloneForComparison(const SelfType* pRhs, const SelfType*& pClone,\ SelfType*& ptrForDelete, SingleThreadTag) const \ {\ pClone = pRhs; \ ptrForDelete = 0; \ }\\ void cloneForComparison(const SelfType* pRhs, const SelfType*&pClone, \ SelfType*& ptrForDelete, MultiThreadTag) const\ { \ ptrForDelete = pRhs->clone(); \ pClone = ptrForDelete; \ } \\ void copyFrom(constSelfType& rhs) \ { \ SelfType* pClone = rhs.clone();\ m_pHolder = pClone->m_pHolder; \ pClone->m_pHolder= 0; \ delete pClone; \ } \\ void remove(constSelfType& rhs, SingleThreadTag) \ { \ this->removeImpl(&rhs); \ } \\ void remove(constSelfType& rhs, MultiThreadTag) \ { \ this->removeImpl(rhs.clone()); \ } \\ voidaddImpl(SuperType* pRhs) \ { \ typenameThreadingModelType::Lock guard(*this); \ CallbackHolder* pH = newCallbackHolder(); \ pH->instance = pRhs; \ pH->prev= m_pHolder; \ m_pHolder = pH; \ } \\ voidremoveImpl(const SuperType* pRhs) \ { \ typenameThreadingModelType::Lock guard(*this); \ CallbackHolder* ptr =m_pHolder; \ CallbackHolder* prev = 0; \ while (ptr != 0)\ { \ if (ptr->instance->equals(pRhs))\ { \ if (prev == 0) m_pHolder = ptr->prev;\ else prev->prev = ptr->prev; \ delete ptr->instance; \ delete ptr; \ break; \ } \ prev = ptr; \ ptr =ptr->prev; \ } \ } \\ void removeImpl(SuperType*pRhs) \ { \ const SuperType* pConst = pRhs; \ this->removeImpl(pConst); \ delete pRhs; \ }\\private: \ CallbackHolder* m_pHolder; \};
#define TEMPLATE_LIST_0#define TEMPLATE_LIST_1 TEMPLATE_LIST_0,typename T0#define TEMPLATE_LIST_2 TEMPLATE_LIST_1, typename T1#defineTEMPLATE_LIST_3 TEMPLATE_LIST_2, typename T2#define TEMPLATE_LIST_4TEMPLATE_LIST_3, typename T3#define TEMPLATE_LIST_5 TEMPLATE_LIST_4,typename T4#define TEMPLATE_LIST_6 TEMPLATE_LIST_5, typename T5
#define TYPE_LIST_0#define TYPE_LIST_1 T0#define TYPE_LIST_2TYPE_LIST_1, T1#define TYPE_LIST_3 TYPE_LIST_2, T2#define TYPE_LIST_4TYPE_LIST_3, T3#define TYPE_LIST_5 TYPE_LIST_4, T4#define TYPE_LIST_6TYPE_LIST_5, T5
#define TYPE_PARAM_LIST_0#define TYPE_PARAM_LIST_1 T0 t0#defineTYPE_PARAM_LIST_2 TYPE_PARAM_LIST_1, T1 t1#define TYPE_PARAM_LIST_3TYPE_PARAM_LIST_2, T2 t2#define TYPE_PARAM_LIST_4 TYPE_PARAM_LIST_3, T3t3#define TYPE_PARAM_LIST_5 TYPE_PARAM_LIST_4, T4 t4#defineTYPE_PARAM_LIST_6 TYPE_PARAM_LIST_5, T5 t5
#define PARAM_LIST_0#define PARAM_LIST_1 t0#define PARAM_LIST_2PARAM_LIST_1, t1#define PARAM_LIST_3 PARAM_LIST_2, t2#definePARAM_LIST_4 PARAM_LIST_3, t3#define PARAM_LIST_5 PARAM_LIST_4,t4#define PARAM_LIST_6 PARAM_LIST_5, t5
DELEGATE_GENERATOR(TEMPLATE_LIST_0, TYPE_LIST_0, TYPE_PARAM_LIST_0,PARAM_LIST_0)DELEGATE_GENERATOR(TEMPLATE_LIST_1, TYPE_LIST_1,TYPE_PARAM_LIST_1, PARAM_LIST_1)DELEGATE_GENERATOR(TEMPLATE_LIST_2,TYPE_LIST_2, TYPE_PARAM_LIST_2,PARAM_LIST_2)DELEGATE_GENERATOR(TEMPLATE_LIST_3, TYPE_LIST_3,TYPE_PARAM_LIST_3, PARAM_LIST_3)DELEGATE_GENERATOR(TEMPLATE_LIST_4,TYPE_LIST_4, TYPE_PARAM_LIST_4,PARAM_LIST_4)DELEGATE_GENERATOR(TEMPLATE_LIST_5, TYPE_LIST_5,TYPE_PARAM_LIST_5, PARAM_LIST_5)DELEGATE_GENERATOR(TEMPLATE_LIST_6,TYPE_LIST_6, TYPE_PARAM_LIST_6, PARAM_LIST_6)
// remove the macros#undef DELEGATE_GENERATOR #undefTEMPLATE_LIST_0#undef TEMPLATE_LIST_1#undef TEMPLATE_LIST_2#undefTEMPLATE_LIST_3#undef TEMPLATE_LIST_4#undef TEMPLATE_LIST_5#undefTEMPLATE_LIST_6
#undef TYPE_LIST_0#undef TYPE_LIST_1#undef TYPE_LIST_2#undefTYPE_LIST_3#undef TYPE_LIST_4#undef TYPE_LIST_5#undefTYPE_LIST_6
#undef TYPE_PARAM_LIST_0#undef TYPE_PARAM_LIST_1#undefTYPE_PARAM_LIST_2#undef TYPE_PARAM_LIST_3#undefTYPE_PARAM_LIST_4#undef TYPE_PARAM_LIST_5#undef TYPE_PARAM_LIST_6
#undef PARAM_LIST_0#undef PARAM_LIST_1#undef PARAM_LIST_2#undefPARAM_LIST_3#undef PARAM_LIST_4#undef PARAM_LIST_5#undefPARAM_LIST_6} // namespace
#endif // WAN_DELEGATE_H threadingmodel.h #ifndefWAN_THREADINGMODEL_H#define WAN_THREADINGMODEL_H/** * @authorKevin Wan <wanjunfeng@gmail.com> * @date 12/30/2005 * Copyright(C) Kevin Wan */namespace wan{struct SingleThreadTag{};struct MultiThreadTag {};template <typenameLockType>class ThreadingModel{public: typedefMultiThreadTag ThreadTag; class Lock { Lock(constLock&); void operator=(const Lock&); public: explicit Lock(const ThreadingModel& host) : m_host(host) { m_host.m_mutex.lock(); } ~Lock() { m_host.m_mutex.unlock(); } private: constThreadingModel& m_host; }; friend class Lock; ThreadingModel() {}private: ThreadingModel(constThreadingModel&); ThreadingModel& operator=(constThreadingModel&);private: mutable LockType m_mutex;};template <>classThreadingModel<void>{public: typedef SingleThreadTagThreadTag; struct Lock { explicit Lock(constThreadingModel&) {} }; ThreadingModel(){}private: ThreadingModel(const ThreadingModel&); ThreadingModel& operator=(const ThreadingModel&);};} //namespace#endif // WAN_THREADINGMODEL_H example.cc #include<stdio.h>#include "delegate.h"const char* bar ="##########################################";void native_func(intvalue){ printf("%s\n", bar); printf("native function, value =%d\n", value);}class Object{public: static voidstatic_member_func(int value) { printf("%s\n",bar); printf("static member function, value = %d\n", value); } void non_const_member_func(int value) { printf("%s\n", bar); printf("non-const member function, value =%d\n", value); } void const_member_func(int value) const { printf("%s\n", bar); printf("const member function,value = %d\n", value); }};classFunctor{public: void operator()(int value) { printf("%s\n", bar); printf("non-const functor, value = %d\n",value); }};class ConstFunctor{public: voidoperator()(int value) const { printf("%s\n", bar); printf("const functor, value = %d\n", value); }};intmain(){ typedef wan::delegate<void(int)> MyDelegate; Object obj; Functor functor; ConstFunctor constFunctor; MyDelegate dele; dele.add(&native_func); dele.add(&Object::static_member_func); dele.add(&obj,&Object::non_const_member_func); dele.add(&obj,&Object::const_member_func); dele.add(&functor); dele.add(&constFunctor); dele(111); printf("%s\n",bar); printf("\n\nafter remove operations\n\n"); dele.remove(&native_func); dele.remove(&obj,&Object::non_const_member_func); dele(222); printf("%s\n",bar); printf("\n\nadd delegate object to delegateobject\n\n"); MyDelegate temp; temp.add(&native_func); temp.add(&obj,&Object::non_const_member_func); dele.add(&temp); dele(333); printf("%s\n", bar);}test.cc #include<stdio.h>#include "delegate.h"// #include "mutex.h"structDummyLock{ void lock() {} void unlock() {}};voidprint_hello(){ printf("print_hello\n");}voidprint_world(){ printf("print_world\n");}classObject{public: Object() { printf("Object::Object\n"); } ~Object() { printf("Object::~Object\n"); } void print() const { printf("in Object::print\n"); } void test()const { wan::delegate<void()> d; d.add(this,&Object::print); d(); }};classFunctor{public: void operator()() const { printf("in Functor::operator() const\n"); }};intmain(){ { wan::delegate<void(), DummyLock>d; d.add(&print_hello); d.add(&print_world); if (d.equals(&d)) printf("the same\n"); else printf("not thesame\n"); printf("\n"); wan::delegate<void(),DummyLock>* pd = d.clone(); if (d.equals(pd)) printf("the same\n"); else printf("not thesame\n"); delete pd; printf("\n"); d(); wan::delegate<void(), DummyLock> d1(d); printf("%u\n", sizeof(d)); d.add(d); d(); printf("\n"); d.remove(d1); d(); } /* { wan::delegate<void(), Mutex> d; d.add(&print_hello); printf("%u\n", sizeof(d)); } */ { wan::delegate<void()> d; d.add(newObject(), &Object::print, true); d(); wan::delegate<void()> d1(d); wan::delegate<void()>* d2 =d.clone(); d1(); (*d2)(); delete d2; } { Object obj; obj.test(); } { wan::delegate<void()> d; d.add(new Functor(),true); d(); }}
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月11日 06时36分06秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
大视角、大方向、大问题、大架构:(二)应用的相关问题
2019-03-06
git
2019-03-06
@InitBinder的作用
2019-03-06
文件上传C:\fakepath\解决方案
2019-03-06
JAVA开发工作流程
2019-03-06
按照list中实体类的某一属性排序
2019-03-06
java计算某日期之后的日期
2019-03-06
struts2自定义类型转换器
2019-03-06
Java调用WebService之Axis实现
2019-03-06
SpringBoot Web(SpringMVC)
2019-03-06
安装rabbitMQ
2019-03-06
javascript 之对象-13
2019-03-06
解决:angularjs radio默认选中失效问题
2019-03-06
java按照关键字指定的key删除redis(支持模糊删除)
2019-03-06
tl-wr742n 怎么设置dns
2019-03-06
Vue基础入门学习
2019-03-06
Spring Validation 校验
2019-03-06
如何使用Postman生成不同格式测试的报告
2019-03-06
Jmeter-ForEach控制器
2019-03-06