PtrHolder.h

Go to the documentation of this file.
00001 //# PtrHolder.h: Hold and delete pointers not deleted by object destructors
00002 //# Copyright (C) 1994,1995,1999,2000
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 #ifndef CASA_PTRHOLDER_H
00029 #define CASA_PTRHOLDER_H
00030 
00031 //# Includes
00032 #include <casacore/casa/aips.h>
00033 
00034 
00035 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00036 
00037 // <summary>
00038 // Hold and delete pointers not deleted by object destructors
00039 // </summary>
00040 
00041 // <use visibility=export>
00042 // <reviewed reviewer="troberts" date="1995/07/29" tests="tPtrHolder">
00043 // </reviewed>
00044 
00045 // <prerequisite>
00046 //   <li> module <linkto module=Exceptions>Exceptions</linkto>
00047 // </prerequisite>
00048 
00049 // <synopsis> 
00050 // <src>PtrHolder</src>s hold allocated pointers which should be
00051 // deleted when an exception is thrown. Exceptions only call destructors
00052 // of objects. Thus, for example, storage allocated in a global function
00053 // (outside of an object)is not deleted. A <src>PtrHolder</src> solves
00054 // this problem: it merely holds the pointer and deletes it when it is
00055 // destroyed itself, e.g. when an exception is thrown or when the
00056 // function exits normally.
00057 // </synopsis> 
00058 
00059 // <example>
00060 // <srcblock>
00061 //    void func(Int *ptr); // some other function that takes a pointer
00062 //    // ...
00063 //    // True below means it's an array, False (the default) would mean
00064 //    // a singleton object.
00065 //    PtrHolder<Int> iholder(new Int[10000], True);
00066 //    func(iholder);                           // converts automatically to ptr
00067 //    (iholder.ptr() + 5) = 11;                // use pointer explicitly
00068 //    some_function_that_throws_exception();   // pointer is deleted
00069 // </srcblock>
00070 // </example>
00071 
00072 // <motivation>
00073 // Avoid leaks when throwing/catching exceptions.
00074 // </motivation>
00075 
00076 // <todo asof="2000/04/11">
00077 //   <li> Use the autoptr class from the Standard Library
00078 // </todo>
00079 
00080 
00081 template<class T> class PtrHolder
00082 {
00083 public:
00084     // The default constructor uses a null pointer.
00085     PtrHolder();
00086 
00087     // Construct a <src>PtrHolder</src> from a pointer which MUST have
00088     // been allocated from <src>new</src>, since the destructor will
00089     // call <src>delete</src> on it. If the pointer is to an array,
00090     // i.e. allocated with operator <src>new[]</src>, then
00091     // <src>isCarray</src> should be set to True. (This parameter is
00092     // required because C-arrays need to be deleted with
00093     // <src>delete[]</src>.)
00094     //
00095     // After the pointer is placed into the holder, the user should
00096     // not manually delete the pointer; the <src>PtrHolder</src>
00097     // object will do that, unless <src>set()</src> or
00098     // <src>clear()</src> is called with <src>deleteCurrentPtr</src>
00099     // set to False. The pointer must also only be put into
00100     // <em>one</em> holder to avoid double deletion.
00101     PtrHolder(T *pointer, Bool isCArray = False);
00102 
00103     ~PtrHolder();
00104 
00105     // Set the pointer to a new value. If <src>deleteCurrentPtr </src>is
00106     // True (the default), then delete the existing pointer first. If
00107     // <src>isCarray</src> is True, then the new pointer is assumed to
00108     // have been allocated with <src>new[]</src>.
00109     void set(T *pointer, Bool isCarray = False, Bool deleteCurrentPtr = True);
00110 
00111     // Set the current pointer to null; if <src>deletePtr</src> is True
00112     // (the default), then the current pointer is deleted first.
00113     void clear(Bool deleteCurrentPtr = True);
00114 
00115     // Release the pointer for use.
00116     // <group>
00117     T *ptr() { return ptr_p; }
00118     const T *ptr() const { return ptr_p; }
00119     // </group>
00120 
00121     // Attempt to automatically release a pointer when required. If the
00122     // compiler can't figure it out, you can use the <src>ptr()</src>
00123     // member function directly.
00124     operator T *() { return ptr_p; }
00125     operator T *() const { return ptr_p; }
00126     // </group>
00127 
00128     // Make it possible to use -> on the pointer object.
00129     T* operator->() const
00130       { return ptr_p; }
00131 
00132     // See if the pointer points to a C-array.
00133     Bool isCArray() const {return isCarray_p;}
00134 
00135 private:
00136     //# Undefined and inaccessible
00137     PtrHolder(const PtrHolder<T> &other);
00138     PtrHolder<T> &operator=(const PtrHolder<T> &other);
00139 
00140     //# We'd also like the following to be undefined and inaccessible, 
00141     //# unfortunately CFront doesn't seem to let you do that.
00142     //# void *operator new(size_t s);
00143 
00144     //# Put functionality in one place
00145     void delete_pointer_if_necessary();
00146 
00147     T *ptr_p;
00148     //# If space were critical, we could make isCarray_p a char
00149     Bool isCarray_p;
00150 };
00151 
00152 
00153 
00154 // <summary>
00155 // Hold and delete pointers not deleted by object destructors
00156 // </summary>
00157 
00158 // <use visibility=export>
00159 // <reviewed reviewer="" date="" tests="tPtrHolder">
00160 // </reviewed>
00161 
00162 // <prerequisite>
00163 //   <li> module <linkto module=Exceptions>Exceptions</linkto>
00164 // </prerequisite>
00165 
00166 // <synopsis> 
00167 // <src>SPtrHolder</src>s hold allocated pointers to non-array objects
00168 // which should be deleted when an exception is thrown.
00169 // SPtrHolder is similar to PtrHolder, but easier to use and only valid
00170 // for pointer to a single object, thus not to a C-array of objects.
00171 // </synopsis> 
00172 
00173 // <example>
00174 // <srcblock>
00175 //    void func(Table *ptr); // some other function that takes a pointer
00176 //    // ...
00177 //    // True below means it's an array, False (the default) would mean
00178 //    // a singleton object.
00179 //    SPtrHolder<Int> iholder(new Table(...));
00180 //    func(iholder);                           // converts automatically to ptr
00181 //    Table* tab = iholder.transfer();         // transfer ownership
00182 // </srcblock>
00183 // If an exception is thrown in function <src>func</src>, the Table will be
00184 // deleted automatically. After the function call, the ownership is tranfered
00185 // back to the 'user' 
00186 // </example>
00187 
00188 // <motivation>
00189 // <src>std::auto_ptr</src> is harder to use and its future is unclear.
00190 // <br>
00191 // <src>PtrHolder</src> is not fully inlined and has C-array overhead.
00192 // Furthermore the automatic conversion to a T* is dangerous, because the
00193 // programmer may not be aware that the pointer is maybe taken over.
00194 // </motivation>
00195 
00196 
00197 template<class T> class SPtrHolder
00198 {
00199 public:
00200   // Construct an <src>SPtrHolder</src> from a pointer which MUST have
00201   // been allocated from <src>new</src>, since the destructor will
00202   // After the pointer is placed into the holder, the user should
00203   // not manually delete the pointer unless the transfer function is called.
00204   // The pointer must also only be put into
00205   // <em>one</em> holder to avoid double deletion.
00206   explicit SPtrHolder (T* ptr = 0)
00207     : itsPtr(ptr) {}
00208 
00209   ~SPtrHolder()
00210     { delete itsPtr; }
00211 
00212   // Reset the pointer.
00213   void reset (T* ptr)
00214     { if (ptr != itsPtr) { delete itsPtr; itsPtr = ptr; }}
00215 
00216   // Transfer ownership of the pointer.
00217   // I.e. return the pointer and set it to 0 in the object.
00218   T* transfer()
00219     { T* ptr = itsPtr; itsPtr = 0; return ptr; }
00220 
00221   // Release the pointer.
00222   void release()
00223     { itsPtr = 0; }
00224 
00225   // Make it possible to dereference the pointer object.
00226   // <group>
00227   T& operator*()
00228     { return *itsPtr; }
00229   const T& operator*() const
00230     { return *itsPtr; }
00231   // </group>
00232 
00233   // Make it possible to use -> on the pointer object.
00234   T* operator->() const
00235     { return itsPtr; }
00236 
00237   // Get the pointer for use.
00238   // <group>
00239   T* ptr()
00240     { return itsPtr; }
00241   const T* ptr() const
00242     { return itsPtr; }
00243   // </group>
00244 
00245 private:
00246   // SPrtHolder cannot be copied.
00247   // <group>
00248   SPtrHolder(const SPtrHolder<T> &other);
00249   SPtrHolder<T> &operator=(const SPtrHolder<T> &other);
00250   // </group>
00251 
00252   //# The pointer itself.
00253   T* itsPtr;
00254 };
00255 
00256 
00257 
00258 } //# NAMESPACE CASACORE - END
00259 
00260 #ifndef CASACORE_NO_AUTO_TEMPLATES
00261 #include <casacore/casa/Utilities/PtrHolder.tcc>
00262 #endif //# CASACORE_NO_AUTO_TEMPLATES
00263 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1