单例模式的c++实现

  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 };
原文地址:https://www.cnblogs.com/suntp/p/6421508.html