Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
2.8 KiB

  1. //
  2. // MODULE: POINTER.H
  3. //
  4. // PURPOSE: Smart pointer that counts references, deletes object when no more references
  5. //
  6. // PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
  7. //
  8. // COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
  9. //
  10. // AUTHOR: Joe Mabel
  11. //
  12. // ORIGINAL DATE: 9-8-98
  13. //
  14. // NOTES:
  15. // 1. Because these are templates, all code is in the header file.
  16. // 2. counting_ptr is intended to be used as part of a "publishing system":
  17. // A "publisher" creates a counting_ptr P to a heap object X. "Clients" obtain access to X
  18. // by copying P or assigning a counting_ptr to be equal to P.
  19. // Write/copy/delete access to P should be under control of a mutex. A single mutex may
  20. // control access to multiple published objects.
  21. // The publisher terminates the publication of *P by deleting or reassigning P. Once no client
  22. // is using *P, *P should go away.
  23. // class X is expected to be an actual class. If it is (say) an int, this will give
  24. // warning C4284, because it makes no sense to use operator-> on an int.
  25. //
  26. // Version Date By Comments
  27. //--------------------------------------------------------------------
  28. // V3.0 9-8-98 JM
  29. //
  30. #ifndef __POINTER_H_
  31. #define __POINTER_H_ 1
  32. #include <windows.h>
  33. #include <windef.h>
  34. #include <winbase.h>
  35. template<class X> class counting_ptr
  36. {
  37. private:
  38. template<class Y> class ref_counter
  39. {
  40. private:
  41. long m_RefCount;
  42. Y* m_px;
  43. ~ref_counter() {}; // Force this to be on the heap.
  44. public:
  45. ref_counter(Y* px = 0) :
  46. m_RefCount(1),
  47. m_px (px)
  48. {}
  49. void AddRef() {::InterlockedIncrement(&m_RefCount);}
  50. void RemoveRef()
  51. {
  52. if (::InterlockedDecrement(&m_RefCount) == 0)
  53. {
  54. delete m_px;
  55. delete this;
  56. }
  57. }
  58. Y& Ref() const { return *m_px; } // supports counting_ptr::operator*
  59. Y* DumbPointer() const { return m_px; } // supports counting_ptr::operator->
  60. };
  61. ref_counter<X> *m_pLow;
  62. public:
  63. // if px != NULL, *px MUST be on the heap (created with new).
  64. explicit counting_ptr(X* px=0) :
  65. m_pLow(new ref_counter<X>(px))
  66. {}
  67. counting_ptr(const counting_ptr<X>& sib) :
  68. m_pLow(sib.m_pLow)
  69. {m_pLow->AddRef();}
  70. counting_ptr<X>& operator=(const counting_ptr<X>& sib)
  71. {
  72. if (sib.m_pLow != m_pLow)
  73. {
  74. (sib.m_pLow)->AddRef();
  75. m_pLow->RemoveRef();
  76. m_pLow = sib.m_pLow;
  77. }
  78. return *this;
  79. }
  80. counting_ptr<X>& operator=( const X *px )
  81. {
  82. if (px != m_pLow->DumbPointer())
  83. {
  84. m_pLow->RemoveRef();
  85. // This const_cast was necessary in order to compile.
  86. m_pLow= new ref_counter<X>(const_cast<X *>(px));
  87. }
  88. return *this;
  89. }
  90. ~counting_ptr() { m_pLow->RemoveRef(); }
  91. X& operator*() const { return m_pLow->Ref(); }
  92. X* operator->() const { return m_pLow->DumbPointer(); }
  93. X* DumbPointer() const { return m_pLow->DumbPointer(); }
  94. bool IsNull() const {return DumbPointer() == NULL;}
  95. };
  96. #endif // __POINTER_H_