C++11标准下的单例设计模式
单例设计模式
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
为什么会产生设计模式这样的东西呢?
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
其中最具代表性的就是单例设计模式
单例设计模式
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
在linux下曾提到过单例设计模式:
实现:
- 饿汉模式:资源在程序初始化阶段就完成加载(空间换时间)
- 饿汉方法实现:
- 采用静态方法修饰资源,所有对象共用同一份资源,程序初始化阶段完成资源加载且只被加载一次
- 构造函数私有化 ,保证一个类只能实例化一个对象
template <typename T>
class Singleton {static T data;Singleton(){}//构造函数私有化
public:static T* GetInstance() {return &data;}
};
- 懒汉模式:资源在使用的时候再去加载(延迟加载)
- 定义对象指针,初始资源为空
- static修饰,共用一份资源
- volatite修饰 ,防止编译器过度优化
- 加锁保护 线程安全
- 二次检测,防止锁冲突
template <typename T>
class Singleton {volatite static T* inst;//定义对象指针 初始为空static std::mutex _mutex;
public:static T* GetInstance() {if(inst==NULL)//double check 二次检测,避免不为空情况依然加锁,造成锁冲突{_mutex.lock();if (inst == NULL) {inst = new T();//调用时发现为空,进行获取资源}_mutex.unlock();}return inst;}
};
总结来说,单例设计主要分为两种:
- 饿汉模式(提前响应)
- 懒汉模式(延迟加载)
饿汉模式
在C++11标准下,饿汉模式要求:程序启动时就创建一个唯一的实例对象
要满足此条件,提前创建对象,只有将其定义为全局变量或静态变量,才会程序启动前完成创建
// 饿汉模式
// 优点:简单
// 缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定。
class Singleton
{
public:
static Singleton* GetInstance()
{
return &m_instance;
}
private:
// 构造函数私有
Singleton(){};// C++11防拷贝
Singleton(Singleton const&) = delete;
Singleton& operator=(Singleton const&) = delete;
static Singleton m_instance;
};
Singleton Singleton::m_instance; // 在程序入口之前就完成单例对象的初始化
注:
1,构造函数私有 外部无法创建对象
2,通过接口 指针获取已创建对象
3,类内 定义静态成员对象,类外初始化
4,定义静态成员,静态成员定义在类内,类内可以访问私有成员函数完成构造,且静态成员存储在静态数据区,与类不为同一块存储空间
懒汉模式
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
class Singleton
{
public:static Singleton* GetInstance() {
// 注意这里一定要使用Double-Check的方式加锁,才能保证效率和线程安全if (nullptr == m_pInstance) {//第一次判断防止多次加锁导致锁冲突m_mtx.lock();if (nullptr == m_pInstance) {//第二次判断是否为空,为空则为第一次调用构造函数创建,不为空,后续都不会调用构造函数,满足对象第一次创建且仅创建一次m_pInstance = new Singleton();}m_mtx.unlock();} return m_pInstance;}// 实现一个内嵌垃圾回收类class CGarbo {public:~CGarbo(){if (Singleton::m_pInstance)delete Singleton::m_pInstance;}};
// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
static CGarbo Garbo;
private:// 构造函数私有Singleton(){};// 防拷贝Singleton(Singleton const&);Singleton& operator=(Singleton const&);static Singleton* m_pInstance; // 单例对象指针 静态成员变量,在调用构造函数前先创建进行判断static mutex m_mtx; //互斥锁
};
Singleton* Singleton::m_pInstance = nullptr;//静态成员变量类外初始化,第一次初始化为nullptr
Singleton::CGarbo Garbo;
mutex Singleton::m_mtx;
void func(int n)
{cout<< Singleton::GetInstance() << endl;
}// 多线程环境下演示上面GetInstance()加锁和不加锁的区别。
int main()
{thread t1(func, 10);thread t2(func, 10);t1.join();t2.join();cout << Singleton::GetInstance() << endl;cout << Singleton::GetInstance() << endl;
}
C++11标准下的单例设计模式相关推荐
- java基础—多线程下的单例设计模式的安全问题
//多线程下的单例设计模式 class Sing {//饿汉式不存在安全问题,因为其不是线程同步的private static Sing s = new Sing();private Sing(){} ...
- C#基础11.2:单例设计模式
PS:注释和讲解全在代码中 单例设计模式其实就是一个经典问题:如何设计只能有一个实例化的对象的类 //其实C++也是用的基本一模一样的方法 using System; using System.Col ...
- 结合Spring源码学习单例设计模式
之前我学习了 Spring Ioc,明白了 Spring IoC 容器是一个管理Bean的容器,在Spring的定义中,它要求所有的IoC容器都需要实现接口 BeanFactory ,它是一个顶级容器 ...
- Java笔记017-类变量和类方法、理解main方法语法、代码块、单例设计模式、final关键字
目录 面向对象编程(高级部分) 类变量和类方法 类变量-提出问题 传统方法解决 问题分析: 类变量快速入门 类变量内存布局 什么是类变量 如何定义类变量定义语法: 如何访问类变量 定义语法: 类变量使 ...
- Java查漏补缺(08)关键字:static、单例设计模式、理解main方法、类的成员之四:代码块、final关键字、抽象类、接口、内部类、枚举类、注解、包装类
Java查漏补缺(08)关键字:static.单例设计模式.理解main方法.类的成员之四:代码块.final关键字.抽象类.接口.内部类.枚举类.注解.包装类 本章专题与脉络 1. 关键字:stat ...
- 单例设计模式singleton
简单引入 单例设计模式作为最简单,最常用的设计模式.一般是这两中写法,这两种写法教科书所谓的标准写法,但是实际上存在不少问题.后面介绍标准写法,以规避这些问题. 1.懒汉式: /*** 问题在于,当多 ...
- GOF设计模式之1:单例设计模式
1.单例设计模式核心作用: 保证一个类只有一个实例,并且提供了访问该实例的全局访问点 2.常见应用场景: window的任务管理器 项目中读取配置文件一般也是一个单例模式 数据库连接池的设计也是采用单 ...
- 第 5 章 单例设计模式
第 5 章 单例设计模式 1.单例设计模式介绍 所谓类的单例设计模式, 就是采取一定的方法保证在整个的软件系统中, 对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). ...
- JavaSE面向对象:继承、多态、Super、Object类、重写、static、final、静态成员、懒汉式、饿汉式、单例设计模式、初始化块、抽象类、抽象方法、接口
感谢尚硅谷免费提供的视频 继承 ** 理解 ** 生活中的继承:子女继承了父母的财产或相貌或才华 java中的继承:一个类不用自己定义属性或方法,就已经具备了另一个类的属性和方法 把这种现象称为jav ...
最新文章
- TCP/IP总结(2)基础概念
- ERP 我最看重什么?
- android 自定义控件央视,Android自定义ViewGroup之第一次接触ViewGroup
- 最短路径(迪杰斯特拉算法)
- 50-overlay 如何实现跨主机通信?
- 深度学习系统相比较传统的机器学习系统,针对常见的分类问题,精度究竟能有多大提升?...
- 为什么计算机专业被称为宇宙机,量子计算机为何被称为宇宙中最强大的计算机...
- Android之back键拦截处理
- mysql关联表分页查询_MySQL一对多分页查询-主表关联表条件查询问题
- AgreementMaker:Efficient Matching for Large Real-World 翻译
- mysql1558错误,mysql删除用户错误ERROR 1558解决办法
- golang 安全的tcp server_化繁为简,写一个简单好用的server
- Java通过SSH实现文件上传下载功能
- PDFium使用分享
- ReadyState的五种状态详解
- python机器学习思维导图脑图(完整版)
- 一篇让你搞定word文档毕业论文/书籍格式
- Python将numpy(.npy文件)存储为.ply文件
- AM335x启动流程(BootRom- MLO-的Uboot)
- python实现数据可视化软件_基于Python实现交互式数据可视化的工具
热门文章
- NLP之TEA之CNN:利用CNN算法实现对句子分类+进行情感分析(预测句子情感)
- 六一儿童节,程序员对自己好一点
- 全球最顶级的电脑配置_世界十大饼干排行榜,全球十大最著名顶级饼干排名
- 那些被岁月遗忘的UNIX经典著作
- typeof NaN的结果是什么?
- 连入网络的所有计算机都必须使用,[判断题] 联入网络的所有计算机都必须使用同样的操作系统。...
- C语言:计算2的50次方需要多久?
- [Audio]硬件设备
- 学习编程之路的随笔 (일 )
- 二分查找,超详细解读与代码实现,看完不会取关