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 };