00001 00002 // Name: singleton.h 00003 // Class: Singleton 00004 // $Revision: 1.1 $ 00005 // $Modtime: 6/02/99 7:14p $ 00006 // Description: Used to make any class a Singleton. 00007 // Usage: Used to make any class into a Singleton. A normal class 00008 // definition should minimally look like this: 00009 /* 00010 class CMyClass : private Singleton<CMyClass> 00011 { 00012 private: 00013 // Friend so that the constructor can be called from the 00014 // parent. 00015 friend Singleton<CMyClass>; 00016 friend std::auto_ptr<CMyClass>; 00017 // Private constructor so that users of the class can't 00018 // instantiate their own copy on the stack. 00019 CMyClass(); 00020 00021 // Destructor 00022 virtual ~CMyClass(); 00023 00024 protected: 00025 ... 00026 public: 00027 00028 // Hide the base class so that multiple compilation modules 00029 // don't try to generate multiple copies of m_ptheSingleton 00030 static CMyClass& Instance(); 00031 ... 00032 }; 00033 00034 In implementation file: 00035 00036 CMyClass& CMyClass::Instance() 00037 { 00038 return Singleton<CMyClass>::Instance(); 00039 } 00040 */ 00041 // Users of the CMyClass would access members and functions 00042 // one of two ways: 00043 /* Option 1: 00044 void foo() 00045 { 00046 CMyClass& myClass = CMyClass::Instance(); 00047 ... 00048 } 00049 */ 00050 /* Option 2: 00051 void foo() 00052 { 00053 CMyClass::Instance().SomeFunction(); 00054 ... 00055 } 00056 */ 00057 // Patterns: Implements Singleton from Design Patterns by GOF. 00058 // Author: Scott Seely 00059 /* 00060 /* 00061 $History: singleton.h $ 00062 * 00063 * ***************** Version 3 ***************** 00064 * User: Scott Date: 6/02/99 Time: 7:21p 00065 * Updated in $/book/workarea/Include 00066 * Finished changes to code. I think things are ready to go now. 00067 * 00068 * ***************** Version 2 ***************** 00069 * User: Scott Date: 6/02/99 Time: 6:58a 00070 * Updated in $/book/workarea/Include 00071 * Finished off comments. Added VSS macros. 00072 */ 00074 #ifndef SINGLETON_H 00075 #define SINGLETON_H 00076 00077 /* 00078 #ifndef SINGLETON_H 00079 #include "singleton.h" 00080 #endif //SINGLETON_H 00081 */ 00082 00083 #ifndef _MEMORY_ 00084 #include <memory> 00085 #endif // _MEMORY_ 00086 00087 #ifndef _EXCEPTION_ 00088 #include <exception> 00089 #endif // _EXCEPTION_ 00090 00091 template <class T> 00092 class Singleton 00093 { 00094 private: 00095 // Pointer to the one and only instance. 00096 // As an auto_ptr, we won't get memory leaks 00097 // because it will be destroyed when the program 00098 // shuts down and before memory leak detection kicks in. 00099 static std::auto_ptr<T> m_ptheSingleton; 00100 00101 protected: 00102 // Constructor 00103 // Allows derived classes access to the constructor. 00104 Singleton(){} 00105 00106 // Allows access to the instance. 00107 // Derived classes should make this public by naming the method 00108 // in the derived class's public section. This gives only one 00109 // path to one instance of m_ptheSingleton, making the Singleton 00110 // behavior work. 00111 static T& Instance(); 00112 00113 public: 00114 // Destructor 00115 virtual ~Singleton(){} 00116 }; 00117 00118 template <class T> 00119 std::auto_ptr<T> Singleton<T>::m_ptheSingleton; 00120 00121 template <class T> 00122 T& Singleton<T>::Instance() 00123 { 00124 // All auto_ptrs are initalized to NULL. 00125 // Only create the object if needed. 00126 if ( NULL == m_ptheSingleton.get() ) 00127 { 00128 m_ptheSingleton = std::auto_ptr<T>( new T() ); 00129 } 00130 if ( NULL == m_ptheSingleton.get() ) 00131 { 00132 throw std::bad_alloc(); 00133 } 00134 return *m_ptheSingleton; 00135 } 00136 00137 #endif // SINGLETON_H 00138