设计模式C++达到 1.辛格尔顿
实现类的单个案件的Singleton模式。该系统有一个类只有一个实例,而本实施例是容易的外部访问。所以容易控制的实例的数量,并且节省系统资源。
单的情况下通常与一些非本地静态对象的使用,对于这些对象,计划是难以控制。对于那些具有全球影响,持久对象和一般的存在,根据某些约束有时需要被初始化或顺序,始化这些对象假设不使用单例方法的话会极度不安全。这个时候就要使用单例模式来解决问题。
实现单例的方法有非常多,最简单的一个是将对象放入函数中作为其静态成员:
class SingleTon;
SingleTon* getSingleTonInstance(){
static SingleTon* instance = new SingleTon();
return instance;
}
class SingleTon{
friend SingleTon* getSingleTonInstance();
private:
SingleTon(){}
};
这是我觉得的最简单的实现单例模式的方法,不足的地方在于这个获得单例对象的函数不在类内。
首先要实现单例模式,将构造函数声明为稀有。这样构造函数就不能被方法,也不能任意创建单例类的对象。而这里获得实例为函数的静态对象,所以其仅仅有一个。且存在时间为创建到程序结束。
当然。也能够将函数中的静态对象改为类中的静态对象,而将这个全局的函数设置为类中的静态函数,这样就得到一个更加普遍经常使用的形式:
class SingleTon{
public:
static SingleTon* getInstance(){
static SingleTon* instance = new SingleTon();
return instance;
}
~SingleTon(){}
private:
SingleTon(){ }
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
};
这里还是使用了函数中的静态成员,使用类中的静态成员也是能够的:
class SingleTon{
public:
static SingleTon* getInstance(){
if(NULL == instance)
instance = new SingleTon();
return instance;
}
private:
SingleTon(){ }
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
static SingleTon* instance;
};
SingleTon* SingleTon::instance;// = new SingleTon();类内的静态成员初始化能够调用类中的私有的构造函数。
为了安全性,这里将复制构造函数和赋值操作符都给隐藏了。可是析构函数还是可见的,程序猿还是会误用delete来删除这个单例实体,这样是不安全的,能够选择将析构函数放入私有中。隐藏析构函数,对于一些对象在最后结束时析构。则不用关心其释放过程。
可是假设在程序运行中要调用析构函数进行实例的删除的话,就使用一个公有的函数来封装析构函数,且将析构函数置为私有:
class SingleTon{
public:
static SingleTon* getInstance(){
if(NULL == instance)
instance = new SingleTon();
return instance;
}
static void delelteInstance(){
if(NULL != instance){
delete instance;
instance = NULL;
}
}
private:
SingleTon(){ }
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
static SingleTon* instance;
~SingleTon();
};
SingleTon* SingleTon::instance ;
这里就已经基本上在单线程上安全了,然后就考虑多线程。当多个线程企图同一时候初始化 单例实例时,就出现了问题,要使用相互排斥来解决这个问题。这里就使用临界区来解决:
CRITICAL_SECTION cs;
class SingleTon{
public:
static SingleTon* getInstance(){
if(NULL == instance){
EnterCriticalSection(&cs);
if(NULL == instance){//双检锁。在进入临界区后再检測一次是否对象已经建立
instance = new SingleTon();
}
LeaveCriticalSection(&cs);
}
return instance;
}
static void delelteInstance(){
if(NULL != instance){
EnterCriticalSection(&cs);
if(NULL != instance){
delete instance;
instance = NULL;
}
LeaveCriticalSection(&cs);
}
}
private:
SingleTon(){ }
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
static SingleTon* instance;
~SingleTon();
};
SingleTon* SingleTon::instance ;
这里使用双检锁的机制,第一次是推断是否须要对实例进行操作,第二次是在进入临界区即对数据加锁后,推断在数据已经不会再被外界干扰的情况下。第一次推断和第二次推断之间是否被其它线程进行了操作,这样两次推断保证了实例的安全。
可是这样还是不够安全。由于多线程中还是会有一些特殊情况,在类中一些文件被锁了,如文件句柄,数据库连接等,这些随着程序的关闭并不会马上关闭资源。必需要在程序关闭前,进行手动释放。
这里的指不会自己主动关闭。是对于析构函数是私有的情况下,由于系统无法訪问私有的析构函数。对于没有这些连接时。即类仅仅在内存中占领了一些地址,则系统将其视为全局变量。在结束时释放其所在内存资源,所以没有内存泄漏。而若类中有文件句柄和数据库连接这些东西。系统并不会帮忙关闭这些。所以必须手动的调用析构函数中对这些文件的关闭操作。
对于这种情况,通常会使用一种私有内嵌类Garbo,意为垃圾工人。在单例类中包括一个私有的静态垃圾工人对象,当程序结束时。系统会调用这个对象的析构函数,而这个析构函数中对单例类对象实现析构。
CRITICAL_SECTION cs;
class SingleTon{
public:
static SingleTon* getInstance(){
if(NULL == instance){
EnterCriticalSection(&cs);
if(NULL == instance){//双检锁。在进入临界区后再检測一次是否对象已经建立
instance = new SingleTon();
}
LeaveCriticalSection(&cs);
}
return instance;
}
static void delelteInstance(){
if(NULL != instance){
EnterCriticalSection(&cs);
if(NULL != instance){
delete instance;
instance = NULL;
}
LeaveCriticalSection(&cs);
}
} private:
SingleTon(){ }
SingleTon(const SingleTon&);
SingleTon& operator=(const SingleTon&);
static SingleTon* instance;
~SingleTon(){}//对应的关闭连接等操作
class GarBo{
public:
~GarBo(){
if(NULL != instance){
EnterCriticalSection(&cs);
if(NULL != instance){
delete instance;
instance = NULL;
}
LeaveCriticalSection(&cs);
}
}
};
static GarBo gc ;
};
SingleTon* SingleTon::instance ;
SingleTon::GarBo SingleTon::gc;//类外的初始化。
这样就得到更加完美的单例类。
版权声明:本文博主原创文章,博客,未经同意不得转载。
设计模式C++达到 1.辛格尔顿的更多相关文章
- 【从cocos2d-x学习设计模式】第一阶段:辛格尔顿
设计模式,它总结了前辈在许多方案重用代码.它是一个想法. 因为我们爱cocos2d-x,然后我们从去cocos2d-x在设计模式中,右一起学习!本篇解释未来辛格尔顿. 提cocos2d-x中间Dire ...
- 设计模式——辛格尔顿(Singleton)
要想正确理解设计模式,首先必须明白它是为了解决什么问题而提出来的. 设计模式学习笔记 --Shulin 转载请注明出处:http://blog.csdn.net/zhshulin 单例模式属于设计模式 ...
- 【OC加强】辛格尔顿和[NSFileManager defaultMagager]以及其他设计模式
我们在工作中使用文件NSFileManager上课时间,创建发现1对象,此2同样的对象地址: NSFileManager *file1=[NSFileManager defaultManager]; ...
- Javascript 设计模式 辛格尔顿
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/30490955 我一直很喜欢Js,,,今天写JsSingleton模式来实现,以及 ...
- JAVA设计模式--辛格尔顿
Singleton模式可以作为一种编程技术,让我们先从理论上说代码 单例模式三个关键点: 1).某个类仅仅能有一个实例 2).该类必须自行创建这个实例 3).该类必须自行向整个系统提供这个实例 应用场 ...
- 我学的是设计模式的视频教程——辛格尔顿,生成器VS工厂方法
课程视频 单例模式 建造者VS工厂方法 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 版权声明:本文博客原创文章,博客, ...
- Swift辛格尔顿设计模式(SINGLETON)
本文已更新为2.0语法,具体查看:一叶单例模式 一.意图 保证一个类公有一个实例.并提供一个訪问它的全局訪问点. 二.使用场景 1.使用场景 当类仅仅能有一个实例并且客户能够从一个众所周知的訪问点訪问 ...
- iOSSingleton设计模式详细的说明教程
iOS有很多的设计模式,当然,不管是什么语言有很多的设计模式.辛格尔顿是一种之一,辛格尔顿,它从字面上是一个单独的实例,首先,它是只有一个单一的,其次,它是一个实例.我们知道,在iOS用于开发Obje ...
- 辛格尔顿和Android
辛格尔顿(Singleton) .singleton.h,定义类的基本成员及接口 #ifndef SINGLETON_H_INCLUDE #define SINGLETON_H_INCLUDE cla ...
随机推荐
- UVA 10828 - Back to Kernighan-Ritchie(概率+高斯消元)
UVA 10828 - Back to Kernighan-Ritchie 题目链接 题意:给图一个流程图,有结点的流程,每次进入下一个流程概率是均等的,有q次询问,求出每次询问结点的运行期望 思路: ...
- hdu1532(最大流)
传送门:Drainage Ditches 题意:给出n个河流,m个点,以及每个河流的流量,求从1到m点的最大流量. 分析:网络流入门题,第一次写按照白书上毫无优化的Ford_fulkerson算法,先 ...
- (hdu 简单题 128道)平方和与立方和(求一个区间的立方和和平方和)
题目: 平方和与立方和 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- CSS实现输入框的高亮效果-------Day50
又到周末了,这一天天过的真快,明天应该回老家了.不知道会不会有机会进行编写.尽量争取吧,实在不想就这样间断.假设说从前会一天天无聊到爆,那如今自己应该是一天天忙的要死,欠缺了太多东西,那些浪费的时间可 ...
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...
- Android清理设备内存具体完整演示样例(一)
MainActivity例如以下: package come.on; import android.app.Activity; import android.content.Context; impo ...
- 2-13. 平均两个有序序列(25)(ZJU_PAT 名单 | 排列 )
主题链接:http://pat.zju.edu.cn/contests/ds/2-13 已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数.有序序列A0, A1-AN-1的中位 ...
- ARMv8 Linux内核异常处理过程分析
NOTE:为了方便大家阅读,制作了PDF版文档.下载请猛戳这里 老样子,为了赚点积分下载其它人的文件,下载以上资料须要资源分2分. 假设没有积分请留言全部文档,留下邮箱就可以. 看了Linaro提供的 ...
- JSTL自定义标签库 (二)
要定义自己的标签,首先写个java类,extends TagSupport 或者 implements Tag ,然后在类体里实现自己想要的方法,或者覆盖父类的方法. 我定义的MyTag代码如下: ...
- A Game of Thrones(3) - Daenerys
Her brother held the gown up for her inspection. “This is beauty. Touch it. Go on. Caress(爱抚,抚抱) the ...