1 #pragma once 2 3 #include <iostream> 4 #include <memory> 5 #include <Windows.h> 6 using namespace std; 7 /*************************************************************************************** 8 9 1、首先要有一个创建实例的静态函数GetInstance 10 2、实现的方式既可以通过new动态创建,也可以通过static静态局部变量实现 11 3、创建的时机既可以通过静态变量初始化时创建,也可以在调用GetInstance函数时再创建,通过静态变量的初始化的好处是 12 它是在进入主函数之前创建成功的可以避免多线程的问题,但是坏处就是在程序启动时初始化会拖慢启动过程。 13 4、为了防止通过调用构造函数创建实例,要将类的构造、复制构造和赋值构造函数设为私有的 14 5、GetInstance函数的返回值既可以是指针,又可以是引用,当是指针的时候要防止它在中途被delete掉,因此要将析构函数设为私有的 15 6、这种模式有点像全局变量,但还是有区别的,单件的作用是保证只有一份实例,而能够全局访问是它附带的功能。 16 17 ********************************************************////////////////////////////////////// 18 class singleton1 19 { 20 public: 21 static singleton1* GetInstance() 22 { 23 if(ptr == NULL) 24 ptr = new singleton1; 25 return ptr; 26 } 27 28 static void show() 29 { 30 cout << "singleton1::show" << endl; 31 } 32 33 private: 34 ~singleton1() 35 { 36 cout << "dest singleton1" << endl; 37 } 38 static singleton1* ptr; 39 singleton1() 40 { 41 cout << "cstr singleton1" << endl; 42 } 43 44 singleton1(const singleton1 &); 45 singleton1& operator=(const singleton1 &); 46 }; 47 48 singleton1* singleton1::ptr = new singleton1; 49 50 /***************** 51 1、在上面的实现中,使用指针时,不能销毁实例,只有当程序结束时才由系统回收,考虑将指针设计成智能指针shared_ptr, 52 但是智能指针的回收还是要调用析构函数,声明为public,指针随时会被delete,有很多问题,所以这种方法是不太实用 53 *****************/ 54 class singleton3 55 { 56 public: 57 ~singleton3() 58 { 59 cout << "dest singleton3" << endl; 60 } 61 62 static singleton3* GetInstance() 63 { 64 if(ptr.get() == NULL) 65 ptr.reset(new singleton3); 66 return ptr.get(); 67 } 68 69 static void show() 70 { 71 cout << "singleton3::show" << endl; 72 } 73 74 private: 75 static shared_ptr<singleton3> ptr; 76 singleton3(){} 77 singleton3(const singleton3 &); 78 singleton3& operator=(const singleton3 &); 79 }; 80 81 shared_ptr<singleton3> singleton3::ptr; 82 83 /**************************************** 84 1、上面的实现都是基于new动态创建,并且返回的都是指针类型,这个实现基于静态局部变量,并且返回引用类型 85 2、返回引用而不是指针的好处是,不用担心中间会被delete掉 86 3、采用静态局部变量的好处是,内存管理交给系统,不需要手动管理 87 ****************************************/ 88 class singleton4 89 { 90 public: 91 ~singleton4() 92 { 93 cout << "dest singleton4" << endl; 94 } 95 96 static singleton4& GetInstance() 97 { 98 static singleton4 s; 99 return s; 100 } 101 102 static void show() 103 { 104 cout << "singleton4::show" << endl; 105 } 106 107 private: 108 singleton4(){;} 109 singleton4(const singleton4 &); 110 singleton4& operator=(const singleton4 &); 111 }; 112 113 /*************************** 114 1、如果是在GetInstance函数中创建实例,并且是多线程的话,如果有多个线程同时调用该函数, 115 则可能会创建多个实例,所以要对创建过程进行加锁处理 116 **************************/ 117 CRITICAL_SECTION g_cs; 118 class Lock 119 { 120 public: 121 Lock() 122 { 123 InitializeCriticalSection(&g_cs); 124 } 125 126 void LockOn() 127 { 128 EnterCriticalSection(&g_cs); 129 } 130 131 void LockOff() 132 { 133 LeaveCriticalSection(&g_cs); 134 } 135 136 ~Lock() 137 { 138 DeleteCriticalSection(&g_cs); 139 } 140 }; 141 Lock g_lock; 142 143 class singleton5 144 { 145 public: 146 ~singleton5() 147 { 148 cout << "dest singleton5" << endl; 149 } 150 151 static singleton5* GetInstance() 152 { 153 if(ptr == NULL) 154 { 155 //采用双重判断是为了提高效率,防止每次都要执行加锁过程 156 g_lock.LockOn(); 157 if(ptr == NULL) 158 ptr = new singleton5; 159 g_lock.LockOff(); 160 } 161 162 return ptr; 163 } 164 165 static void show() 166 { 167 cout << "singleton5::show" << endl; 168 } 169 170 private: 171 static singleton5* ptr; 172 singleton5(){} 173 singleton5(const singleton5 &); 174 singleton5& operator=(const singleton5 &); 175 }; 176 singleton5* singleton5::ptr = NULL; 177 178 /****************** 179 1、上面的实现虽然满足了多线程调用,但是实际中可能会有很多类都要设计成实例模式, 180 那么就需要都按照上面那样实现一遍,不能重用,下面的模板类就可以满足重用的需求 181 *******************************/ 182 template <typename T> 183 class Singleton 184 { 185 public: 186 static T& Instance() 187 { 188 if (m_pInstance == NULL) 189 { 190 //Lock lock; 191 g_lock.LockOn(); 192 if (m_pInstance == NULL) 193 { 194 m_pInstance = new T; 195 atexit(&Destroy);//将Destroy注册为程序结束时的执行函数释放内存 196 } 197 198 //return *m_pInstance; 199 g_lock.LockOff(); 200 } 201 202 return *m_pInstance; 203 } 204 205 protected: 206 Singleton(void) 207 { 208 cout << "cstr Singleton" << endl; 209 } 210 virtual ~Singleton(void) 211 { 212 cout << "dest Singleton" << endl; 213 } 214 215 private: 216 Singleton(const Singleton& rhs) 217 { 218 cout << "copy cstr Singleton" << endl; 219 } 220 Singleton& operator = (const Singleton& rhs) 221 { 222 cout << "= cstr Singleton" << endl; 223 } 224 225 static void Destroy() 226 { 227 if (m_pInstance != NULL) 228 delete m_pInstance; 229 m_pInstance = NULL; 230 } 231 232 static T* m_pInstance; 233 }; 234 235 template <typename T> 236 T* Singleton<T>::m_pInstance = NULL; 237 238 //实际的单例类就按照下面的方式实现 239 class SingletonInstance : public Singleton<SingletonInstance> 240 { 241 public: 242 friend Singleton<SingletonInstance>; 243 void show() 244 { 245 cout << "SingletonInstance::show" << endl; 246 } 247 // 248 private: 249 SingletonInstance() 250 { 251 cout << "cstr SingletonInstance" << endl; 252 } 253 virtual ~SingletonInstance(void) 254 { 255 cout << "dest SingletonInstance" << endl; 256 } 257 258 SingletonInstance(const SingletonInstance& rhs) 259 { 260 cout << "copy cstr SingletonInstance" << endl; 261 } 262 }; 263 264 //测试类 265 class SingletonTest 266 { 267 public: 268 SingletonTest() 269 { 270 //singleton1& s1 = singleton1::GetInstance1(); 271 //s1.show(); 272 273 //singleton1 *p1 = singleton1::GetInstance(); 274 //p1->show(); 275 ////delete p1; 276 277 //singleton3 *p3 = singleton3::GetInstance(); 278 //p3->show(); 279 280 //singleton4 &p4 = singleton4::GetInstance(); 281 //p4.show(); 282 283 //singleton5 *p5 = singleton5::GetInstance(); 284 //p5->show(); 285 286 SingletonInstance &si = SingletonInstance::Instance(); 287 si.show(); 288 } 289 };