单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
简单实现:
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