c++设计模式之单例模式
来源:互联网 发布:素颜美女知乎 编辑:程序博客网 时间:2024/06/14 05:29
- 单例模式概念
单例模式事比较常用的设计模式之一。一般情况下,我们建立的一些类是属于工具性质的,基本不用存储太多的跟自身有关的数据,在这种情况下,每次都去new一个对象,即增加了开销,也使得代码更加臃肿。其实,我们只需要一个实例对象就可以。如果采用全局或者静态变量的方式,会影响封装性,难以保证别的代码不会对全局变量造成影响,而且这样的代码显的很不优雅。 使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象——也就是说除了一个全局实例外,仍然能创建相同类的本地实例。
我们将默认的构造函数声明为私有的,这样就不会被外部所new了,甚至可以将析构函数也声明为私有的,这样就只有自己能够删除自己了。 - 单例模式的懒汉模式和饿汉模式
懒汉模式:就是不到万不得已是不会去实例化类的,也就是说在第一次用到类实例的时候才会去实例化。
饿汉模式:在单例类定义的时候就实例化了。
优点和缺点:
(1)在访问量比较小的时候,采用懒汉模式。以时间换空间。
(2)因为要进行线程同步,所以在访问量较多的时候,采用饿汉模式,可以实现更好的性能。以空间换时间。
实现:把构造函数定义为私有的或者保护的,再定义一个类的私有的静态指针,指向这个类的唯一实例,再提供一个公有的静态的方法获取该实例。 - 代码实现
《一》饿汉模式
(1)饿汉模式实现一
class SiglenTon //懒汉模式(线程不安全){public: static SiglenTon *GetInstance() { if( ptr == NULL) { ptr = new SiglenTon(); } return ptr; }private: SiglenTon() { cout<<"SiglenTon()"<<endl; } static SiglenTon *ptr;};SiglenTon *SiglenTon::ptr = NULL;int main(){ SiglenTon *ptr = SiglenTon::GetInstance(); return 0;}
该方式实现的单例模式是不安全的,假如有两个线程同时调用GetInstance的时候,同时检测到ptr指针为空,同时创建一个相同的对象,这是错误的。
(2)饿汉模式实现二(加一层互斥锁)
class SigleTon {public: static SigleTon *GetInstance() { cout<<"static SigleTon *GetInstance()"<<endl; pthread_mutex_lock(&mutex); if( ptr == NULL) { ptr = new SigleTon(); } pthread_mutex_unlock(&mutex); return ptr; }private: SigleTon() { cout<<"SigleTon()"<<endl; } static SigleTon *ptr;};SigleTon *SigleTon::ptr = NULL;
该方式加了一对互斥锁,线程是安全的,但是对于单线程来说,每次都要加锁解锁,效率不高。而且如果每次判断是否为空都需要被锁定,如果有很多线程的话,就会造成大量线程的阻塞。
(3)饿汉模式实现三(两层互斥锁)
class SigleTon //加双重互斥锁{public: static SigleTon *GetInstance() { cout<<"static SigleTon *GetInstance()"<<endl; pthread_mutex_lock(&mutex); if( ptr == NULL) { pthread_mutex_lock(&mutex); ptr = new SigleTon(); pthread_mutex_lock(&mutex); } pthread_mutex_unlock(&mutex); return ptr; }private: SigleTon() { cout<<"SigleTon()"<<endl; } static SigleTon *ptr;};SigleTon *SigleTon::ptr = NULL;
(4)饿汉模式实现四(用一个静态内部变量实现懒汉模式)
在Instance函数里定义一个静态的实例,也可以保证拥有唯一实例,在返回时只需要返回其指针就可以了。推荐这种实现方法,真得非常简单。
class SiglenTon {public: static SiglenTon *Instance() { cout<<"static SiglenTon Instance()"<<endl; pthread_mutex_lock(&mutex); static SiglenTon msigleton; pthread_mutex_lock(&mutex); return &msigleton; }private: SiglenTon() { cout<<"SiglenTon()"<<endl; } static SiglenTon *ptr;};SiglenTon *SiglenTon::ptr = NULL;
《二》懒汉模式
在类外初始化指针的时候就创建一个对象。懒汉模式是线程安全的,不用加互斥锁,因为在当类定义的时候定义了一个对象,对类进行了初始化。后面不管哪个线程调用Instance函数,都只不过是返回了一个对象的指针而已。
class SigleTon{public: static SigleTon *GetInstance() { cout<<"static SigleTon *GetInstance()"<<endl; if( ptr == NULL) { return ptr; } }private: SigleTon() { cout<<"SigleTon()"<<endl; } static SigleTon *ptr;};SigleTon *SigleTon::ptr = new SigleTon();
阅读全文
0 0
- (C#)设计模式 之 单例模式
- 设计模式之单例模式(C++)
- C#--设计模式之单例模式
- Objective-C 设计模式之单例
- Objective-C之单例设计模式
- 设计模式之单例模式(C++)
- C语言和设计模式(之单例模式)
- Objective-C中的设计模式之单例模式
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- 设计模式之:单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- android 7.1 服务进程 open串口设备失败
- 关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
- 解决Java调用https服务证书错误javax.net.ssl.SSLHandshakeException
- Dominos<并查集求解>
- boot中的命令行解析器
- c++设计模式之单例模式
- vue-router总结
- Q123:PBRT-V3,各种形式的“光传播方程”的推导依据
- Java常识 ------分支语句(for do---while while语句)
- ConstraintLayout属性详解和Chain的使用
- JvavScript与java中的正则表达式的区别
- JS设置cookie、读取cookie、删除cookie
- C# 获取CPU ID(本机)
- [Leetcode] 293. Flip Game 解题报告