单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
简单实现:
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
只为训练自己,时刻锤炼一个程序员最基本的技能!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· Supergateway:MCP服务器的远程调试与集成工具
· C# 13 中的新增功能实操