C++ 单例模式

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

简单实现:

 1 #include <iostream>
 2 #include <cstdlib>
 3 
 4 using namespace std;
 5 
 6 class CSingleton{
 7 private:
 8     CSingleton(){
 9         cout << "construct function" << endl;
10     }
11     static CSingleton *p_Instance;
12 public:
13     static CSingleton *GetInstance(){
14         if(p_Instance == NULL){
15             p_Instance = new CSingleton();
16             cout << "Construct a instance " << endl;
17         }
18         return p_Instance;
19     }
20 };
21 
22 CSingleton *CSingleton::p_Instance = NULL;
23 
24 int main()
25 {
26     CSingleton *p = CSingleton::GetInstance();
27     system("pause");
28     return 0;
29 }

上述方法代码容易实现,但存在一个问题,即是内在泄漏,由new申请的内存并没有得到释放

为了让实例自动释放内存,可在类CSingleton内部定义一个垃圾回收类,同时定义一个该类的静态成员,当程序运行结束,系统自动析构此静态成员时,在析构函数中会释放CSingleton实例。

 1 #include <iostream>
 2 #include <cstdlib>
 3 
 4 using namespace std;
 5 
 6 class CSingleton{
 7 private:
 8     CSingleton(){
 9         cout << "construct function" << endl;
10     }
11     static CSingleton *p_Instance;
12 
13     //垃圾回收类
14     class GCarbo{
15     public:
16         GCarbo(){ cout << "construct GCarbo" << endl;}
17         ~GCarbo()
18         {
19             cout << "destruct GCarbo" << endl;
20             if(p_Instance != NULL){
21                 delete p_Instance;
22                 p_Instance = NULL;
23                 cout << "release memory succeed ! " << endl;
24                 system("pause"); //不暂停看不到输出信息
25             }
26         }
27     };
28     static GCarbo gc;
29     
30 public:
31     static CSingleton *GetInstance(){
32         if(p_Instance == NULL){
33             p_Instance = new CSingleton();
34             cout << "Construct a instance " << endl;
35         }
36         return p_Instance;
37     }
38 };
39 
40 CSingleton *CSingleton::p_Instance = NULL;
41 //类的静态数据成员需要类外部进行初始化,以创建GCarbo类的一个实例
42 CSingleton::GCarbo CSingleton::gc; 
43 
44 int main()
45 {
46     CSingleton *p = CSingleton::GetInstance();47     return 0;
48 }

上述方法虽然解决了内存泄漏问题,但在多线程环境下,如当两个线程同时调用GetInstance()方法时,执行到if(p_Instance == NULL)时,都为真,然后两个线程都得到一个实例,两个指针并不是指向同一个地方,这不满足单例模式定义

解决方法:(加锁实现同步)

 1 //其他代码同上
 2 static CSingleton *GetInstance(){
 3         //这里采用Double-Check Locking(双重锁定)
 4         //第一个if语句使实例未被创建时候再加锁处理,而不是每次调用GetInstance()方法就会判断锁,若已创建实例则直接退出
 5         //第二个if语句,使获得锁的线程在创建实例后,不能再创建新的实例,以满足单例目的
 6         if(p_Instance == NULL){
 7             Lock();
 8             if(p_Instance == NULL){
 9                 p_Instance = new CSingleton();
10                 cout << "Construct a instance " << endl;
11             }
12             UnLock();
13         }
14         return p_Instance;
15     }

参考:

http://www.2cto.com/kf/201403/283007.html

http://blog.csdn.net/roy1261/article/details/51425987

只为训练自己,时刻锤炼一个程序员最基本的技能!
原文地址:https://www.cnblogs.com/coding-wtf/p/5940083.html