SmartPointer.h 3.2 KB

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