Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

smartptr.h

Go to the documentation of this file.
00001 
00002 //
00003 // Copyright (C) 2000
00004 // Ralf Westram
00005 // (Coded@ReallySoft.de)
00006 //
00007 // Permission to use, copy, modify, distribute and sell this software
00008 // and its documentation for any purpose is hereby granted without fee,
00009 // provided that the above copyright notice appear in all copies and
00010 // that both that copyright notice and this permission notice appear
00011 // in supporting documentation.  Ralf Westram makes no
00012 // representations about the suitability of this software for any
00013 // purpose.  It is provided "as is" without express or implied warranty.
00014 //
00015 // This code is part of my library.
00016 // You may find a more recent version at http://www.reallysoft.de/
00017 //
00019 
00020 #ifndef SMARTPTR_H
00021 #define SMARTPTR_H
00022 
00023 #ifndef RS_ASSERT_H
00024 #include "rs_assert.h"
00025 #endif
00026 
00027 namespace rs {
00028 
00029     // --------------------------------------------------------------------------------
00030     //     SmartPointers
00031     // --------------------------------------------------------------------------------
00032 
00033     template <class T> class SmartPtr;
00034 
00035     // --------------------------------------------------------------------------------
00036     //     class Counted
00037     // --------------------------------------------------------------------------------
00039     template <class T>
00040     class Counted {
00041     private:
00042         unsigned counter;
00043         T *const pointer;
00044 
00045         Counted(T *p) : counter(0), pointer(p) { assert(p); }
00046         ~Counted() { assert(counter==0); delete pointer; }
00047 
00048         unsigned new_reference() {
00049             //cout << "new reference to pointer" << int(pointer) << " (now there are " << counter+1 << " references)" << "\n";
00050             return ++counter;
00051         }
00052         unsigned free_reference() {
00053             //cout << "removing reference to pointer " << int(pointer) << " (now there are " << counter-1 << " references)\n";
00054             assert(counter!=0);
00055             return --counter;
00056         }
00057 
00058         friend class SmartPtr<T>;
00059     };
00060 
00061     template <class T>
00062     // --------------------------------------------------------------------------------
00063     //     class SmartPtr
00064     // --------------------------------------------------------------------------------
00067     class SmartPtr {
00068     private:
00069         Counted<T> *object;
00070 
00071         void Unbind() {
00072             if (object && object->free_reference()==0) delete object;
00073             object = 0;
00074         }
00075     public:
00077         SmartPtr() : object(0) {}
00078 
00087         SmartPtr(T *p) {
00088             object = new Counted<T>(p);
00089             object->new_reference();
00090         }
00091 
00096         ~SmartPtr() {Unbind(); }
00097 
00098         SmartPtr(const SmartPtr<T>& other) {
00099             object = other.object;
00100             if (object) object->new_reference();
00101         }
00102         SmartPtr<T>& operator = (const SmartPtr<T>& other) {
00103             if (other.object) other.object->new_reference();
00104             Unbind();
00105             object = other.object;
00106             return *this;
00107         }
00108 
00109         T *operator->() { assert(object); return object->pointer; }
00110         const T *operator->() const { assert(object); return object->pointer; }
00111 
00112         T& operator*() { assert(object); return *(object->pointer); }
00113         const T& operator*() const { assert(object); return *(object->pointer); }
00114 
00116         bool Null() const { return object==0; }
00117 
00119         void SetNull() { Unbind(); }
00120 
00127         SmartPtr<T> deep_copy() const { return SmartPtr<T>(new T(**this)); }
00128 
00137         bool sameObject(const SmartPtr<T>& other) const {
00138             assert(object);
00139             assert(other.object);
00140             return object==other.object;
00141         }
00142     };
00143 
00144     template <class T> bool operator==(const SmartPtr<T>& s1, const SmartPtr<T>& s2) {
00145         return s1.sameObject(s2);
00146     }
00147 
00148     template <class T> bool operator!=(const SmartPtr<T>& s1, const SmartPtr<T>& s2) {
00149         return !s1.sameObject(s2);
00150     }
00151 
00152 };
00153 
00154 #else
00155 #error smartptr.h included twice
00156 #endif // SMARTPTR_H

Contact me in case of errors or questions.
This documentation is powered by Doxygen.
(C) 2000-2002 Doxygen