1*b3979f3aSjkunz /* 2*b3979f3aSjkunz * smart_ptr.h 3*b3979f3aSjkunz * elftosb 4*b3979f3aSjkunz * 5*b3979f3aSjkunz * Created by Chris Reed on 4/18/06. 6*b3979f3aSjkunz * Copyright 2006 __MyCompanyName__. All rights reserved. 7*b3979f3aSjkunz * 8*b3979f3aSjkunz */ 9*b3979f3aSjkunz #if !defined(_smart_ptr_h_) 10*b3979f3aSjkunz #define _smart_ptr_h_ 11*b3979f3aSjkunz 12*b3979f3aSjkunz /*! 13*b3979f3aSjkunz * \brief Simple, standard smart pointer class. 14*b3979f3aSjkunz * 15*b3979f3aSjkunz * This class only supports the single-owner paradigm. 16*b3979f3aSjkunz */ 17*b3979f3aSjkunz template <typename T> 18*b3979f3aSjkunz class smart_ptr 19*b3979f3aSjkunz { 20*b3979f3aSjkunz public: 21*b3979f3aSjkunz typedef T data_type; 22*b3979f3aSjkunz typedef T * ptr_type; 23*b3979f3aSjkunz typedef const T * const_ptr_type; 24*b3979f3aSjkunz typedef T & ref_type; 25*b3979f3aSjkunz typedef const T & const_ref_type; 26*b3979f3aSjkunz 27*b3979f3aSjkunz //! Default constuctor. Initialises with no pointer set. smart_ptr()28*b3979f3aSjkunz smart_ptr() : _p(0) {} 29*b3979f3aSjkunz 30*b3979f3aSjkunz //! This constructor takes a pointer to the object to be deleted. smart_ptr(ptr_type p)31*b3979f3aSjkunz smart_ptr(ptr_type p) : _p(p) {} 32*b3979f3aSjkunz 33*b3979f3aSjkunz //! Destructor. If an object (pointer) has been set, it will be deleted. 34*b3979f3aSjkunz //! Deletes the object using safe_delete(). ~smart_ptr()35*b3979f3aSjkunz virtual ~smart_ptr() { safe_delete(); } 36*b3979f3aSjkunz 37*b3979f3aSjkunz //! Return the current pointer value. get()38*b3979f3aSjkunz ptr_type get() { return _p; } 39*b3979f3aSjkunz 40*b3979f3aSjkunz //! Return the const form of the current pointer value. get()41*b3979f3aSjkunz const_ptr_type get() const { return _p; } 42*b3979f3aSjkunz 43*b3979f3aSjkunz //! Change the pointer value, or set if if the default constructor was used. 44*b3979f3aSjkunz //! If a pointer had previously been associated with the object, and \a p is 45*b3979f3aSjkunz //! different than that previous pointer, it will be deleted before taking 46*b3979f3aSjkunz //! ownership of \a p. If this is not desired, call reset() beforehand. set(ptr_type p)47*b3979f3aSjkunz void set(ptr_type p) 48*b3979f3aSjkunz { 49*b3979f3aSjkunz if (_p && p != _p) 50*b3979f3aSjkunz { 51*b3979f3aSjkunz safe_delete(); 52*b3979f3aSjkunz } 53*b3979f3aSjkunz _p = p; 54*b3979f3aSjkunz } 55*b3979f3aSjkunz 56*b3979f3aSjkunz //! Dissociates any previously set pointer value without deleting it. reset()57*b3979f3aSjkunz void reset() { _p = 0; } 58*b3979f3aSjkunz 59*b3979f3aSjkunz //! Dissociates a previously set pointer value, deleting it at the same time. clear()60*b3979f3aSjkunz void clear() { safe_delete(); } 61*b3979f3aSjkunz 62*b3979f3aSjkunz //! Forces immediate deletion of the object. If you are planning on using 63*b3979f3aSjkunz //! this method, think about just using a normal pointer. It probably makes 64*b3979f3aSjkunz //! more sense. safe_delete()65*b3979f3aSjkunz virtual void safe_delete() 66*b3979f3aSjkunz { 67*b3979f3aSjkunz if (_p) 68*b3979f3aSjkunz { 69*b3979f3aSjkunz delete _p; 70*b3979f3aSjkunz _p = 0; 71*b3979f3aSjkunz } 72*b3979f3aSjkunz } 73*b3979f3aSjkunz 74*b3979f3aSjkunz //! \name Operators 75*b3979f3aSjkunz //@{ 76*b3979f3aSjkunz 77*b3979f3aSjkunz //! Makes the object transparent as the template type. ptr_type()78*b3979f3aSjkunz operator ptr_type () { return _p; } 79*b3979f3aSjkunz 80*b3979f3aSjkunz //! Const version of the pointer operator. const_ptr_type()81*b3979f3aSjkunz operator const_ptr_type () const { return _p; } 82*b3979f3aSjkunz 83*b3979f3aSjkunz //! Makes the object transparent as a reference of the template type. ref_type()84*b3979f3aSjkunz operator ref_type () { return *_p; } 85*b3979f3aSjkunz 86*b3979f3aSjkunz //! Const version of the reference operator. const_ref_type()87*b3979f3aSjkunz operator const_ref_type () const { return *_p; } 88*b3979f3aSjkunz 89*b3979f3aSjkunz //! Returns a boolean indicating whether the object has a pointer set or not. 90*b3979f3aSjkunz operator bool () const { return _p != 0; } 91*b3979f3aSjkunz 92*b3979f3aSjkunz //! To allow setting the pointer directly. Equivalent to a call to set(). 93*b3979f3aSjkunz smart_ptr<T> & operator = (const_ptr_type p) 94*b3979f3aSjkunz { 95*b3979f3aSjkunz set(const_cast<ptr_type>(p)); 96*b3979f3aSjkunz return *this; 97*b3979f3aSjkunz } 98*b3979f3aSjkunz 99*b3979f3aSjkunz //! Another operator to allow you to treat the object just like a pointer. 100*b3979f3aSjkunz ptr_type operator ->() { return _p; } 101*b3979f3aSjkunz 102*b3979f3aSjkunz //! Another operator to allow you to treat the object just like a pointer. 103*b3979f3aSjkunz const_ptr_type operator ->() const { return _p; } 104*b3979f3aSjkunz 105*b3979f3aSjkunz // //! Pointer dereferencing operator. 106*b3979f3aSjkunz // ref_type operator * () const { return *_p; } 107*b3979f3aSjkunz // 108*b3979f3aSjkunz // //! Const version of the pointer dereference operator. 109*b3979f3aSjkunz // const_ref_type operator * () const { return *_p; } 110*b3979f3aSjkunz 111*b3979f3aSjkunz //@} 112*b3979f3aSjkunz 113*b3979f3aSjkunz protected: 114*b3979f3aSjkunz ptr_type _p; //!< The wrapped pointer. 115*b3979f3aSjkunz }; 116*b3979f3aSjkunz 117*b3979f3aSjkunz /*! 118*b3979f3aSjkunz * \brief Simple, standard smart pointer class that uses the array delete operator. 119*b3979f3aSjkunz * 120*b3979f3aSjkunz * This class only supports the single-owner paradigm. 121*b3979f3aSjkunz * 122*b3979f3aSjkunz * This is almost entirely a copy of smart_ptr since the final C++ specification 123*b3979f3aSjkunz * does not allow template subclass members to access members of the parent that 124*b3979f3aSjkunz * do not depend on the template parameter. 125*b3979f3aSjkunz */ 126*b3979f3aSjkunz template <typename T> 127*b3979f3aSjkunz class smart_array_ptr 128*b3979f3aSjkunz { 129*b3979f3aSjkunz public: 130*b3979f3aSjkunz typedef T data_type; 131*b3979f3aSjkunz typedef T * ptr_type; 132*b3979f3aSjkunz typedef const T * const_ptr_type; 133*b3979f3aSjkunz typedef T & ref_type; 134*b3979f3aSjkunz typedef const T & const_ref_type; 135*b3979f3aSjkunz 136*b3979f3aSjkunz //! Default constuctor. Initialises with no pointer set. smart_array_ptr()137*b3979f3aSjkunz smart_array_ptr() : _p(0) {} 138*b3979f3aSjkunz 139*b3979f3aSjkunz //! This constructor takes a pointer to the object to be deleted. smart_array_ptr(ptr_type p)140*b3979f3aSjkunz smart_array_ptr(ptr_type p) : _p(p) {} 141*b3979f3aSjkunz 142*b3979f3aSjkunz //! Destructor. If an array has been set, it will be deleted. 143*b3979f3aSjkunz //! Deletes the array using safe_delete(). ~smart_array_ptr()144*b3979f3aSjkunz virtual ~smart_array_ptr() { safe_delete(); } 145*b3979f3aSjkunz 146*b3979f3aSjkunz //! Return the current pointer value. get()147*b3979f3aSjkunz ptr_type get() { return _p; } 148*b3979f3aSjkunz 149*b3979f3aSjkunz //! Return the const form of the current pointer value. get()150*b3979f3aSjkunz const_ptr_type get() const { return _p; } 151*b3979f3aSjkunz 152*b3979f3aSjkunz //! Change the pointer value, or set if if the default constructor was used. 153*b3979f3aSjkunz //! If a pointer had previously been associated with the object, and \a p is 154*b3979f3aSjkunz //! different than that previous pointer, it will be deleted before taking 155*b3979f3aSjkunz //! ownership of \a p. If this is not desired, call reset() beforehand. set(ptr_type p)156*b3979f3aSjkunz void set(ptr_type p) 157*b3979f3aSjkunz { 158*b3979f3aSjkunz if (_p && p != _p) 159*b3979f3aSjkunz { 160*b3979f3aSjkunz safe_delete(); 161*b3979f3aSjkunz } 162*b3979f3aSjkunz _p = p; 163*b3979f3aSjkunz } 164*b3979f3aSjkunz 165*b3979f3aSjkunz //! Dissociates any previously set pointer value without deleting it. reset()166*b3979f3aSjkunz void reset() { _p = 0; } 167*b3979f3aSjkunz 168*b3979f3aSjkunz //! Dissociates a previously set pointer value, deleting it at the same time. clear()169*b3979f3aSjkunz void clear() { safe_delete(); } 170*b3979f3aSjkunz 171*b3979f3aSjkunz //! Forces immediate deletion of the object. If you are planning on using 172*b3979f3aSjkunz //! this method, think about just using a normal pointer. It probably makes 173*b3979f3aSjkunz //! more sense. safe_delete()174*b3979f3aSjkunz virtual void safe_delete() 175*b3979f3aSjkunz { 176*b3979f3aSjkunz if (_p) 177*b3979f3aSjkunz { 178*b3979f3aSjkunz delete [] _p; 179*b3979f3aSjkunz _p = 0; 180*b3979f3aSjkunz } 181*b3979f3aSjkunz } 182*b3979f3aSjkunz 183*b3979f3aSjkunz //! \name Operators 184*b3979f3aSjkunz //@{ 185*b3979f3aSjkunz 186*b3979f3aSjkunz //! Makes the object transparent as the template type. ptr_type()187*b3979f3aSjkunz operator ptr_type () { return _p; } 188*b3979f3aSjkunz 189*b3979f3aSjkunz //! Const version of the pointer operator. const_ptr_type()190*b3979f3aSjkunz operator const_ptr_type () const { return _p; } 191*b3979f3aSjkunz 192*b3979f3aSjkunz //! Makes the object transparent as a reference of the template type. ref_type()193*b3979f3aSjkunz operator ref_type () { return *_p; } 194*b3979f3aSjkunz 195*b3979f3aSjkunz //! Const version of the reference operator. const_ref_type()196*b3979f3aSjkunz operator const_ref_type () const { return *_p; } 197*b3979f3aSjkunz 198*b3979f3aSjkunz //! Returns a boolean indicating whether the object has a pointer set or not. 199*b3979f3aSjkunz operator bool () const { return _p != 0; } 200*b3979f3aSjkunz 201*b3979f3aSjkunz //! To allow setting the pointer directly. Equivalent to a call to set(). 202*b3979f3aSjkunz smart_array_ptr<T> & operator = (const_ptr_type p) 203*b3979f3aSjkunz { 204*b3979f3aSjkunz set(const_cast<ptr_type>(p)); 205*b3979f3aSjkunz return *this; 206*b3979f3aSjkunz } 207*b3979f3aSjkunz 208*b3979f3aSjkunz //! Another operator to allow you to treat the object just like a pointer. 209*b3979f3aSjkunz ptr_type operator ->() { return _p; } 210*b3979f3aSjkunz 211*b3979f3aSjkunz //! Another operator to allow you to treat the object just like a pointer. 212*b3979f3aSjkunz const_ptr_type operator ->() const { return _p; } 213*b3979f3aSjkunz 214*b3979f3aSjkunz //! Indexing operator. 215*b3979f3aSjkunz ref_type operator [] (unsigned index) { return _p[index]; } 216*b3979f3aSjkunz 217*b3979f3aSjkunz //! Indexing operator. 218*b3979f3aSjkunz const_ref_type operator [] (unsigned index) const { return _p[index]; } 219*b3979f3aSjkunz 220*b3979f3aSjkunz // //! Pointer dereferencing operator. 221*b3979f3aSjkunz // ref_type operator * () const { return *_p; } 222*b3979f3aSjkunz // 223*b3979f3aSjkunz // //! Const version of the pointer dereference operator. 224*b3979f3aSjkunz // const_ref_type operator * () const { return *_p; } 225*b3979f3aSjkunz 226*b3979f3aSjkunz //@} 227*b3979f3aSjkunz 228*b3979f3aSjkunz protected: 229*b3979f3aSjkunz ptr_type _p; //!< The wrapped pointer. 230*b3979f3aSjkunz }; 231*b3979f3aSjkunz 232*b3979f3aSjkunz #endif // _smart_ptr_h_ 233