/* * smart_ptr.h * elftosb * * Created by Chris Reed on 4/18/06. * Copyright 2006 __MyCompanyName__. All rights reserved. * */ #if !defined(_smart_ptr_h_) #define _smart_ptr_h_ /*! * \brief Simple, standard smart pointer class. * * This class only supports the single-owner paradigm. */ template class smart_ptr { public: typedef T data_type; typedef T * ptr_type; typedef const T * const_ptr_type; typedef T & ref_type; typedef const T & const_ref_type; //! Default constuctor. Initialises with no pointer set. smart_ptr() : _p(0) {} //! This constructor takes a pointer to the object to be deleted. smart_ptr(ptr_type p) : _p(p) {} //! Destructor. If an object (pointer) has been set, it will be deleted. //! Deletes the object using safe_delete(). virtual ~smart_ptr() { safe_delete(); } //! Return the current pointer value. ptr_type get() { return _p; } //! Return the const form of the current pointer value. const_ptr_type get() const { return _p; } //! Change the pointer value, or set if if the default constructor was used. //! If a pointer had previously been associated with the object, and \a p is //! different than that previous pointer, it will be deleted before taking //! ownership of \a p. If this is not desired, call reset() beforehand. void set(ptr_type p) { if (_p && p != _p) { safe_delete(); } _p = p; } //! Dissociates any previously set pointer value without deleting it. void reset() { _p = 0; } //! Dissociates a previously set pointer value, deleting it at the same time. void clear() { safe_delete(); } //! Forces immediate deletion of the object. If you are planning on using //! this method, think about just using a normal pointer. It probably makes //! more sense. virtual void safe_delete() { if (_p) { delete _p; _p = 0; } } //! \name Operators //@{ //! Makes the object transparent as the template type. operator ptr_type () { return _p; } //! Const version of the pointer operator. operator const_ptr_type () const { return _p; } //! Makes the object transparent as a reference of the template type. operator ref_type () { return *_p; } //! Const version of the reference operator. operator const_ref_type () const { return *_p; } //! Returns a boolean indicating whether the object has a pointer set or not. operator bool () const { return _p != 0; } //! To allow setting the pointer directly. Equivalent to a call to set(). smart_ptr & operator = (const_ptr_type p) { set(const_cast(p)); return *this; } //! Another operator to allow you to treat the object just like a pointer. ptr_type operator ->() { return _p; } //! Another operator to allow you to treat the object just like a pointer. const_ptr_type operator ->() const { return _p; } // //! Pointer dereferencing operator. // ref_type operator * () const { return *_p; } // // //! Const version of the pointer dereference operator. // const_ref_type operator * () const { return *_p; } //@} protected: ptr_type _p; //!< The wrapped pointer. }; /*! * \brief Simple, standard smart pointer class that uses the array delete operator. * * This class only supports the single-owner paradigm. * * This is almost entirely a copy of smart_ptr since the final C++ specification * does not allow template subclass members to access members of the parent that * do not depend on the template parameter. */ template class smart_array_ptr { public: typedef T data_type; typedef T * ptr_type; typedef const T * const_ptr_type; typedef T & ref_type; typedef const T & const_ref_type; //! Default constuctor. Initialises with no pointer set. smart_array_ptr() : _p(0) {} //! This constructor takes a pointer to the object to be deleted. smart_array_ptr(ptr_type p) : _p(p) {} //! Destructor. If an array has been set, it will be deleted. //! Deletes the array using safe_delete(). virtual ~smart_array_ptr() { safe_delete(); } //! Return the current pointer value. ptr_type get() { return _p; } //! Return the const form of the current pointer value. const_ptr_type get() const { return _p; } //! Change the pointer value, or set if if the default constructor was used. //! If a pointer had previously been associated with the object, and \a p is //! different than that previous pointer, it will be deleted before taking //! ownership of \a p. If this is not desired, call reset() beforehand. void set(ptr_type p) { if (_p && p != _p) { safe_delete(); } _p = p; } //! Dissociates any previously set pointer value without deleting it. void reset() { _p = 0; } //! Dissociates a previously set pointer value, deleting it at the same time. void clear() { safe_delete(); } //! Forces immediate deletion of the object. If you are planning on using //! this method, think about just using a normal pointer. It probably makes //! more sense. virtual void safe_delete() { if (_p) { delete [] _p; _p = 0; } } //! \name Operators //@{ //! Makes the object transparent as the template type. operator ptr_type () { return _p; } //! Const version of the pointer operator. operator const_ptr_type () const { return _p; } //! Makes the object transparent as a reference of the template type. operator ref_type () { return *_p; } //! Const version of the reference operator. operator const_ref_type () const { return *_p; } //! Returns a boolean indicating whether the object has a pointer set or not. operator bool () const { return _p != 0; } //! To allow setting the pointer directly. Equivalent to a call to set(). smart_array_ptr & operator = (const_ptr_type p) { set(const_cast(p)); return *this; } //! Another operator to allow you to treat the object just like a pointer. ptr_type operator ->() { return _p; } //! Another operator to allow you to treat the object just like a pointer. const_ptr_type operator ->() const { return _p; } //! Indexing operator. ref_type operator [] (unsigned index) { return _p[index]; } //! Indexing operator. const_ref_type operator [] (unsigned index) const { return _p[index]; } // //! Pointer dereferencing operator. // ref_type operator * () const { return *_p; } // // //! Const version of the pointer dereference operator. // const_ref_type operator * () const { return *_p; } //@} protected: ptr_type _p; //!< The wrapped pointer. }; #endif // _smart_ptr_h_