单例模式

单例模式是一种常用的软件设计模式。 在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

class A;

A a; 这个系统中只能有一个A类对象

控制这个A类型的对象个数,单例模型。系统只有一个对象。

#include <iostream>
using namespace std;//单例模型class A {
//为了不让用户可以自己创建对象 必须把构造函数私有化
private:A() {a = new A;}
//这里唯一一个public的接口设置为静态
//用户便不需要创建对象直接类名进行访问
public:static A* getInstance() {return a;}
//成员变量也需要私有化 不然用户可以A::a
//而且需要设置为静态 匹配上面接口的返回值
private:static A* a;
};
//类外初始化
A* A::a = NULL;//实现单例的步骤
//1.构造函数私有化
//2.增加静态私有的当前类的指针变量
//3.提供静态的对外接口 可以让用户获得单例对象
int main() {A::getInstance();return 0;
}

 单例模型分为懒汉式和饿汉式两种:

#include <iostream>
using namespace std;//单例模型//单例 分为懒汉式 和 饿汉式
class Singleton_lazy {
private:Singleton_lazy() {}
public://增加一个条件判断 如果静态变量为空 则创建一个对象返回static Singleton_lazy* getInstance() {if (pSingleton == NULL) {pSingleton = new Singleton_lazy;}return pSingleton;}//这个释放堆区对象的方式不能提供 太危险了//只要有一个人释放 大家共享的对象就都没了/*static void freeSpace() {if (pSingleton != NULL) {delete pSingleton;pSingleton = NULL;}}*/
private:static Singleton_lazy* pSingleton;
};
//类外初始化
Singleton_lazy* Singleton_lazy::pSingleton = NULL;//饿汉式
class Singleton_hungry {
private:Singleton_hungry() { cout << "我是饿汉式构造" << endl; }
public://可以发现这里没有条件判断了static Singleton_hungry* getInstance() {return pSingleton;}
private:static Singleton_hungry* pSingleton;
};
//类外初始化 初始化的时候直接创建对象
Singleton_hungry* Singleton_hungry::pSingleton = new Singleton_hungry;void test01() {Singleton_lazy* p1 = Singleton_lazy::getInstance();Singleton_lazy* p2 = Singleton_lazy::getInstance();if (p1 == p2) {cout << "两个指针指向同一块内存 是单例" << endl;}else {cout << "不是单例模式" << endl;}
}
void test02() {Singleton_hungry* p1 = Singleton_hungry::getInstance();Singleton_hungry* p2 = Singleton_hungry::getInstance();if (p1 == p2) {cout << "两个指针指向同一块内存 是单例" << endl;}else {cout << "不是单例模式" << endl;}
}int main() {cout << "我是main函数" << endl;test01();test02();return 0;
}

输出结果:

我是饿汉式构造
        我是main函数
        两个指针指向同一块内存 是单例
        两个指针指向同一块内存 是单例

可以看到 最先输出的并不是main函数的输出 因为当程序走到饿汉式的静态成员类外初始化

的地方时 就直接调用了它的构造函数

两种单例模式下重复的调用接口也都是指向同一块内存

同时需要注意的是在单例模式下 我们是不需要考虑堆区内存释放的问题 首先如果提供一个接口freeSpace()去释放的话 太过于危险 因为大家共享一个对象 一释放全没了 内存泄漏指的是不释放堆区内存 不停的堆积下去会让内存放不下而泄漏 但是我们的单例模型从头到尾只有一个对象 只占一块堆区内存 所以等程序结束后自动释放即可

单线程基本概念

示例图:

可以看到 单线程就是顺序往下执行 而多线程就是图片右边有A B两个线程同时执行 但是不一定谁先执行完 当A执行test01 而B执行test02的时候 假设提前给a变量赋值为10 那么就容易产生混乱 如果线程A先一步执行加10操作然后B进入条件判断 那么最后a的结果是20 如果是B在A还没来得及加10之前就判断了 那么a最后结果为10 所以说变量a是进程A B的竞争资源 通常来说解决多线程混乱问题的方式就是给a加一个锁 比如当进程A开始执行test01了那么就会给变量a上锁 知道执行完给a解锁进程B才可以访问变量

单例碰到多线程

懒汉式遇到多线程是不安全的 因为A B线程在执行的时候都会进行判断静态成员变量不为NULL然后new出一个新的对象

饿汉式遇到多线程是安全的 因为饿汉式的静态成员变量在类外初始化 在线程执行之前就已经创建了好了对象 线程A B访问接口的时候返回的都是同一个对象

c++设计模式-单例模式相关推荐

  1. Python设计模式-单例模式

    Python设计模式-单例模式 基于Python3.5.2,代码如下 #coding:utf-8 import threading import timeclass Singleton(object) ...

  2. Android设计模式——单例模式(Singleton)

    二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元 ...

  3. 【学习笔记】ABAP OOD设计模式 - 单例模式

    ABAP OOD设计模式 - 单例模式 整理转自-<SAP ABAP 面向对象程序设计(原则.模式及实践)> 单例模式(Singleton Pattern)是常用的且较为简单的软件设计模式 ...

  4. Go 语言实现 23 种设计模式 单例模式

    Go 语言实现 23 种设计模式 单例模式 单例模式 单例模式是一种常用的软件设计模式,在使用过程中,单例对象的类只有一个实例.使用单例模式,1 可以节省内存等资源,例如windows操作系统的资源管 ...

  5. java singleton inner class_Java面向对象设计模式-单例模式

    Java面向对象设计模式-单例模式 2020-05-28 589 0 单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,有多重实现方式. 一.饿汉式单例模式,构造方法私有化,在加载类Sin ...

  6. Java开发中常用的设计模式-单例模式

    单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式. Java开发中常用的设计模式-单例模式 单例模式有3个特点: 单例类只有一个实例对象: 该单例对象必须 ...

  7. 炒冷饭系列:设计模式 单例模式

    2019独角兽企业重金招聘Python工程师标准>>> 炒冷饭系列:设计模式 单例模式 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆 ...

  8. 设计模式-单例模式-注册式单例模式-枚举式单例模式和容器式单例模式在Java中的使用示例

    场景 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例: 设计模式-单例模式-饿汉式单例模式.懒汉式单例模式.静态内部类在Java中的使用示例_霸道流氓气质的博客- ...

  9. 设计模式----创建型设计模式(单例模式、工厂方法模式、构建者模式)

    创建型设计模式 单例模式(Singleton Pattern) 单例模式介绍 代码演示 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全, ...

  10. 小视频源码,设计模式单例模式

    小视频源码,设计模式单例模式实现的相关代码 .一,单线程时候推荐 /*** Created by Shinelon on 2018/10/11.* 单利模式 懒汉式 -->单线程推荐使用*/pu ...

最新文章

  1. 天平游码读数例题_量筒、天平经典习题
  2. 数据库连接池DBPool分析(一):简介
  3. Logback日志系统配置攻略
  4. mysql 唯一索引出现重复数据_MySQL 创建唯一索引忽略对已经重复数据的检查
  5. 最近面试遇到的技术问题
  6. html首页 slider图片切换效果,jQuery插件Slider Revolution实现响应动画滑动图片切换效果...
  7. 17 | 跳表:为什么Redis一定要用跳表来实现有序集合?
  8. LeetCode 1722. 执行交换操作后的最小汉明距离(并查集)
  9. visual studio 2015 无法打开源文件“stdafx.h“
  10. Qt 局域网聊天工具
  11. SSM框架整合及详解
  12. Java、JSP汽车租赁管理系统
  13. Golang基础(1)
  14. 使用传统AV屏幕用作树莓派屏幕
  15. js正则表达式密码校验
  16. 三门课成绩总分用c语言,编写一个C语言程序:输入三个学生三门课的成绩,计算每个学生的总分和平均成绩...
  17. 爬虫小试-0217影响因子表
  18. 胡桃工具箱, 基于 .NET 开源的多功能原神工具箱
  19. xshell查询日志命令_Xshell查看服务器日志
  20. 启动vsftpd失败是什么原因_CentOS 7 Vsftpd无法启动详解

热门文章

  1. 如何实现一键调用以太坊智能合约
  2. Redis - Redisson lock和tryLock原理解析
  3. C语言使用说明笔记1.2
  4. excel 2016 提取汉字和数字(经典方法,没有之一)
  5. C++:面向对象(总结+补习)
  6. Linux sfdisk命令参数及用法详解--分区操作工具
  7. Greenplum部署
  8. 深入了解 cometd的服务器推送技术
  9. 【大数据处理技术】实验8
  10. 我不以游戏为创业方向的原因