00001 #ifndef NO_PTR_DELETER_H 00002 #define NO_PTR_DELETER_H 00003 00023 namespace NoPtr 00024 { 00025 namespace NoPtrImpl 00026 { 00027 00028 /* Used by DynObj and DynTmp so that ObjType gets deleted in 00029 code section where complete definition is visible. This 00030 allows them to support declaring OjbType without a full 00031 definition, and support the e.g. the pimpl idioim. 00032 00033 The only necessary design aspect of this class is that 00034 the function pointer for the deleter function must be 00035 created only in the constructor of the class. Indeed, 00036 this is the requirement for the pimpl idiom: the constructor 00037 must be defined in the source file, at which place the 00038 full definition of ObjType is visible, hence the delete works. 00039 Here, we use a static variable and a static function that gets 00040 called only once to minimize the impact of this feature on the 00041 creation time for DynObj and DynTmp. 00042 */ 00043 template <typename ObjType> 00044 class Deleter 00045 { 00046 protected: 00047 // just set the pointer to deleter once in whole program run 00048 Deleter() { static const bool inited = initStatic(); } 00049 // call the deleter on \a ptr 00050 static void destroy(ObjType* ptr) { (*_deleteObj)(ptr); } 00051 00052 private: 00053 // init the static pointer to deleter function 00054 static bool initStatic() 00055 { 00056 _deleteObj = &Deleter<ObjType>::callDelete; 00057 return true; 00058 } 00059 00060 // method to call delete operator to support pimpl 00061 static inline void callDelete(ObjType* ptr) {delete ptr;} 00062 00063 // typedef for function 00064 typedef void (*DeleteFn)(ObjType*); 00065 // the pointer to the function to use for deletion 00066 static DeleteFn _deleteObj; 00067 }; 00068 00069 // Fundamental type, so safe use even from inline 00070 template <typename ObjType> 00071 typename Deleter<ObjType>::DeleteFn Deleter<ObjType>::_deleteObj; 00072 00073 } // implementation namespace 00074 00075 } 00076 00077 #endif // NO_PTR_DELETER_H