home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Header File Name: refcount.h
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 02/03/1997
- // Date Last Modified: 03/15/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ---------- Include File Description and Details ---------- //
- // ----------------------------------------------------------- //
- /*
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- Reference counting is a technique used to ensure the safe
- deletion or modification of an object when a copy of the
- object exists. In order to create reference counted objects,
- a class must inherit the CountedObject class to embed a
- reference count into each object. The RefCount class is used
- to handle pointers to reference counted objects. It works by
- storing pointers to objects in containers, rather than the
- objects themselves.
- */
- // ----------------------------------------------------------- //
- #ifndef __REFCOUNT_HPP__
- #define __REFCOUNT_HPP__
-
- // Reference (C)ounted (O)bject Class
- // Reference counting works by storing a refcount with each object.
- // Each time the object is referenced by some other object or array
- // the counter is incremented. When the entity is finished with the
- // object the counter is decremented. When the counter goes to zero,
- // it means that no entities are referencing the object, so it can
- // be saftly deleted.
- class CountedObject
- // Inherit this class to embed a reference count into each object
- {
- public:
- CountedObject() { refcount = 1; }
- virtual ~CountedObject() { } // Destructor provided for virtuality
-
- public:
- void IncRefCount() { refcount++; }
- void DecRefCount() { refcount--; }
- int UnReferenced() { return refcount == 0; } // Return true if not referenced
- unsigned Count() { return refcount; } // Returns object's refcount
- void Release() { refcount = 0; } // Resets the object's refcount
-
- protected:
- unsigned refcount;
- };
-
- // NOTE: To avoid portability problems with template classes, enable
- // the __NOT_USING_TEMPLATE_CLASS__ macro and directly code this
- // class for the data type that needs to be reference counted.
-
- // Default to using template class
- #ifndef __NOT_USING_TEMPLATE_CLASS__
- #define __USING_TEMPLATE_CLASS__
- #endif
-
- #ifdef __USING_TEMPLATE_CLASS__
- // (R)eference (C)ount class
- // The RefCount class is used to handle reference-counted objects.
- // Reference counted pointers work like normal pointers, except
- // they keep track of the number of references to the objects they
- // point to. To set up a reference counted pointer to an object,
- // allocate and initialize the object on the heap using the new
- // operator, and then pass a pointer to the object in a call to
- // the RefCount constructor.
- template<class TYPE>
- class RefCount
- {
- public:
- RefCount(TYPE *ptr = 0) { ObjectPtr = ptr; }
- ~RefCount() { Unbind(); }
- RefCount(const RefCount<TYPE> &ptr) { // Copy constructor
- // Called when a RefCount pointer is passed by value or copied.
- // Like normal pointers only the ObjectPtr is copied, not the
- // object pointed to by ObjectPtr. The aliasing that ocurrs at
- // this point is recorded by incrementing the reference count.
- Bind(ptr);
- }
-
- void operator=(const RefCount<TYPE> &ptr) {
- // Assignment operator using share semantics.
- // This assignment operator does not allow chain assignments
- NewBinding(ptr);
- }
-
- // int is a dummy parameter used to set the pointer to a NULL
- void operator=(int) { Unbind(); ObjectPtr = 0; }
-
- protected:
- void Bind(const RefCount<TYPE> &ptr);
- void Unbind();
- void NewBinding(const RefCount<TYPE> &ptr);
-
- protected:
- // TYPE assumed to be a structure having IncRefCount(), DecRefCount(),
- // and Referenced() member functions inherited from the CountedObject
- // class.
- TYPE *ObjectPtr;
-
- public:
- // The overloaded * and -> operators allow reference counted pointers
- // to be de-referenced like ordinary pointers.
- TYPE &operator*() const { return *ObjectPtr; }
- TYPE *operator->() const { return ObjectPtr; }
-
- // Used to test whether a RefCount is null
- int operator!() { return ObjectPtr == 0; } // Return true if equal 0
- operator int() { return ObjectPtr != 0; } // Return true if not equal 0
-
- friend int operator==(const RefCount<TYPE> &a, const RefCount<TYPE> &b)
- {
- return a.ObjectPtr == b.ObjectPtr;
- }
-
- friend int operator!=(const RefCount<TYPE> &a, const RefCount<TYPE> &b)
- {
- return a.ObjectPtr != b.ObjectPtr;
- }
- };
-
- template<class TYPE>
- void RefCount<TYPE>::Bind(const RefCount<TYPE> &ptr)
- // Binds object to the same object that ptr is bound to.
- {
- ObjectPtr = ptr.ObjectPtr;
- if (ObjectPtr) ObjectPtr->IncRefCount();
- }
-
- template<class TYPE>
- void RefCount<TYPE>::Unbind()
- {
- // Ensure that ObjectPtr is pointing to an object
- if(ObjectPtr == 0) return;
-
- ObjectPtr->DecRefCount();
- if (ObjectPtr->UnReferenced()) delete ObjectPtr;
- }
-
- template<class TYPE>
- void RefCount<TYPE>::NewBinding(const RefCount<TYPE> &ptr)
- // Gives the reference counted pointer a new binding (the same as ptr)
- {
- if (ObjectPtr != ptr.ObjectPtr) { // Prevents accidental deletion
- Unbind();
- Bind(ptr);
- }
- }
-
- #endif // __USING_TEMPLATE_CLASS__
-
- #endif // __REFCOUNT_HPP__
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-