zoukankan      html  css  js  c++  java
  • 在C++中实现delegate

    delegate.h
    #ifndef WAN_DELEGATE_H
    #define WAN_DELEGATE_H
      
    /**
     * @author Kevin Wan <wanjunfeng@gmail.com>
     * @date   06/30/2005
     * Copyright (C) Kevin Wan
     */
    #include "threadingmodel.h"
      
    namespace wan
    {
    namespace local
    {
    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 ReturnType TEMPLATE_LIST> \
    class ICallback<ReturnType(TYPE_LIST)> \
    { \
        typedef ICallback<ReturnType(TYPE_LIST)> SelfType; \
    \
    public: \
        virtual ~ICallback() {} \
    \
        virtual ReturnType invoke(TYPE_LIST) const = 0; \
        virtual bool equals(const SelfType* pDelegate) const = 0; \
        virtual SelfType* clone() const = 0; \
    }; \
    \
    template <typename ReturnType TEMPLATE_LIST> \
    class NativeCallback<ReturnType(TYPE_LIST)> \
        : public ICallback<ReturnType(TYPE_LIST)> \
    { \
        typedef ICallback<ReturnType(TYPE_LIST)> SuperType; \
        typedef NativeCallback<ReturnType(TYPE_LIST)> SelfType; \
        typedef ReturnType (*FunctionPtr)(TYPE_LIST); \
    \
    public: \
        explicit NativeCallback(FunctionPtr ptr) \
            : m_handler(ptr) \
        { \
        } \
    \
        NativeCallback(const SelfType& rhs) \
            : ICallback<ReturnType(TYPE_LIST)>(rhs) \
            , m_handler(rhs.m_handler) \
        { \
        } \
    \
        ReturnType invoke(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> \
    class MemberCallback<ObjectType, ReturnType(TYPE_LIST)> \
        : public ICallback<ReturnType(TYPE_LIST)> \
    { \
        typedef ICallback<ReturnType(TYPE_LIST)> SuperType; \
        typedef MemberCallback<ObjectType, ReturnType(TYPE_LIST)> SelfType; \
        typedef ReturnType (ObjectType::*FunctionPtr)(TYPE_LIST); \
        typedef ReturnType (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(const SelfType& 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<const SelfType*>(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) \
                return true; \
            return false; \
        } \
    \
        SelfType* clone() const \
        { \
            return new SelfType(*this); \
        } \
    \
    private: \
        void incrementRefCount() \
        { \
            ++m_pObjectManager->refCount; \
        } \
    \
        void decrementRefCount() \
        { \
            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> \
        : public local::ICallback<ReturnType(TYPE_LIST)> \
        , public ThreadingModel<LockType> \
    { \
        typedef local::ICallback<ReturnType(TYPE_LIST)> SuperType; \
        typedef delegate<ReturnType(TYPE_LIST), LockType> SelfType; \
        typedef ThreadingModel<LockType> ThreadingModelType; \
        struct CallbackHolder \
        { \
            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) {} \
    \
        explicit delegate(ReturnType (*ptr)(TYPE_LIST)) \
            : m_pHolder(0) \
        { \
            this->add(ptr); \
        } \
    \
        template <typename ObjectType> \
        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 <typename FunctorType> \
        explicit delegate(FunctorType* pFunctor, bool needDelete = false) \
            : m_pHolder(0) \
        { \
            this->add(pFunctor, needDelete); \
        } \
    \
        delegate(const SelfType& 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() \
        { \
            typename ThreadingModelType::Lock guard(*this); \
            CallbackHolder* ptr = m_pHolder; \
            while (ptr != 0) \
            { \
                CallbackHolder* prev = ptr->prev; \
                delete ptr->instance; \
                delete ptr; \
                ptr = prev; \
            } \
            m_pHolder = 0; \
        } \
    \
        ReturnType operator()(TYPE_PARAM_LIST) \
        { \
            return this->invoke(PARAM_LIST); \
        } \
    \
        ReturnType invoke(TYPE_PARAM_LIST) const \
        { \
            typename ThreadingModelType::Lock guard(*this); \
            if (m_pHolder == 0) return ReturnType(); \
            return m_pHolder->call(PARAM_LIST); \
        } \
    \
        bool equals(const SuperType* pDelegate) const \
        { \
            const SelfType* pRhs = dynamic_cast<const SelfType*>(pDelegate); \
            if (pRhs == 0) return false; \
    \
            SelfType* temp = 0; \
            const SelfType* pClone; \
            cloneForComparison(pRhs, pClone, temp, typename ThreadingModelType::ThreadTag()); \
    \
            typename ThreadingModelType::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 = new SelfType(); \
            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 = new local::NativeCallback<ReturnType(TYPE_LIST)>(ptr); \
            this->addImpl(pNew); \
        } \
    \
        template <typename ObjectType> \
        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> \
        void add(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST), bool needDelete = false) \
        { \
            SuperType* pNew = new local::MemberCallback<ObjectType, ReturnType(TYPE_LIST)> \
                    (t, ptr, needDelete); \
            this->addImpl(pNew); \
        } \
    \
        template <typename ObjectType> \
        void add(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> \
        void add(FunctorType* pFunctor, bool needDelete = false) \
        { \
            this->add(pFunctor, &FunctorType::operator(), needDelete); \
        } \
    \
        template <typename FunctorType> \
        void add(const FunctorType* pFunctor) \
        { \
            this->add(pFunctor, &FunctorType::operator()); \
        } \
    \
        void add(const SelfType& rhs) \
        { \
            SelfType* pClone = rhs.clone(); \
            this->addImpl(pClone); \
        } \
    \
        void remove(ReturnType (*ptr)(TYPE_LIST)) \
        { \
            SuperType* pNew = new local::NativeCallback<ReturnType(TYPE_LIST)>(ptr); \
            this->removeImpl(pNew); \
        } \
    \
        template <typename ObjectType> \
        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> \
        void remove(ObjectType* t, ReturnType(ObjectType::*ptr)(TYPE_LIST), bool needDelete = false) \
        { \
            SuperType* pNew = new local::MemberCallback<ObjectType, ReturnType(TYPE_LIST)> \
                (t, ptr, needDelete); \
            this->removeImpl(pNew); \
        } \
    \
        template <typename ObjectType> \
        void remove(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> \
        void remove(FunctorType* pFunctor, bool needDelete = false) \
        { \
            this->remove(pFunctor, &FunctorType::operator(), needDelete); \
        } \
    \
        template <typename FunctorType> \
        void remove(const FunctorType* pFunctor) \
        { \
            this->remove(pFunctor, &FunctorType::operator()); \
        } \
    \
        void remove(const SelfType& rhs) \
        { \
            this->remove(rhs, typename ThreadingModelType::ThreadTag()); \
        } \
    \
    private: \
        void cloneForComparison(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(const SelfType& rhs) \
        { \
            SelfType* pClone = rhs.clone(); \
            m_pHolder = pClone->m_pHolder; \
            pClone->m_pHolder = 0; \
            delete pClone; \
        } \
    \
        void remove(const SelfType& rhs, SingleThreadTag) \
        { \
            this->removeImpl(&rhs); \
        } \
    \
        void remove(const SelfType& rhs, MultiThreadTag) \
        { \
            this->removeImpl(rhs.clone()); \
        } \
    \
        void addImpl(SuperType* pRhs) \
        { \
            typename ThreadingModelType::Lock guard(*this); \
            CallbackHolder* pH = new CallbackHolder(); \
            pH->instance = pRhs; \
            pH->prev = m_pHolder; \
            m_pHolder = pH; \
        } \
    \
        void removeImpl(const SuperType* pRhs) \
        { \
            typename ThreadingModelType::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
    #define TEMPLATE_LIST_3 TEMPLATE_LIST_2, typename T2
    #define TEMPLATE_LIST_4 TEMPLATE_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_2 TYPE_LIST_1, T1
    #define TYPE_LIST_3 TYPE_LIST_2, T2
    #define TYPE_LIST_4 TYPE_LIST_3, T3
    #define TYPE_LIST_5 TYPE_LIST_4, T4
    #define TYPE_LIST_6 TYPE_LIST_5, T5
    #define TYPE_PARAM_LIST_0
    #define TYPE_PARAM_LIST_1 T0 t0
    #define TYPE_PARAM_LIST_2 TYPE_PARAM_LIST_1, T1 t1
    #define TYPE_PARAM_LIST_3 TYPE_PARAM_LIST_2, T2 t2
    #define TYPE_PARAM_LIST_4 TYPE_PARAM_LIST_3, T3 t3
    #define TYPE_PARAM_LIST_5 TYPE_PARAM_LIST_4, T4 t4
    #define TYPE_PARAM_LIST_6 TYPE_PARAM_LIST_5, T5 t5
    #define PARAM_LIST_0
    #define PARAM_LIST_1 t0
    #define PARAM_LIST_2 PARAM_LIST_1, t1
    #define PARAM_LIST_3 PARAM_LIST_2, t2
    #define PARAM_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
      
    #undef TEMPLATE_LIST_0
    #undef TEMPLATE_LIST_1
    #undef TEMPLATE_LIST_2
    #undef TEMPLATE_LIST_3
    #undef TEMPLATE_LIST_4
    #undef TEMPLATE_LIST_5
    #undef TEMPLATE_LIST_6
    #undef TYPE_LIST_0
    #undef TYPE_LIST_1
    #undef TYPE_LIST_2
    #undef TYPE_LIST_3
    #undef TYPE_LIST_4
    #undef TYPE_LIST_5
    #undef TYPE_LIST_6
    #undef TYPE_PARAM_LIST_0
    #undef TYPE_PARAM_LIST_1
    #undef TYPE_PARAM_LIST_2
    #undef TYPE_PARAM_LIST_3
    #undef TYPE_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
    #undef PARAM_LIST_3
    #undef PARAM_LIST_4
    #undef PARAM_LIST_5
    #undef PARAM_LIST_6
    } // namespace
    #endif // WAN_DELEGATE_H

    threadingmodel.h
    #ifndef WAN_THREADINGMODEL_H
    #define WAN_THREADINGMODEL_H

    /**
     * @author Kevin Wan <wanjunfeng@gmail.com>
     * @date   12/30/2005
     * Copyright (C) Kevin Wan
     */

    namespace wan
    {
    struct SingleThreadTag {};
    struct MultiThreadTag {};

    template <typename LockType>
    class ThreadingModel
    {
    public:
        typedef MultiThreadTag ThreadTag;

        class Lock
        {
            Lock(const Lock&);
            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:
            const ThreadingModel& m_host;
        };

        friend class Lock;

        ThreadingModel() {}

    private:
        ThreadingModel(const ThreadingModel&);
        ThreadingModel& operator=(const ThreadingModel&);

    private:
        mutable LockType    m_mutex;
    };

    template <>
    class ThreadingModel<void>
    {
    public:
        typedef SingleThreadTag ThreadTag;

        struct Lock
        {
            explicit Lock(const ThreadingModel&) {}
        };

        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(int value)
    {
        printf("%s\n", bar);
        printf("native function, value = %d\n", value);
    }

    class Object
    {
    public:
        static void static_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);
        }
    };

    class Functor
    {
    public:
        void operator()(int value)
        {
            printf("%s\n", bar);
            printf("non-const functor, value = %d\n", value);
        }
    };

    class ConstFunctor
    {
    public:
        void operator()(int value) const
        {
            printf("%s\n", bar);
            printf("const functor, value = %d\n", value);
        }
    };

    int main()
    {
        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 delegate object\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"

    struct DummyLock
    {
        void lock() {}
        void unlock() {}
    };

    void print_hello()
    {
        printf("print_hello\n");
    }

    void print_world()
    {
        printf("print_world\n");
    }

    class Object
    {
    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();
        }
    };

    class Functor
    {
    public:
        void operator()() const
        {
            printf("in Functor::operator() const\n");
        }
    };

    int main()
    {
        {
            wan::delegate<void(), DummyLock> d;
            d.add(&print_hello);
            d.add(&print_world);
            if (d.equals(&d))
                printf("the same\n");
            else
                printf("not the same\n");
            printf("\n");
            wan::delegate<void(), DummyLock>* pd = d.clone();
            if (d.equals(pd))
                printf("the same\n");
            else
                printf("not the same\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(new Object(), &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();
        }
    }
  • 相关阅读:
    Selenium笔记(三)--WebDriver 等待、支持的类、javaScript警告框、提示框、确认框、Http代理、页面加载策略、网络元素、Keyboard;远程WebDriver
    Selenium3+python3自动化(四十八)--阿里云centos7上搭建selenium启动chrome浏览器headless无界面模式
    Selenium3+python3自动化(四十七)--定位的坑:class属性有空格
    Selenium3+python3自动化(四十六)--弹窗处理(PyKeyboard) tab切换,enter回车,输入
    Selenium3+python3自动化(四十五)--弹出框死活定位不到
    Selenium3+python3自动化(四十四)--行为事件(ActionChains)源码详解
    Selenium3+python3自动化(四十三)--爬取我的博客园粉丝的名称,并写入.text文件
    Selenium3+python3自动化(四十二)--批量操作循环点击报错
    Selenium3+python3自动化(四十一)--Chrome浏览器静默模式启动(headless)
    Selenium3+python3自动化(四十)--Chrome正在受到自动软件的控制
  • 原文地址:https://www.cnblogs.com/kevinwan/p/371692.html
Copyright © 2011-2022 走看看