SmartPointer.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #ifndef RVC_COMM_SMARTPOINTER_H__
  2. #define RVC_COMM_SMARTPOINTER_H__
  3. #pragma once
  4. #include <assert.h>
  5. #ifndef _WIN32
  6. #include <winpr/interlocked.h>
  7. #endif //NOT _WIN32
  8. template<class T> class CSmartPointer
  9. {
  10. public:
  11. CSmartPointer():m_pPoint(NULL),m_pnReference(NULL){}
  12. CSmartPointer(T *pPoint) :m_pPoint(pPoint), m_pnReference(NULL){}
  13. CSmartPointer(const CSmartPointer<T> &Point)
  14. :m_pPoint(Point.m_pPoint),m_pnReference(Point.m_pnReference)
  15. {
  16. if(m_pnReference)
  17. InterlockedIncrement(m_pnReference);
  18. }
  19. ~CSmartPointer()
  20. {
  21. Clear();
  22. }
  23. CSmartPointer<T> &operator=(T *pPoint)
  24. {
  25. if(pPoint!=m_pPoint)
  26. {
  27. Clear();
  28. m_pPoint=pPoint;
  29. }
  30. return *this;
  31. }
  32. CSmartPointer<T> &operator =(const CSmartPointer<T> &Point)
  33. {
  34. if(Point.m_pPoint!=m_pPoint)
  35. {
  36. Clear();
  37. m_pPoint=Point.m_pPoint;
  38. m_pnReference=Point.m_pnReference;
  39. if(m_pnReference)
  40. InterlockedIncrement(m_pnReference);
  41. }
  42. return *this;
  43. }
  44. bool operator ==(T *pPoint)const
  45. {
  46. return m_pPoint==pPoint;
  47. }
  48. bool operator ==(const CSmartPointer<T> &Point)const
  49. {
  50. return m_pPoint==Point.m_pPoint;
  51. }
  52. bool operator !=(T *pPoint)const
  53. {
  54. return m_pPoint!=pPoint;
  55. }
  56. bool operator !=(const CSmartPointer<T> &Point)const
  57. {
  58. return m_pPoint!=Point.m_pPoint;
  59. }
  60. void Attach(T *pPoint)
  61. {
  62. Attach(pPoint, NULL);
  63. }
  64. void Attach(T *pPoint,LONG *pnReference)
  65. {
  66. if(m_pPoint!=pPoint)
  67. {
  68. Clear();
  69. m_pPoint=pPoint;
  70. m_pnReference=pnReference;
  71. if(pnReference!=NULL && *pnReference>0)
  72. InterlockedIncrement(m_pnReference);
  73. else
  74. m_pnReference = new LONG(1);
  75. }
  76. }
  77. T *Detach()
  78. {
  79. if(m_pnReference)
  80. {
  81. if (*m_pnReference != 1)
  82. {
  83. assert(false);
  84. return NULL;
  85. }
  86. else
  87. {
  88. delete m_pnReference;
  89. m_pnReference=NULL;
  90. }
  91. }
  92. T *pRet=m_pPoint;
  93. m_pPoint=NULL;
  94. return pRet;
  95. }
  96. void AddRef()
  97. {
  98. if (m_pnReference != NULL && *m_pnReference > 0)
  99. InterlockedIncrement(m_pnReference);
  100. }
  101. void SubRef()
  102. {
  103. if (m_pnReference)
  104. {
  105. LONG nRef = InterlockedDecrement(m_pnReference);
  106. if (nRef == 0)
  107. {
  108. delete m_pPoint;
  109. delete m_pnReference;
  110. }
  111. m_pnReference = NULL;
  112. }
  113. }
  114. void Clear()
  115. {
  116. if(m_pnReference)
  117. {
  118. LONG nRef=InterlockedDecrement(m_pnReference);
  119. if(nRef==0)
  120. {
  121. delete m_pPoint;
  122. delete m_pnReference;
  123. }
  124. m_pnReference=NULL;
  125. }
  126. m_pPoint=NULL;
  127. }
  128. T *operator ->() const
  129. {
  130. return m_pPoint;
  131. }
  132. /*operator T*() const
  133. {
  134. return m_pPoint;
  135. }*/
  136. T* GetRawPointer() const
  137. {
  138. return m_pPoint;
  139. }
  140. #if 1
  141. template<class P>
  142. CSmartPointer<P> ConvertCase()
  143. {
  144. CSmartPointer<P> pRet;
  145. try
  146. {
  147. if (m_pnReference != NULL)
  148. pRet.Attach(dynamic_cast<P *>(m_pPoint),m_pnReference);
  149. else
  150. pRet = dynamic_cast<P *>(m_pPoint); // if not managed originally, ret pointer should not be managed too!!!
  151. }
  152. catch(...)
  153. {
  154. return NULL;
  155. }
  156. return pRet;
  157. }
  158. #else
  159. template<class P>
  160. CSmartPointer<P> ConvertCase() // do this a little bit brute-force
  161. {
  162. CSmartPointer<P> pRet;
  163. P **pp = (P**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pPoint));
  164. *pp = dynamic_cast<P *>(m_pPoint);
  165. LONG **pr = (LONG**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pnReference));
  166. *pr = m_pnReference;
  167. if(m_pnReference)
  168. InterlockedIncrement(m_pnReference);
  169. return pRet;
  170. }
  171. #endif
  172. private:
  173. T *m_pPoint;
  174. LONG *m_pnReference;
  175. };
  176. #endif