RefCount.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:6k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /*
  2. This is reference-counting code that I originally found in sample source
  3. code distributed by SGI (/usr/share/src/dmedia/video/O2/lib/RefCount.{c++,h}).
  4. As opposed to much of the other source code, it had no copyright statement.
  5.  -- SMR
  6.     Fri Mar 12 06:27:39 CET 1999
  7. */
  8. ////////////////////////////////////////////////////////////////////////
  9. //
  10. // File: RefCount.h
  11. //
  12. ////////////////////////////////////////////////////////////////////////
  13. #ifndef _REF_COUNT_H
  14. #define _REF_COUNT_H
  15. #include <assert.h>
  16. #ifndef NULL
  17. #define NULL 0
  18. #endif
  19. ////////////////////////////////////////////////////////////////////////
  20. //
  21. // RefCount class
  22. //
  23. // This is a base class that should be inherited by all classes that
  24. // are reference counted.
  25. //
  26. // When the LEAK_TEST variable is set, any ref-counted objects which
  27. // are not deleted when a program exits will report memory leaks.
  28. // This is implemented as a crude hack: when an object is created, at
  29. // allocates one word of memory and then disguises the pointer so that
  30. // it looks like a leak.  When the object is freed, it frees the
  31. // memory.
  32. //
  33. //
  34. ////////////////////////////////////////////////////////////////////////
  35. // #define LEAK_TEST
  36. class RefCount
  37. {
  38. public:
  39.     //
  40.     // The constructor just needs to initialize the reference count
  41.     // on the object.
  42.     //
  43.     RefCount()
  44. {
  45.     myRefCount = 0;
  46. #ifdef LEAK_TEST
  47.     int* leak = new int;
  48.     myLeak = ~ long(leak);
  49. #endif
  50. }
  51.     //
  52.     // Every base class needs a virtual destructor.
  53.     //
  54.     virtual ~RefCount();
  55.     //
  56.     // Reference counting stuff.
  57.     // It should only be called from within the Ref
  58.     // class.  Compiler didn't like:
  59.     //     template <class Target> friend class Ref;
  60.     //
  61.     
  62.     void incRefCount();
  63.     void decRefCount();
  64. private:
  65.     int myRefCount;
  66. #ifdef LEAK_TEST
  67.     long myLeak;
  68. #endif
  69. };
  70. ////////////////////////////////////////////////////////////////////////
  71. //
  72. // Ref class
  73. //
  74. // This is a reference to an object that maintains a reference count.
  75. // The target class must be derived from RefCount.
  76. //
  77. // To use Refs, first make a class that derives from RefCount, like
  78. // this: 
  79. //
  80. // class Foo : public RefCount
  81. //  {
  82. //  public:
  83. //      Foo();
  84. //      ~Foo();
  85. //     void doSomething();
  86. //  };
  87. //
  88. // Any pointer to a Foo that represents ownership should use a Ref,
  89. // which will increment the reference count as long as the pointer
  90. // exists, and then decrement the reference count when the pointer
  91. // goes away.  For example:
  92. //
  93. // {
  94. //     Ref<Foo> myPtr = new Foo();
  95. //     myPtr->doSomething();
  96. // }
  97. //
  98. // When my pointer goes out of scope at the end of this block, the
  99. // object will be deleted because there are no other references to it.
  100. //
  101. // References to a Foo from other classes should also use a Ref:
  102. //
  103. // class Bar
  104. // {
  105. // public:
  106. //     Bar() { myFoo = new Foo(); }
  107. // private:
  108. //     Ref<Foo> myFoo;
  109. // };
  110. //
  111. // When an instance of the class Bar is deleted, the reference count
  112. // on myFoo will be decremented, and the object freed if it is the
  113. // last reference.
  114. //
  115. // When to use pointers and when to use Ref:
  116. //
  117. // 1) Use a Ref for class members (as in Bar, above).
  118. //
  119. // 2) Use a Ref for local variables. (Although it's safe to use a
  120. //    pointer if you know that somebody else has a referenc to the
  121. //    object, it's probably worth the cost to use a Ref.)
  122. //
  123. // 3) Use pointers in arguments to functions.  It's more efficient.
  124. //    The caller must keep a reference for the duration of the call.
  125. //    This means that you should not pass a newly created object as an
  126. //    argument to a function; instead do the following:
  127. //
  128. // {
  129. //     extern void aFunction( Foo* );
  130. //     Ref<Foo> x = new Foo();
  131. //     aFunction( x );
  132. // }
  133. //
  134. // 4) Return a Ref from a function when you are returning ownership of
  135. //    the object, or if you *might* be returning ownership.
  136. //
  137. // 5) Return a pointer from a function when you are not returning
  138. //    ownership.
  139. //
  140. ////////////////////////////////////////////////////////////////////////
  141. template <class Target>
  142. class Ref
  143. {
  144. public:
  145.     //
  146.     // Be default, we point to NULL.
  147.     //
  148.     Ref()
  149. {
  150.     myTarget = NULL;
  151. }
  152.     //
  153.     // These two constructors just acquire ownership of an object by
  154.     // bumping its reference count.  (incRefCount() and decRefCount()
  155.     // handle the case when the pointer is NULL.)
  156.     //
  157.     Ref( Target* target )
  158. {
  159.     target->incRefCount();
  160.     myTarget = target;
  161. }
  162.     Ref( const Ref& other )
  163. {
  164.     other.myTarget->incRefCount();
  165.     myTarget = other.myTarget;
  166. }
  167.     //
  168.     // Destroying this reference object drops the reference count.
  169.     //
  170.     ~Ref()
  171. {
  172.     myTarget->decRefCount();
  173. }
  174.     //
  175.     // A function for those rare cases when -> or casting is not right.
  176.     //
  177.     
  178.     Target* getTarget() 
  179. {
  180.     return myTarget;
  181. }
  182.     //
  183.     // Assignment adds a reference.  (The reference to the object we
  184.     // used to have must be decremented second, to handle assignment
  185.     // to self.)
  186.     //
  187.     Ref& operator =( const Ref& other )
  188. {
  189.     other.myTarget->incRefCount();
  190.     myTarget->decRefCount();
  191.     this->myTarget = other.myTarget;
  192.     return *this;
  193. }
  194.     Ref& operator =( Target* target )
  195. {
  196.     target->incRefCount();
  197.     myTarget->decRefCount();
  198.     this->myTarget = target;
  199.     return *this;
  200. }
  201.     //
  202.     // We can cast to a Target*.  This is used when calling a function
  203.     // that takes a Target*.
  204.     //
  205.     operator Target* () const
  206. {
  207.     return myTarget;
  208. }
  209.     //
  210.     // Overloading "->" allows a Ref to be used just like a pointer.
  211.     //
  212.     Target* operator ->() const
  213. {
  214.     return myTarget;
  215. }
  216. private:
  217.     //
  218.     // This is the pointer to the object we are managing.
  219.     //
  220.     Target* myTarget;
  221. };
  222. #endif // _REF_COUNT_H