Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

SmartPtr.h

Go to the documentation of this file.
00001 /*
00002  * Dibbler - a portable DHCPv6
00003  *
00004  * authors: Tomasz Mrugalski <thomson@klub.com.pl>
00005  *          Marek Senderski <msend@o2.pl>
00006  *
00007  * $Id: SmartPtr.h,v 1.4 2004/06/04 19:47:06 thomson Exp $
00008  *
00009  * $Log: SmartPtr.h,v $
00010  * Revision 1.4  2004/06/04 19:47:06  thomson
00011  * Various fixes.
00012  *
00013  * Revision 1.3  2004/06/04 16:55:27  thomson
00014  * *** empty log message ***
00015  *
00016  * Revision 1.2  2004/03/29 22:06:49  thomson
00017  * 0.1.1 version
00018  *
00019  *
00020  * Released under GNU GPL v2 licence
00021  *
00022  */
00023 
00024 #ifndef SMARTPTR_H
00025 #define SMARTPTR_H
00026 
00027 #include <iostream>
00028 
00029 class Ptr {
00030 public:
00031         //constructor used in case of NULL SmartPtr
00032         Ptr() {
00033                 ptr=NULL;
00034                 refcount=1;
00035         }
00036         //Constructor used in case of non NULL SmartPtr
00037         Ptr(void* sth) {
00038             ptr=sth;
00039             refcount=1;
00040         }
00041 
00042         ~Ptr() {
00043             //if(ptr) delete ptr;
00044         }
00045         int refcount; //refrence counter
00046         void * ptr;       //pointer to the real object
00047 };
00048 
00049 template <class T>
00050 class SmartPtr
00051 {
00052 
00053         //Don't use this class alone, it's used only in casting 
00054         //one smartpointer to another smartpointer 
00055         //e.g.
00056         //SmartPtr<a> a(new a()); SmartPtr<b> b(new(b)); a=b;
00057 
00058 public:
00059     SmartPtr();
00060     SmartPtr(T* something);
00061         SmartPtr(Ptr *voidptr) { 
00062         if(voidptr) 
00063         {
00064             this->ptr=voidptr; 
00065             this->ptr->refcount++;
00066         }
00067         else
00068             this->ptr=new Ptr();
00069     }
00070     SmartPtr(const SmartPtr & ref);
00071         SmartPtr(int onlyNull);
00072         SmartPtr& operator=(const SmartPtr& old);
00073 
00074         operator Ptr*() {if (this->ptr->ptr) 
00075                                                 return this->ptr;
00076                                         else
00077                                                 return (Ptr*)NULL;
00078                                         }
00079         //operator int() {return ptr->ptr?1:NULL;};
00080 
00081     //bool operator==(SmartPtr& right);
00082     //SmartPtr& operator=(const SmartPtr& old);
00083     ~SmartPtr();
00084     T& operator*() const;
00085     T* operator->() const;
00086 
00087  private:
00088     Ptr * ptr;
00089 };
00090 
00091 template <class T>
00092 
00093 SmartPtr<T>::SmartPtr() {
00094     ptr = new Ptr();
00095 }
00096 
00097 template <class T>
00098 SmartPtr<T>::SmartPtr(T* something) {
00099     ptr = new Ptr(something);
00100 }
00101 
00102 template <class T>
00103 SmartPtr<T>::SmartPtr(const SmartPtr& old) {
00104         old.ptr->refcount++;
00105         this->ptr = old.ptr;
00106     this->ptr->refcount=old.ptr->refcount;
00107 }
00108 
00109 template <class T>
00110 SmartPtr<T>::~SmartPtr() {
00111     if (!(--(ptr->refcount))) {
00112         delete (T*)(ptr->ptr);
00113         delete ptr;
00114     }
00115 }
00116 
00117 template <class T>
00118 T& SmartPtr<T>::operator*() const {
00119     return *((T*)(ptr->ptr)); //it can return NULL
00120 }
00121 
00122 template <class T>
00123 T* SmartPtr<T>::operator->() const {
00124     if (!ptr) {
00125         return 0;
00126     }
00127     return (T*)(ptr->ptr); //it can return NULL
00128 }
00129 
00130 //It's is called in eg. instrusction: return NULL;
00131 //and SmartPtr is returned in function
00132 template <class T>
00133 SmartPtr<T>::SmartPtr(int )
00134 {
00135         ptr=new Ptr(); //this->ptr->ptr is NULL
00136 }
00137 
00138 template <class T>
00139 SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr& old) {
00140         if (this==&old)
00141                 return *this;
00142         if (this->ptr) 
00143                 if(!(--this->ptr->refcount))
00144                 {
00145                     delete (T*)(this->ptr->ptr);
00146                     delete this->ptr;
00147                     this->ptr=NULL;
00148                 }
00149                 this->ptr=old.ptr;
00150                 old.ptr->refcount++;
00151                 //    cout << "operator=" << endl;
00152                 return *this;
00153 }
00154 #endif
00155 

Generated on Wed Mar 16 00:10:26 2005 for Dibbler - a portable DHCPv6 by  doxygen 1.3.9.1