![]() |
![]() |
00001 #ifndef GUARD_Ptr_h 00002 #define GUARD_Ptr_h 00003 00004 #include <stdexcept> 00005 #include <cstddef> 00006 // #include <iostream> 00007 #include <utility> 00008 00009 template<class T> class Ptr { 00010 public: 00011 // new member to copy the object conditionally when needed 00012 void make_unique() { 00013 if (*refptr != 1) { 00014 --*refptr; 00015 refptr = new size_t(1); 00016 p = p? clone(p): 0; 00017 } 00018 } 00019 00020 // the rest of the class looks like `Ref_handle' except for its name 00021 Ptr(): p(0), refptr(new size_t(1)) { } 00022 Ptr(T* t): p(t), refptr(new size_t(1)) { } 00023 Ptr(const Ptr& h): p(h.p), refptr(h.refptr) { ++*refptr; } 00024 00025 Ptr& operator=(const Ptr&); // implemented analogously to 14.2/261 00026 ~Ptr(); // implemented analogously to 14.2/262 00027 operator bool() const { return p; } 00028 T& operator*() const; // implemented analogously to 14.2/261 00029 T* operator->() const; // implemented analogously to 14.2/261 00030 00031 //FIXME: Ptr::operator==()is this good design? 00032 bool operator==( const Ptr<T> P) const { return p==P.p; } 00033 00034 //FIXME: Ptr::operator<()is this good design? 00035 bool operator<( const Ptr<T> P) const { return p<P.p; } 00036 00037 private: 00038 T* p; 00039 std::size_t* refptr; 00040 }; 00041 00042 template<class T> T* clone(const T* tp) 00043 { 00044 return tclone(tp); 00045 } 00046 00047 00048 00049 template<class T> 00050 T& Ptr<T>::operator*() const { if (p) return *p; throw std::runtime_error("unbound Ptr"); } 00051 00052 template<class T> 00053 T* Ptr<T>::operator->() const { if (p) return p; throw std::runtime_error("unbound Ptr"); } 00054 00055 00056 template<class T> 00057 Ptr<T>& Ptr<T>::operator=(const Ptr& rhs) 00058 { 00059 ++*rhs.refptr; 00060 // free the lhs, destroying pointers if appropriate 00061 if (--*refptr == 0) { 00062 delete refptr; 00063 delete p; 00064 } 00065 00066 // copy in values from the right-hand side 00067 refptr = rhs.refptr; 00068 p = rhs.p; 00069 return *this; 00070 } 00071 00072 template<class T> Ptr<T>::~Ptr() 00073 { 00074 if (--*refptr == 0) { 00075 delete refptr; 00076 /* 00077 if (p) 00078 std::cout << "DC:\t\tPtr deleted: " << std::endl; 00079 else 00080 std::cout << "DC: \t\tPtr deleted: dangling" << std::endl; 00081 delete p; 00082 */ 00083 } 00084 } 00085 00086 00087 #endif