delegate in c++ (new version)
发布日期:2021-05-09 04:09:51 浏览次数:20 分类:博客文章

本文共 19493 字,大约阅读时间需要 64 分钟。

Delegate in C# is similar to a function pointer in C or C++, but it's type-safe and easy to use. Using a delegate allows the programmer to encapsulate a reference to a method inside adelegate object. The delegate object can then be passed to code which can call thereferenced method, without having to know at compile time which method will beinvoked.
This C++ delegate library implements the similar concept. You can use it to as type-safe callback, thread entry routine etc.
you can download it from .
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
 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
#define
 TEMPLATE_LIST     TEMPLATE_LIST_0
#define
 TYPE_LIST         TYPE_LIST_0
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_0
#define
 PARAM_LIST        PARAM_LIST_0
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_1
#define
 TYPE_LIST         TYPE_LIST_1
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_1
#define
 PARAM_LIST        PARAM_LIST_1
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_2
#define
 TYPE_LIST         TYPE_LIST_2
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_2
#define
 PARAM_LIST        PARAM_LIST_2
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_3
#define
 TYPE_LIST         TYPE_LIST_3
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_3
#define
 PARAM_LIST        PARAM_LIST_3
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_4
#define
 TYPE_LIST         TYPE_LIST_4
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_4
#define
 PARAM_LIST        PARAM_LIST_4
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_5
#define
 TYPE_LIST         TYPE_LIST_5
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_5
#define
 PARAM_LIST        PARAM_LIST_5
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
#define
 TEMPLATE_LIST     TEMPLATE_LIST_6
#define
 TYPE_LIST         TYPE_LIST_6
#define
 TYPE_PARAM_LIST TYPE_PARAM_LIST_6
#define
 PARAM_LIST        PARAM_LIST_6
#include 
"
__delegate.h
"
#undef
 TEMPLATE_LIST
#undef
 TYPE_LIST
#undef
 TYPE_PARAM_LIST
#undef
 PARAM_LIST
//
 remove the macros
#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
__delegate.h
/*
*
 * @author Kevin Wan <wanjunfeng@gmail.com>
 * @date   06/30/2005
 * Copyright (C) Kevin Wan
 
*/
   
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;
};
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);
}
上一篇:Gmail added "Mail Fetcher" to gmail.
下一篇:用pylint来检查python程序的潜在错误

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月09日 21时50分01秒