00001 #ifndef OBTSingleton_H_ 00002 #define OBTSingleton_H_ 00003 00004 #include <cstdlib> 00005 #include <stdexcept> 00006 #include "OBT.h" 00007 00008 namespace OBT 00009 { 00024 template< class T > 00025 class Singleton 00026 { 00027 public: 00028 00039 static T& getInstance() ; 00040 00041 private: 00042 00044 static void create() ; 00045 00047 static void onDeadReference() ; 00048 00050 static void destroy() ; 00051 00053 static T* _instance ; 00054 00056 static bool _destroyed ; 00057 00059 static bool _explicitDestruction ; 00060 00062 Singleton() ; 00063 00065 virtual ~Singleton() ; 00066 00068 Singleton( const Singleton& ) ; 00069 00071 Singleton& operator=( const Singleton& ) ; 00072 } ; 00073 00074 //------------------------------------------------------------------------- 00075 // static member variables initialization. 00076 //------------------------------------------------------------------------- 00077 template< class T > T* Singleton<T>::_instance = 0 ; 00078 template< class T > bool Singleton<T>::_destroyed = false ; 00079 template< class T > bool Singleton<T>::_explicitDestruction = false ; 00080 00081 //------------------------------------------------------------------------- 00082 // destructor 00083 //------------------------------------------------------------------------- 00084 template< class T > 00085 Singleton<T>::~Singleton() 00086 { 00087 } 00088 00089 //------------------------------------------------------------------------- 00090 // getInstance 00091 //------------------------------------------------------------------------- 00092 template< class T > 00093 T& 00094 Singleton<T>::getInstance() 00095 { 00096 if ( _instance == NULL ) 00097 { 00098 // checks for dead reference 00099 if ( _destroyed == true ) 00100 { 00101 onDeadReference() ; 00102 } 00103 00104 // create the instance 00105 create() ; 00106 00107 // the destroy method will be called at the application exit 00108 std::atexit( destroy ) ; 00109 } 00110 return *_instance ; 00111 } 00112 00113 //------------------------------------------------------------------------- 00114 // create 00115 //------------------------------------------------------------------------- 00116 template< class T > 00117 void 00118 Singleton<T>::create() 00119 { 00120 // initialise _instance 00121 static T theInstance ; 00122 _instance = &theInstance ; 00123 } 00124 00125 //------------------------------------------------------------------------- 00126 // onDeadReference 00127 //------------------------------------------------------------------------- 00128 template< class T > 00129 void 00130 Singleton<T>::onDeadReference() 00131 { 00132 // obtains the shell of the destroyed singleton 00133 create() ; 00134 // now _instance points to the "ashes" of the singleton 00135 // - the raw memory that the singleton was seated in. 00136 // creates a new singleton at that address 00137 new( _instance ) T ; 00138 // reset _destroyed because we're back in business 00139 _destroyed = false ; 00140 // set _explicitDestruction because the business must be destroyed 00141 // at the application exit 00142 _explicitDestruction = true ; 00143 // the destroy method will be called at the application exit 00144 std::atexit( destroy ) ; 00145 00146 throw std::runtime_error( "Detection of a Singleton Dead Reference" ) ; 00147 } 00148 00149 //------------------------------------------------------------------------- 00150 // destroy 00151 //------------------------------------------------------------------------- 00152 template< class T > 00153 void 00154 Singleton<T>::destroy() 00155 { 00156 if ( _explicitDestruction ) 00157 { 00158 _instance->~T() ; 00159 } 00160 _instance = NULL ; 00161 _destroyed = true ; 00162 } 00163 } 00164 #endif //OBTSingleton_H_