没有合适的资源?快使用搜索试试~ 我知道了~
C++中的单例模式及按需释放模型
需积分: 20 5 下载量 31 浏览量
2012-11-12
14:32:34
上传
评论 1
收藏 276KB DOC 举报
温馨提示
试读
37页
单例模式是设计模式中最简单最容易理解的模式之一,实用方便,项目设计开发中会被经常使用,但是不知道读者有没有考虑过这个问题,单例模式实例什么时候被释放,读者有兴趣可以仔细分析下,按照目前通常方法实现的单例模式都是直到系统退出的时候才释放的,甚至是有垃圾回收机制的C#上也是这样的,系统切换了功能模块还存在大量的这个模块根本不使用的单例类对象,实际上是很浪费存储空间的,单例类少还好说,如果单例类有几十甚至几百的时候(中大型项目这个数量不算夸张),这种空间占用就不是可以轻易容忍的了。
资源推荐
资源详情
资源评论
C++
中的单例模式及按需释放模型(一)
分类:设计模式C++2011-11-28 16:19146 人阅读评论(0)收藏举报
关键字:C++、单例模式、友元、模板、多线程、对象生命周期
单例模式是设计模式中最简单最容易理解的模式之一,实用方便,项目设计开发中会被经常使用,但是不
知道读者有没有考虑过这个问题,单例模式实例什么时候被释放,读者有兴趣可以仔细分析下,按照目前
通常方法实现的单例模式都是直到系统退出的时候才释放的,甚至是有垃圾回收机制的 C#上也是这样的,
系统切换了功能模块还存在大量的这个模块根本不使用的单例类对象,实际上是很浪费存储空间的,单例
类少还好说,如果单例类有几十甚至几百的时候(中大型项目这个数量不算夸张),这种空间占用就不是
可以轻易容忍的了。
注意我这里说的不仅仅是安全释放的问题(目前网上的关于单例释放的解决方案大
多都是安全释放,即程序退出时安全释放),而是能在程序运行中把本模块不用的
(其他模块使用的)单例类及时从内存中释放掉。
如果读者觉得这是个问题,并且也想解决这个问题,可以仔细阅读下本系列博文,会对你解决这个问题有
帮助的。
为了描述单例模式及其问题,首先举一个实际项目的例子,项目是一个手机的移动项目,需要访问硬件设
备读取 IC 卡的内容,读取到的内容需要传递给界面模块显示,这些信息是和人相关的信息,相应的界面
主要显示和人业务相关的内容,这些人业务通常需要提供类似民族的下拉列表框方便用户选择民族输入,
同时项目中除了管理人业务,还有其他的类似部门管理、仓储货品管理等功能。
简单分析这个项目,发现其中有以下元素可以定义成单例模式对象
1、硬件访问类,因为硬件只有一个,多个对象实例没有意义,而且容易访问冲突;
2、IC 卡信息传递类,通过硬件访问到的 IC 卡信息要么通过结构体作为参数在各个函数中传递,要么定
义成单例类直接可以在多个模块访问,不作为函数的参数满天飞,因为硬件只有一个,所以这个类实例存
在多个也没有多少意义,所以最好是一个单例类;
3、民族等字典类,这种类在多个模块中使用,也使用单例模式,因为内容是固定的,多个实例只会浪费
存储空间。
下边我们分析下 3 个单例类的区别
1、硬件访问类,管理一个设备,以行为方法为主,数据信息少,而且这种指明设备信息的内容基本不变,
对于设备的初始化和关闭的行为,一种方式提供 Init、Close 等类似方法让外部调用管理,更好的方法是
让设备管理类成为一个闭包,在构造函数和析构函数中执行初始化和关闭的行为,即最好是闭包的单例类
管理设备(关于这一点,很多教科书会说构造函数的行为要尽量简单,不要执行一些实际的可能错误的行
为,还是使用 Init、Close 的方式比较好,但是即使是这样,安全的做法也应该在析构函数中调用 Close
方法,提供一个最后的安全关闭能力);
2、IC 卡信息传递类,内容或者说内部各个字段的状态是可变的,每次写入读取都会变化,即有状态的单
例类;
3、民族等字典类,内容可以认为恒定不变的,类似的字典类可能很多,比如行政区划也是这种类,如果
不在人业务中,不会使用这种字典类,如果在其他不使用这些字典单例类实例的模块中运行时,这些单例
类还存在就会浪费存储空间,最好能在确认不使用的情况下把内容释放掉,即状态不变需要释放的单例类。
(关于这一点其实还有个方法就是模块划分清晰的话做成 DLL,那样当人业务 DLL 卸载的时候,其中的
字典表自然就不会存在了,但是这要求 DLL 划分的粒度够小,毕竟很难做到所有字典表同 DLL 直接对应
好,所以存在按需施放还是有必要的)
对于以上 3 个单例类,要解决其中讲到的所有情况,单例类应该具有以下特点:
1、必须单例,整个系统只能有一个这种类的实例,不能多个;
2、延迟创建,第一次需要的时候创建,目前的单例模式实现方式大多可以做到这点;
3、按需释放,在确认不使用的情况下,能把单例类释放掉,释放出其占有的内存空间,不是要等到程序
退出时才释放。
本系列博文会在 C++上实现单例模式,并讲解如何让单例类 3 个特点都具备,网上的单例模式文章很多,
主要以 java 和 C#为主,C++的文章也有一些很不错,大家可以自己参考 。
以下是各章节的简单介绍,读者可以根据自己的水平与兴趣选择阅读:
1、C++ 中的单例模式及按需释放模型(二) 中会讲到 3 种 C++中常见的实现单例模式的方法,其中一种
是模仿 C#编写的,会说明这种方法是错误的,第二种单例模式是正确的,但是非常不好,第三种是目前
网上比较常见的正确的实现方法,但是还是不能解决按需释放的问题;
2、C++ 中的单例模式及按需释放模型(三) 中会讲解如何使用辅助类实现按需施放的单例模式,能够实
现单例类所有 3 个特点;
3、C++ 中的单例模式及按需释放模型(四) 中会使用模板类把辅助类抽象出来,变成通用的辅助类,在
这一章会发现使用这个辅助模板类的情况下,单例类的开发比平时看到的单例类实现还要简单;
4、C++ 中的单例模式及按需释放模型(五) 中会提供辅助模板类的多线程版本,并演示如何在多线程中
使用这种单例类,同时会测试多线程下使用的效率,讲解运行中产生的比较有意思结果的原因。
当读者阅读完本文,读者会发现使用文中的方法实现单例模式更加简单,并且可以实现单例类的全部 3 种
特点。
同时文中会提到使用这个方法还是有个要求的,就是开发者要对对象的生命周期有个比较好的控制能力。
值得一提的是,目前 java 和 C#上常见的单例实现方法也不能做到第 3 种特点,没有这个特点,设备管理
类的闭包关闭和常用字典类的按需释放是做不到的。(当然如果开发者觉得不喜欢使用设备的闭包管理、
觉得计算机空间是无限的,或者单例占有的空间很小的,不需要按需施放,继续使用常见的单例模式也无
不可)
最后说明下文中的示例代码地址是 http://download.csdn.net/detail/gogogo/3852925,在 vs2005 下编译通
过,需要的读者可以下载查看。
为了使本模型使用起来更加方便,本人后来又对现有的程序进行了改进,主要是进行了操作符重载,使开
发过程中使用本模型更加简洁容易,具体请见《按需释放单例模型的改进》,也提供了新的例子,下载地
址是 http://download.csdn.net/detail/gogogo/3881956。
C++
中的单例模式及按需释放模型(二)
分类:C++设计模式
2011-11-28 17:1489 人阅读评论(2)收藏举报
一、在 C++中实现单例模式
例子工程的名称是 Singleton。
1、模拟 C#的方法实现单例模式
本人开始学习设计模式也是先看的 C#语言描述的,后来要在 C++上实现,参考了网上相关文章,使用一
个静态类成员的指针来实现单例模式,代码如下:
SingletonSimulateGC 类定义
[cpp]view plain copy
1. classSingletonSimulateGC
2. {
3. private:
4. SingletonSimulateGC(void);
5. public:
6. staticSingletonSimulateGC*GetInstance();
7. ~SingletonSimulateGC(void);
8.
9. public:
10. intSomeFunction();
11.
12. private:
13. staticSingletonSimulateGC*m_pInstance;
14. };
类实现如下
[cpp]view plain copy
1. #include"SingletonSimulateGC.h"
2.
3. SingletonSimulateGC*SingletonSimulateGC::m_pInstance=NULL;
4.
5. SingletonSimulateGC*SingletonSimulateGC::GetInstance()
6. {
7. if(m_pInstance==NULL)
8. {
9. try
10. {
11. m_pInstance=newSingletonSimulateGC();
12. }
13. catch(...)//防止 new 分配内存可能出错的问题,如果是内存分配错误异常为
std::bad_alloc
14. {
15. m_pInstance=NULL;
16. }
17. }
18.
19. returnm_pInstance;
20. }
21.
22. SingletonSimulateGC::SingletonSimulateGC(void)
23. {
24. }
25.
26. SingletonSimulateGC::~SingletonSimulateGC(void)
27. {
28. }
29.
30. intSingletonSimulateGC::SomeFunction()
31. {
32. return10;
33. }
代码很简单,很像 C#的实现,使用静态成员方法 GetInstance 即可获得一个单例类的实例,这种写法在
有垃圾回收机制的语言中是没有问题的,但是 C++不行,如果仔细调试的话,会发现直到程序退出
SingletonSimulateGC 的析构方法都没有被调用过,对于大多数只保存数据的单例类来说,这没有什么,
当程序退出的时候,进程会自动释放这些存储空间,但是如果是个设备管理单例类,在这个单例类的析构
方法中管理着设备的关闭等清理方法,这个析构方法不被调用,只是进程退出的时候简单的执行一个类似
CloseHandle 方法,设备是会出现问题的,所以这种做法实际上是错误的。
为了解决这个错误问题,网上有一种做法如下
[cpp]view plain copy
1. classCSingleton
2. {
3. //其它成员
4. public:
5. staticCSingleton*GetInstance()
6.
7. private:
8. CSingleton(){};
剩余36页未读,继续阅读
资源评论
pingfeng1216
- 粉丝: 1
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功