zoukankan      html  css  js  c++  java
  • callback的实现

    Callback.h

    继承层次

    • CallBack实现类
    基类 第一层子类 第二层子类 第三层子类
    SimpleRefCount CallbackImplBase CallbackImpl FunctorCallbackImpl
    MemPtrCallbackImpl
    BoundFunctorCallbackImpl
    TwoBoundFunctorCallbackImpl
    ThreeBoundFunctorCallbackImpl
    • Callback封装类
      • CallbackBase 封装Ptr<CallbackImplBase> m_impl
      • Callback CallbackBase的子类。根据传入的不同实参,构造不同类型的callback。 屏幕快照 2016-08-13 下午4.53.12

    模板整体说明

    • CallbackImpl:有不同的特化子模板
      • 根据重载()操作符时需要的形参类型个数将Ti~Tk特化为empty类,调用是根据传入的模板形参个数匹配相应的模板
      • R:回调返回值
    • FunctorCallbackImpl:CallbackImpl没有默认值,
      • T:泛函的类型(配套的,包括泛函返回类型,泛函形参类型)
    • MemPtrCallbackImpl:CallbackImpl
      • OBJ_PTR:object的类型
      • MEM_PTR:object成员泛函的类型(包括泛函返回类型,泛函形参类型)
    • BoundFunctorCallbackImpl: CallbackImpl

      • T:泛函类型
      • R:回调返回值
      • Tx:绑定的类型
      • 回调时,总有一个类型为Tx的值作为回调的形参
    • CallBack:T1~T9:默认值为empty类

    • MakeCallback<>模板函数:根据传入不同的形参,实例化不同版本

      • 形参:泛函指针
        • 根据传入的普通泛函涉及的类型个数(返回值类型,形参类型个数)匹配不同回调形参个数的模板
      • 形参:类成员泛函指针,类对象指针
        • 根据传入的类成员泛函的涉及的类型(返回值类型,形参类型个数)匹配不同回调形参的模板
      • 形参:泛函指针,绑定的值(1~3个)

    CallbackTraits

    • 模板1 c++ template <typename T> struct CallbackTraits;
    • 将指针转化为引用,用于MemPtrCallBackImpl c++ template <typename T> struct CallbackTraits<T *> { static T & GetReference (T * const p){ return *p; } };

    CallbackImplBase

    class CallbackImplBase : public SimpleRefCount<CallbackImplBase>
    {
    public:
      virtual ~CallbackImplBase () {}
     // Equality test
      virtual bool IsEqual (Ptr<const CallbackImplBase> other) const = 0;
    };
    

    CallbackImpl

    通过重载函数操作符"()"实现
    - 模板声明,该模板限定了最多能传入9个形参给callback

    template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
    class CallbackImpl;
    
    • 无参数特化模板
    template <typename R>
    class CallbackImpl<R,empty,empty,empty,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
    public:
      virtual ~CallbackImpl () {}
      virtual R operator() (void) = 0;      //!< Abstract operator
    };
    
    • 将模板形参T2~T9特例话为空 这是将基类模板中模板形参T2到T9特化为empty类型的一个例子(部分特化)
    template <typename R, typename T1>
    class CallbackImpl<R,T1,empty,empty,empty,empty,empty,empty,empty,empty> : public CallbackImplBase {
    public:
      virtual ~CallbackImpl () {}
      virtual R operator() (T1) = 0;        //!< Abstract operator
    }; 
    
    • 其他类似
    • CallbackImpl的定义
    template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
    class CallbackImpl : public CallbackImplBase {
    public:
      virtual ~CallbackImpl () {}
      virtual R operator() (T1, T2, T3, T4, T5, T6, T7, T8, T9) = 0;  //!< Abstract operator
    };
    

    FunctorCallbackImpl

    CallbackImpl with functors
    R:回调返回类型;
    T :m_functor类型,T是一个函数指针的类型(包括函数形参列表,以及函数返回类型。而处于兼容性考虑,T应该是这样的类型 R(*)(T1,T2.......)

    template <typename T, typename R, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8, typename T9>
    class FunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> {
    public:
    FunctorCallbackImpl (T const &functor):m_functor(functor){}
    virtual ~FunctorCallbackImpl () {}
    //无输入参数的回调,
    R operator() (void) {return m_functor (); }
    //带一个形参的回调
     R operator() (T1 a1) {return m_functor (a1);  }
    // 其他形参个数的回调类似
    .......
    virtual bool IsEqual (Ptr<const CallbackImplBase> other) const{
    FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6,T7,T8,T9>const *otherDerived =dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *> (PeekPointer (other));//把其他类型的CallbackImpl转换成FunctorCallbackImpl类
    if (otherDerived == 0){return false;}
    else if (otherDerived->m_functor != m_functor){
        return false;}
    return true;
    }
    private:
      T m_functor;         //!< the functor
    };
    

    MemPtrCallbackImpl

    CallbackImpl for pointer to member functions
    模板形参MEM_PTR:类成员泛函的类型(涉及泛函返回类型,形参类型表等)

    template <typename OBJ_PTR, typename MEM_PTR, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
    class MemPtrCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> {
    public:
    MemPtrCallbackImpl (OBJ_PTR const&objPtr, MEM_PTR memPtr)
        : m_objPtr (objPtr), m_memPtr (memPtr) {}
      virtual ~MemPtrCallbackImpl () {}
      //无形参成员函数回调实现
      R operator() (void) {
     return ((CallbackTraits<OBJ_PTR>::GetReference (m_objPtr)).*m_memPtr)();//将m_objPtr转换成引用并调用其成员函数(*m_memPtr)  
     //其他参数个数的成员函数的回调实现类似
     }
     .......
     virtual bool IsEqual (Ptr<const CallbackImplBase> other) const {
     MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *otherDerived=dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> const *> (PeekPointer (other));
    if (otherDerived == 0){  return false;  }
    else if (otherDerived->m_objPtr != m_objPtr||therDerived->m_memPtr != m_memPtr){return false;}
    return true;
    }
    private:
      OBJ_PTR const m_objPtr;     //!< the object pointer
      MEM_PTR m_memPtr;        //!< the member function pointer
    };
    

    BoundFunctorCallbackImpl

    CallbackImpl for functors with first argument bound at construction

     template <typename T, typename R, typename TX, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7, typename T8>
    class BoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,empty> {
    public:
    template <typename FUNCTOR, typename ARG>
      BoundFunctorCallbackImpl (FUNCTOR functor, ARG a)
        : m_functor (functor), m_a (a) {}
      virtual ~BoundFunctorCallbackImpl () {}
    //没有可变类型形参的函数调用
    R operator() (void) {    return m_functor (m_a);  }
    //有一个Arg的函数回调
    R operator() (T1 a1) {  return m_functor (m_a,a1);  }
    //其他Arg个数的模板类似
    virtual bool IsEqual (Ptr<const CallbackImplBase> other) const{
    //实现和上面类似,先转换,然后比较
    }
    private:
      T m_functor;    //!< The functor
      typename TypeTraits<TX>::ReferencedType m_a;  //!< the bound argument
    };
    

    TwoBoundFunctorCallbackImpl

    CallbackImpl for functors with first two arguments bound at construction

    template <typename T, typename R, typename TX1, typename TX2, typename T1, typename T2, typename T3, typename T4,typename T5, typename T6, typename T7>
    class TwoBoundFunctorCallbackImpl : public CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,empty,empty> {
    ....
    private:
      T m_functor;              //!< The functor
      typename TypeTraits<TX1>::ReferencedType m_a1;  //!< first bound argument
      typename TypeTraits<TX2>::ReferencedType m_a2;  //!< second bound argument
    };
    }
    

    ThreeBoundFunctorCallbackImpl

    和上述类似

    CallbackBase

    class CallbackBase {
    public:
      CallbackBase () : m_impl () {}
       Ptr<CallbackImplBase> GetImpl (void) const { return m_impl; }
    protected:
    CallbackBase (Ptr<CallbackImplBase> impl) : m_impl (impl) {}
      Ptr<CallbackImplBase> m_impl;         //!< the pimpl
       static std::string Demangle (const std::string& mangled);
       //符号重组?这个干什么的呢?
    };
    

    CallBack类

    • 模板的示例化具有POD语义:需要的内存是自动管理的,并且允许用户传递一个CallBack实例
    • 模板使用pimpl idiom,传递CallBack类的值并将实现传递给其pimpl指针
    • CallbackImpl和 FunctorCallbackImpl的子类可用于任何functor-type,而 MemPtrCallbackImpl 可用于某一个类的成员函数指针
    • 通过reference list implementation实现CallBack类的值语义 ####Callback的构造函数
    • 空构造函数 Callback () {}
    • 根据 Ptr构建Callback c++ Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > const &impl): CallbackBase (impl){}
    • 内置类型为FunctorCallbackImpl 创建一个FunctorCallbackImpl的实例(第一参数特化为iFUNCTOR类型,其他分别是R,T1等)。创建Create模板函数的此FunctorCallbackImpl的实例,给函数传入实参functor,创建对应的Ptr的关于FunctorCallbackImpl的实例,将此Ptr对象作为CallBackBase类的构造函数实参
    template <typename FUNCTOR>
      Callback (FUNCTOR const &functor, bool, bool) 
     : CallbackBase(Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > (functor)){}
    
    • 内置类型为MemPtrCallbackImpl 实例化MemPtrCallbackImpl,创建一个此类型的ptr,传给Create函数的实参为objPtr和memPtr
    template <typename OBJ_PTR, typename MEM_PTR>
     Callback (OBJ_PTR const &objPtr, MEM_PTR memPtr):CallbackBase (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > (objPtr, memPtr)){}
    

    Callback的绑定

    • Bind
      • 构造一个绑定第一个Arg的回调
      • 实例化一个BoundFunctorCallbackImpl,实例化传入的模板实参解释
        • Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9>BoundFunctorCallbackImpl内置泛函类型
        • R:回调的返回类型
        • T1:绑定的类型
        • T2~T9:其他可控的函调形参类型
      • 创建上述BoundFunctorCallbackImpl实例类的一个对象
        • 传给类的构造函数的实参:(*this):BoundFunctorCallbackImpl的内部泛函
        • a :绑定的值
      • 创建Ptr>对象impl
        • 传给Ptr构造函数的实参:上面创建的BoundFunctorCallbackImpl实例类临时对象和false
      • 以impl为实参构建Callback对象
    template <typename T>
    Callback<R,T2,T3,T4,T5,T6,T7,T8,T9> Bind (T a) {
        Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,T7,T8,T9,empty> > impl =
          Ptr<CallbackImpl<R,T2,T3,T4,T5,T6,T7,T8,T9,empty> > (
            new BoundFunctorCallbackImpl<
              Callback<R,T1,T2,T3,T4,T5,T6,T7,T8,T9>,
              R,T1,T2,T3,T4,T5,T6,T7,T8,T9> (*this, a), false);
        return Callback<R,T2,T3,T4,T5,T6,T7,T8,T9> (impl);
      }
    
    • 绑定前两个 实现与Bind类似
    template <typename TX1, typename TX2>
    Callback<R,T3,T4,T5,T6,T7,T8,T9> TwoBind (TX1 a1, TX2 a2){..}
    
    • 绑定前三个

      实现与上面类似

    template <typename TX1, typename TX2, typename TX3>
      Callback<R,T4,T5,T6,T7,T8,T9> ThreeBind (TX1 a1, TX2 a2, TX3 a3){...}
    

    Callback的其他成员函数函数

    template<typename R,typename T1 = empty, typename T2 = empty,typename T3 = empty, typename T4 = empty,typename T5 = empty, typename T6 = empty,typename T7 = empty, typename T8 = empty,typename T9 = empty>
    class Callback : public CallbackBase {
    public:
    bool IsNull (void) const {
       return (DoPeekImpl () == 0) ? true : false;
     }
     void Nullify (void) {
        m_impl = 0;
      }
      //无输入参数的回调
     R operator() (void) const {
        return (*(DoPeekImpl ()))();
      }
      //输入一个参数的回调
      R operator() (T1 a1) const {
        return (*(DoPeekImpl ()))(a1);
      }
     // 其他输入参数个数的回调与上述类似
     bool IsEqual (const CallbackBase &other) const {
        return m_impl->IsEqual (other.GetImpl ());
      }
      //如果other能转换成我这种类型,返回true
       bool CheckType (const CallbackBase & other) const {
        return DoCheckType (other.GetImpl ());
      }
      void Assign (const CallbackBase &other) {
        DoAssign (other.GetImpl ());
      }
      private:
      CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *DoPeekImpl (void) const {
        return static_cast<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *> (PeekPointer (m_impl));
      }
      //如果other能转换成我这种类型,返回true
      bool DoCheckType (Ptr<const CallbackImplBase> other) const {
        if (other != 0 && dynamic_cast<const CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *> (PeekPointer (other)) != 0)
        {  return true; //不为空且能转换    }
        else if (other == 0){ return true; //传入的Ptr为空 }
        else{   return false; }
      }
      void DoAssign (Ptr<const CallbackImplBase> other) {
        if (!DoCheckType (other))
          {
            Ptr<CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> > expected;
            NS_FATAL_ERROR (....);
          }
        m_impl = const_cast<CallbackImplBase *> (PeekPointer (other));
      }
    }
    

    MakeCallback模板函数

    针对不同形参个数的函数指针的 MakeCallback函数模板

    template <typename R>
    Callback<R> MakeCallback (R (*fnPtr)()) {
      return Callback<R> (fnPtr, true, true);
    }
    template <typename R, typename T1>
    Callback<R,T1> MakeCallback (R (*fnPtr)(T1)) {
      return Callback<R,T1> (fnPtr, true, true);
    }
    //其他类型函数指针的MakeCallback类似
    

    针对不同形参个数的类成员函数指针的 MakeCallback函数模板

    template <typename T, typename OBJ, typename R>
    Callback<R> MakeCallback (R (T::*memPtr)(void), OBJ objPtr) {
      return Callback<R> (objPtr, memPtr);
    }//const版本类似
    template <typename T, typename OBJ, typename R, typename T1>
    Callback<R,T1> MakeCallback (R (T::*memPtr)(T1), OBJ objPtr) {
      return Callback<R,T1> (objPtr, memPtr);
    }
    //其他类似
    
    • != 符号的重载

    • MakeNullCallback的定义

    • MakeBoundCallback的定义(包括绑定一个,两个等)

      CallBack类的和属性系统相关的东西

    class CallbackValue : public AttributeValue
    {
    public:
    CallbackValue ();
     CallbackValue (const CallbackBase &base);
     virtual ~CallbackValue ();
     void Set (CallbackBase base);
     template <typename T>
      bool GetAccessor (T &value) const;
      virtual Ptr<AttributeValue> Copy (void) const;
      virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const;
      virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker);
      private:
      CallbackBase m_value;                 //!< the CallbackBase
    };
    ATTRIBUTE_ACCESSOR_DEFINE (Callback);
    ATTRIBUTE_CHECKER_DEFINE (Callback);
    //Assign和CheckType函数是callback的成员函数。因此T应该也是一张callback又是哪里定义的
    template <typename T>
    bool CallbackValue::GetAccessor (T &value) const
    {
      if (value.CheckType (m_value))
        {
          value.Assign (m_value);
          return true;
        }
      return false;
    }
    

    Callback.cc

    • CallbackValue类成员函数的一些定义
    • 定义和Callback相关的checker
    ATTRIBUTE_CHECKER_IMPLEMENT (Callback);
    
  • 相关阅读:
    [转]王垠的过去和现状
    支持向量机(SVM)基础
    C语言编程心得
    Fortran学习心得
    gdb使用心得
    大道至简第一章读后感
    第一个音符
    Exercise 1.20 最大公约数算法
    Exercise 1.19 Fast Fibonacci
    Exercise 1.16 1.17 1.18
  • 原文地址:https://www.cnblogs.com/rainySue/p/callback-de-shi-xian.html
Copyright © 2011-2022 走看看