ReferencePtr.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (C) 2000 Sean Cavanaugh
  2. // This file is licensed under the terms of the Lesser GNU Public License
  3. // (see LPGL.txt, or http://www.gnu.org/copyleft/lesser.txt)
  4. #if !defined(AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)
  5. #define AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #ifdef WIN32
  10. #define WIN32_LEAN_AND_MEAN
  11. #include "windows.h"
  12. #endif
  13. #include "assert.h"
  14. #include "limits.h"
  15. #ifdef SYSTEM_POSIX
  16. #ifdef HAVE_STDDEF_H
  17. // For NULL
  18. #include <stddef.h>
  19. #endif
  20. #endif
  21. #include "ReferenceCounter.h"
  22. /*!
  23. \author Sean Cavanaugh
  24. \email [email protected]
  25. \cvsauthor $Author: sean $
  26. \date $Date: 2000/09/11 20:28:24 $
  27. \version $Revision: 1.1 $
  28. \brief ReferencePtr is a simplified ReferencePtr, primiarily for use with reference counted pointers.
  29. Its purpose is solely for simplified garbage collection, and not any kind of advanced
  30. copy on write functionality. Passing a normal pointer to this class effectively starts
  31. its reference count at one and should not be manually deleted. (But it may be referenced
  32. as long as you know the object still exists in some scope somewhere)
  33. */
  34. template<class DATA_T>
  35. class ReferencePtrBlock
  36. {
  37. public:
  38. DATA_T* pData; // User defined data block
  39. mutable ReferenceCounter ReferenceCount;
  40. };
  41. template<class DATA_T>
  42. class ReferencePtr
  43. {
  44. public:
  45. // Construction
  46. ReferencePtr();
  47. ReferencePtr(DATA_T* other);
  48. ReferencePtr(const ReferencePtr<DATA_T>& other);
  49. virtual ~ReferencePtr();
  50. // Assignment
  51. ReferencePtr<DATA_T>& operator=(const ReferencePtr<DATA_T>& other);
  52. ReferencePtr<DATA_T>& operator=(DATA_T* other);
  53. // Dereferencing
  54. operator DATA_T*() const {return m_pData->pData;}
  55. DATA_T* operator->() const {return m_pData->pData;}
  56. protected:
  57. // Internal methods
  58. void Alloc(); // Allocate the m_pData
  59. void Release(); // Releases a reference count (possibly freeing memory)
  60. protected:
  61. // Member data
  62. ReferencePtrBlock<DATA_T>* m_pData;
  63. };
  64. template<class DATA_T>
  65. ReferencePtr<DATA_T>::ReferencePtr()
  66. {
  67. Alloc();
  68. }
  69. template<class DATA_T>
  70. ReferencePtr<DATA_T>::ReferencePtr(DATA_T* other)
  71. {
  72. Alloc();
  73. m_pData->pData = other;
  74. m_pData->ReferenceCount = 1;
  75. }
  76. template<class DATA_T>
  77. ReferencePtr<DATA_T>::ReferencePtr(const ReferencePtr<DATA_T>& other)
  78. {
  79. m_pData = other.m_pData;
  80. m_pData->ReferenceCount++;
  81. }
  82. template<class DATA_T>
  83. ReferencePtr<DATA_T>::~ReferencePtr()
  84. {
  85. Release();
  86. }
  87. template<class DATA_T>
  88. ReferencePtr<DATA_T>& ReferencePtr<DATA_T>::operator=(const ReferencePtr<DATA_T>& other)
  89. {
  90. if (m_pData != other.m_pData)
  91. {
  92. Release();
  93. m_pData = other.m_pData;
  94. m_pData->ReferenceCount++;
  95. }
  96. return *this;
  97. }
  98. template<class DATA_T>
  99. ReferencePtr<DATA_T>& ReferencePtr<DATA_T>::operator=(DATA_T* other)
  100. {
  101. if (m_pData->ReferenceCount.dec() <= 0)
  102. {
  103. delete m_pData->pData;
  104. m_pData->pData = other;
  105. m_pData->ReferenceCount = 1;
  106. }
  107. else
  108. {
  109. Alloc();
  110. m_pData->pData = other;
  111. }
  112. return *this;
  113. }
  114. template<class DATA_T>
  115. void ReferencePtr<DATA_T>::Alloc()
  116. {
  117. m_pData = new ReferencePtrBlock<DATA_T>;
  118. m_pData->ReferenceCount = 1;
  119. m_pData->pData = NULL;
  120. }
  121. template<class DATA_T>
  122. void ReferencePtr<DATA_T>::Release()
  123. {
  124. assert(m_pData != NULL);
  125. if (m_pData->ReferenceCount.dec() <= 0)
  126. {
  127. delete m_pData->pData;
  128. m_pData->pData = NULL;
  129. delete m_pData;
  130. m_pData = NULL;
  131. }
  132. }
  133. #endif // !defined(AFX_ReferencePtr_H__BAEBCE9D_CD68_40AF_8A54_B23A0D14E807__INCLUDED_)