在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秒