Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ReferenceCounter.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_ReferenceCounter_h_
00003 #define INCLUDED_ReferenceCounter_h_
00004 
00005 #include <iostream>
00006 #include <stdexcept>
00007 
00008 //! Performs simple reference counting, will delete the object when removing the last reference
00009 /*! Remember to call setAutoDelete(false) if you
00010  *  instantiate a subclass on the stack instead of the heap -- don't want to try to free memory
00011  *  on the stack if/when last reference is removed!  (The stack limits the allocation of the behavior
00012  *  to the current scope, so reference counting is moot.)
00013  *
00014  *  @todo It would be nice if there was a way for ReferenceCounter to automatically know whether it
00015  *  has been allocated on the stack... is that possible?
00016  */
00017 class ReferenceCounter {
00018  public:
00019   //! constructor
00020   ReferenceCounter() : references(0),RC_autodelete(true) {}
00021   //! copy constructor - uses autodelete setting of @a rc, but references will still start at 0
00022   ReferenceCounter(const ReferenceCounter& rc) : references(0),RC_autodelete(rc.RC_autodelete) {}
00023   //! assignment operator - does nothing because the reference count shouldn't be copied
00024   ReferenceCounter& operator=(const ReferenceCounter& /*rc*/) {return *this;}
00025 
00026   //! destructor - will std::cout a warning if still has references
00027   virtual ~ReferenceCounter() {
00028     if(references>0)
00029       std::cout << "*** WARNING ReferenceCounter was deleted with " << references << " references" << std::endl;
00030   }
00031 
00032   //! adds one to #references
00033   virtual void addReference() { ++references; }
00034   //! subtracts one from #references AND DELETES the object IF ZERO (and RC_autodelete is set)
00035   /*! @return true if the last reference was removed, false otherwise */
00036   virtual bool removeReference() {
00037     if(--references==0) {
00038       if(RC_autodelete)
00039         delete this;
00040       return true;
00041     } else if(references==(unsigned int)-1) {
00042       //std::cout << "*** WARNING ReferenceCounter went negative" << std::endl;
00043       throw std::underflow_error("ReferenceCounter went negative");
00044     } else
00045       return false;
00046   }
00047   //! returns the number of references
00048   /*! @return references */
00049   virtual unsigned int getReferences() const { return references; }
00050 
00051   //! if true, next time a removeReference() causes #references to hit 0, the object will delete itself
00052   void setAutoDelete(bool b) {RC_autodelete=b;}
00053 
00054   bool getAutoDelete() { return RC_autodelete; } //!< returns RC_autodelete
00055   
00056  protected:
00057   //! the current number of references
00058   unsigned int references;
00059 
00060   //! if false, prevents deletion when counter hits 0 (needed in case of stack allocation or if the subclass is a direct member variable of another class)
00061   bool RC_autodelete;
00062 };
00063 
00064 /*
00065 #include "Behaviors/BehaviorBase.h"
00066 
00067 const char* findname(ReferenceCounter* x) {
00068   BehaviorBase* beh=dynamic_cast<BehaviorBase*>(x);
00069   if(beh==NULL) {
00070     static char s[100];
00071     sprintf(s,"Uknown @ %x",x);
00072     return s;
00073   } else {
00074     static char s2[100];
00075     sprintf(s2," @ %x",x);
00076     return (beh->getName()+s2).c_str();
00077   }
00078 }
00079 
00080 */
00081 
00082 /*! @file
00083  * @brief Defines the ReferenceCounter base class, which allows for automatic memory deallocation
00084  * @author ejt (Creator)
00085  */
00086 
00087 #endif
00088 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:49 2016 by Doxygen 1.6.3