单例模式——C++版
单例模式是什么??
单例模式(Singleton)是一种常用的设计模式,它能够保证系统中应用该模式的类只有一个实例。
为什么要存在单例模式??
在很多场景下,我们都希望一个类只能创建出唯一的对象,例如windows下的任务管理器,我们就只能打开一个。若不使用单例模式,就会在多次打开时弹出多个窗口,重复对象,浪费内存。而且要是多个窗口的状态不一致,也会造成误解。因此保证某个对象只能有一个实例这一点很重要。
单例模式的特点:
1.一个类只能有一个实例
2.该类必须自己创建该实例
3.必须向整个系统提供该实例
对应它的三个特点,我们需要做的是:
- 构造函数声明为私有的
- 该类中要包含该类的静态私有对象
- 提供一个共有的静态成员函数来创建或获取它本身的私有对象
两种实现方式(饿汉模式&&懒汉模式)
饿汉模式
- 利用静态成员变量初始化在调main函数之前的特性实现,对象定义后,数据立即加载到内存。
以空间换取时间
这种方式没有加锁,没有双重检查,也不用考虑异常捕获造成的内存泄漏。
//------------------------hangry_pattern-------------------------------------
//通过类模板来实现
template<class T>
class Singleton_hangry
{public://该函数用来获取唯一实例static T* GetInstance(){assert(_inst);return _inst;}protected://构造函数定义为保护的,在其派生类中也可见Singleton_hangry(){};private://由于静态成员函数不能调用非静态的成员变量,所以声明成静态的类对象指针static T* _inst;//拷贝构造和运算符重载函数定义为私有,目的是防拷贝Singleton_hangry(const T &);Singleton_hangry& operator=(const T&);
};//静态成员变量要在类外进行初始化
//初始化时创建唯一实例,在main函数调用前就会执行
//空间换时间的做法
template<class T>
T* Singleton_hangry<T>::_inst=new T;
测试代码:
//-------------------TestCode----------------------------------------------------
int main()
{int* p1=Singleton_hangry<int>::GetInstance();int* p2=Singleton_hangry<int>::GetInstance();cout<<"p1==>"<<p1<<endl;cout<<"p2==>"<<p2<<endl;return 0;
}
执行结果:
p1==>0x10cec20
p2==>0x10cec20
懒汉模式
这种模式是在执行时,首次调用获取唯一实例的接口函数时才会加载内存,延时加载。
//---------------------------lazy_pattern------------------
template<class T>
class Singleton_lazy
{public://创建或获取唯一实例static T* GetInstance(){if(_inst==NULL)_inst=new T;return _inst;}protected://构造函数定义成保护为了在继承时派生类可见Singleton_lazy(){};private://唯一实例static T* _inst;//防拷贝Singleton_lazy(const T&);T& operator=(const T&);
};//main函数执行前先将该实例初始化为空,运行时再加载
template<class T>
T* Singleton_lazy<T>::_inst=NULL;
测试代码:
//-----------------------------TestCode------------------------
int main()
{char* p1=Singleton_lazy<char>::GetInstance();char* p2=Singleton_lazy<char>::GetInstance();cout<<"p1----->"<<(void*)p1<<endl;cout<<"p2----->"<<(void*)p2<<endl;return 0;
}
执行结果:
p1----->0x16bbc20
p2----->0x16bbc20
这样的实现方式其实是线程不安全的,因为在判断_inst是否为空,以及使用new申请空间这两步不是原子操作,在中间可能有其他线程进来,导致创建出来两个实例,不符合我们的期望。基于此,要让它成为线程安全函数就需要对其进行加锁
static T* GetInstance(){pthread_mutex_lock(&lock);if(_inst==NULL){_inst=new T;}pthread_mutex_unlock(&lock);return _inst}
在每一次对_inst进行判空时都要上锁,这样的加锁方式使性能大大下降,显然不满足单例模式高效的特点。因此,对其进行优化,采用双重检查的方式实现。
完整代码:
#include <iostream>
#include <pthread.h>
using namespace std;//--------------------lazy_safe_pattern------------------
template<class T>
class Singleton_lazy
{public://初始化互斥锁static pthread_mutex_t lock;static T* GetInstance(){if(_inst==NULL){pthread_mutex_lock(&lock);if(_inst==NULL){_inst=new T;}pthread_mutex_unlock(&lock);}return _inst;}protected://构造函数定义成保护为了在继承时派生类可见Singleton_lazy(){};private://唯一实例static T* _inst;//防拷贝Singleton_lazy(const T&);T& operator=(const T&);
};//main函数执行前先将该实例初始化为空,运行时再加载
template<class T>
T* Singleton_lazy<T>::_inst=NULL;
template<class T>
pthread_mutex_t Singleton_lazy<T>::lock;//-----------------------------TestCode------------------------
int main()
{char* p1=Singleton_lazy<char>::GetInstance();char* p2=Singleton_lazy<char>::GetInstance();cout<<"p1----->"<<(void*)p1<<endl;cout<<"p2----->"<<(void*)p2<<endl;return 0;
}
测试结果:
p1----->0x10cbc20
p2----->0x10cbc20
单例模式——C++版相关推荐
- 23种设计模式(一)单例模式
2019独角兽企业重金招聘Python工程师标准>>> 定义 单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):"保证一个类仅有一个实例,并提供 ...
- 【Python】《大话设计模式》Python版代码实现
<大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...
- Python 单例模式
#单例模式 class Dog(object):#定义一个类变量#None相当于c++中的NULL,修饰基本类型和类类型均可instance = None#重写__new__方法def __new__ ...
- 《大话设计模式》Python 版代码实现
From:http://www.cnblogs.com/wuyuegb2312/archive/2013/04/09/3008320.html 一.简单工厂模式 模式特点:工厂根据条件产生不同功能的类 ...
- 【设计模式】5、单例模式
原始单例模式 1 package com.shejimoshi.create.Singleton; 2 3 4 /** 5 * 功能:保证一个类仅有一个实例,并提供一个访问它的全局访问点 6 * 适用 ...
- 《大话设计模式》Python版代码实现
<大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...
- 漫画:什么是单例设计模式
转载自 永远爱大家的 程序员小灰 ----- 第二天 ----- 单例模式第一版: 1 2 3 4 5 6 7 8 9 10 11 public class Singleton { pri ...
- Java笔试面试-设计模式
1.说一下设计模式?你都知道哪些? 答:设计模式总共有 23 种,总体来说可以分为三大类:创建型模式( Creational Patterns ).结构型模式( Structural Patterns ...
- java面试题大合集
文章目录 单例模式 最简单的第一版 单例模式第二版:(线程安全) 第三版: (补充线程安全) HashMap hashmap 1.7 hashmap 1.8 锁升级的过程 扩容机制 HashMap的H ...
最新文章
- 讨论:写程序到底需不需要懂数学?
- Error:No resource identifier found for attribute 'appComponentFactory' in packag
- 【案例】常驻查询引发的thread pool 性能问题之二
- java中android_在Android中用纯Java代码布局
- 使用MVC框架中要注意的问题(二):将Model和Controller单独用一个项目设计
- css里slidebottom,jquery - 从CSS“top”到“bottom”的jQuery动画 - 堆栈内存溢出
- java面试题整理_2018年最新java面试题整理。。。持续更新中。。。
- 2008服务器系统来电自启,服务器2008自动重启
- 求助,关于MFC中的 Secur32.lib问题
- 华硕n54u mysql_改华硕[N14U N54U]5G 2G的7620老毛子Padavan固件(私人云储存 ari
- 使用 ESP-Prog / Jlink 进行 JTAG 调试时的常见错误及解决办法
- 【大话设计模式-11】组合模式(案例解析)
- IT行业为何如此吃香?2019学习IT就业前景分析
- 漫画:什么是IaaS、PaaS、SaaS?
- 机器学习笔记(3.1)
- Oracle分区表及分区索引
- 五分钟学会用Simulink模型生成HDL代码
- Python编程:函数
- CAN通讯车用触摸显示器
- 查看oracle版本及补丁,检查及升级Oracle数据库补丁版本