callbacks,callback的實現

 2023-11-19 阅读 18 评论 0

摘要:Callback.h 繼承層次 CallBack實現類基類第一層子類第二層子類第三層子類SimpleRefCountCallbackImplBaseCallbackImplFunctorCallbackImplMemPtrCallbackImplBoundFunctorCallbackImplTwoBoundFunctorCallbackImplThreeBoundFunctorCallbackImplCallback封裝類 CallbackBase

Callback.h

繼承層次

  • CallBack實現類
基類第一層子類第二層子類第三層子類
SimpleRefCountCallbackImplBaseCallbackImplFunctorCallbackImpl
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 testvirtual 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

callbacks,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 pointerMEM_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 functortypename 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 functortypename TypeTraits<TX1>::ReferencedType m_a1;  //!< first bound argumenttypename 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 pimplstatic 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){..}
  • c++ callback、綁定前三個

    實現與上面類似

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能轉換成我這種類型,返回truebool 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能轉換成我這種類型,返回truebool 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);

callback什么意思、轉載于:https://www.cnblogs.com/rainySue/p/callback-de-shi-xian.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/180402.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息