home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / Core Utilities / SmartPtr.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-12  |  3.4 KB  |  207 lines  |  [TEXT/CWIE]

  1. #ifndef __SMARTPTR__
  2. #define __SMARTPTR__
  3. #pragma once
  4.  
  5. #include "Object.h"
  6.  
  7. //----------------------------------------------------------------------------
  8. // ObjectReference - a reference to a reference counted object.
  9. //----------------------------------------------------------------------------
  10.  
  11. template<class T>
  12. class SmartPtr
  13. {
  14. public:
  15.     T* ptr;
  16.  
  17.     inline SmartPtr()                        : ptr(nil)                                            {}
  18.     inline SmartPtr(T* obj)                    : ptr(reinterpret_cast<T*>(NewObjectRef(obj)))        {}
  19.     inline SmartPtr(const SmartPtr<T>& obj)    : ptr(reinterpret_cast<T*>(NewObjectRef(obj.ptr)))    {}
  20.  
  21. //    SmartPtr(const T& obj) const    : ptr(&obj)                 { NewObjectRef(const_cast<TObject*>(&obj)); }
  22. //    SmartPtr(T& obj)                : ptr(&obj)                 { NewObjectRef(&obj); }
  23. //    SmartPtr(const T* obj) const    : ptr(const_cast<T*>(obj))    { NewObjectRef(const_cast<T*>(obj));  }
  24.  
  25. #if    MEMBER_TEMPLATES_SUPPORTED
  26.  
  27.     template<class U>
  28.     inline SmartPtr(SmartPtr<U>& rhs) : ptr(&rhs)              { rhs.NewReference(); }
  29.  
  30. #else
  31.  
  32. //    SmartPtr(TObject* rhs) : ptr(dynamic_cast<T*>(rhs))    { NewObjectRef(ptr); }
  33.  
  34. #endif
  35.  
  36.     ~SmartPtr()
  37.     {
  38.         TObject::DeleteObjectRef(ptr);
  39.     }
  40.     
  41.     operator T*()    { return ptr; }
  42.  
  43. #if MEMBER_TEMPLATES_SUPPORTED
  44.  
  45.     inline SmartPtr<T>& operator=(const SmartPtr<U&> rhs)
  46.     {
  47.         if (this != &rhs)
  48.         {
  49.             ptr = SwapObjectRef(ptr, rhs);
  50.         }
  51.         
  52.         return *this
  53.     }
  54.  
  55. #else
  56.  
  57.     inline SmartPtr<T>& operator=(const SmartPtr<T>& rhs)
  58.     {
  59.         TObject::SwapObjectRef(ptr, rhs.ptr);
  60.  
  61.         ptr = rhs.ptr;
  62.         
  63.         return *this;
  64.     }
  65.  
  66.     inline SmartPtr<T>& operator=(const T* obj)
  67.     {
  68.         TObject::SwapObjectRef(static_cast<const TObject*>(ptr),
  69.                                static_cast<const TObject*>(obj));
  70.         
  71.         ptr = const_cast<T*>(obj);
  72.         
  73.         return *this;
  74.     }
  75.  
  76. /*
  77.     SmartPtr<T>& operator=(TObject* param)
  78.     {
  79.         T* obj = dynamic_cast<T*>(param);
  80.  
  81.         if (ptr != obj)
  82.         {
  83.             SwapObjectRef(ptr, obj);
  84.             ptr = obj;
  85.         }
  86.         
  87.         return *this;
  88.     }
  89. */
  90.  
  91. #endif
  92.  
  93.     inline bool operator==(const T* obj) const
  94.     {
  95.         return ptr == obj;
  96.     }
  97.  
  98.     inline bool operator==(const SmartPtr<T>& obj) const
  99.     {
  100.         return ptr == obj.ptr;
  101.     }
  102.  
  103.     inline bool operator!=(const T* obj) const
  104.     {
  105.         return ptr != obj;
  106.     }
  107.  
  108.     inline bool operator!=(const SmartPtr<T>& obj) const
  109.     {
  110.         return ptr != obj.ptr;
  111.     }
  112.  
  113.      // Named helpers for out operators for when C++ is stupid
  114.  
  115.     inline void SetToNull()
  116.     {
  117.         TObject::DeleteObjectRef(ptr);
  118.         ptr = nil;
  119.     }
  120.         
  121.     inline bool IsNull() const
  122.     {
  123.         return ptr == nil;
  124.     }
  125.         
  126.     inline const T* Dereference() const
  127.     {
  128.         if (ptr == nil)
  129.         {
  130.             TObject::NilObjectReference();
  131.         }
  132.  
  133. #if qDebug
  134.         if (ptr->GetReferenceCount() == 0)
  135.             Warning("Zero reference count in dereferenced object");
  136. #endif            
  137.         return ptr;
  138.     }
  139.  
  140.     inline T* Dereference()
  141.     {
  142.         if (ptr == nil)
  143.         {
  144.             TObject::NilObjectReference();
  145.         }
  146.  
  147. #if qDebug
  148.         if (ptr->GetReferenceCount() == 0)
  149.             Warning("Zero reference count in dereferenced object");
  150. #endif            
  151.         return ptr;
  152.     }
  153.  
  154.     inline T* GetPtr() const
  155.     {
  156.         return const_cast<T*>(ptr);
  157.     }
  158.  
  159.     inline const T& operator*() const
  160.     {
  161.         return *Dereference();
  162.     }
  163.  
  164.     inline T& operator*()
  165.     {
  166.         return *Dereference();
  167.     }
  168.  
  169.     inline const T* operator->() const
  170.     {
  171.         return Dereference();
  172.     }
  173.  
  174.     inline T* operator->()
  175.     {
  176.         return Dereference();
  177.     }
  178.  
  179.     inline operator bool() const
  180.     {
  181.         return !IsNull();
  182.     }
  183.     
  184.     inline bool operator!() const
  185.     {
  186.         return IsNull();
  187.     }
  188. };
  189.  
  190. template<class T, class U>
  191.     SmartPtr<T>& operator=(SmartPtr<U&> rhs)
  192.     {
  193.         if (ptr != &rhs.ptr)
  194.         {
  195.             ptr = SwapObjectRef(ptr, rhs);
  196.         }
  197.         
  198.         return *this
  199.     }
  200.  
  201. typedef SmartPtr<const TObject>        ConstObjectPtr;
  202. typedef SmartPtr<TObject>             ObjectPtr;
  203.  
  204.  
  205. #endif __SMARTPTR__
  206.  
  207.