单例模式:

        只能有一个实例,有懒汉和饿汉区分,实现核心思想:

        1.构造函数私有化

        2.使用静态函数作为接口来获取类对象

1、懒汉模式:

        由调用者实例,多线程情况下会存在线程安全问题,需要加互斥锁进行防护

2、饿汉模式:

        没有人为实例对象时,就把对象给实例好,当需要使用时只要通过接口函数直接获取对象

注意:

     饿汉模式new的对象,需要人为处理,否则会导致内存泄漏,可以使用智能指针进行管理,或者写个静态的类中类,让类中类进行析构释放

代码示例:

饿汉模式

//饿汉模式,没有线程安全问题,无需加锁
class singleHungry
{
private:int dataA;int dataB;
private://构造函数私有化singleHungry(int a, int b):dataA(a),dataB(b){} //禁用默认拷贝构造、赋值运算符函数singleHungry(const singleHungry& s) = delete;singleHungry& operator= (const singleHungry& s) = delete;
public:~singleHungry(){}static singleHungry s_instacne;static singleHungry& getInstacne();//业务逻辑int getAddResult(){int result = dataA + dataB;cout<<"add result = "<<result<<endl;return result;}
};//静态变量需要在类外进行初始化,由于对象是静态变量,存储在静态存储区,无需人为回收,进程结束自动回收内存
singleHungry singleHungry::s_instacne(1,2);
singleHungry& singleHungry::getInstacne()
{return s_instacne;
}

懒汉模式


//懒汉模式,存在线程安全问题,需要加锁
class singleLazy
{
private:int dataA;int dataB;
private://构造函数私有化singleLazy(int a, int b):dataA(a),dataB(b){}//禁用默认拷贝构造、赋值运算符函数singleLazy(const singleLazy& s) = delete;singleLazy& operator= (const singleLazy& s) = delete;
public:~singleLazy(){}//互斥锁解决线程安全问题static mutex s_mute; //智能指针管理对象,解决内存泄漏问题static shared_ptr<singleLazy> s_instance;static shared_ptr<singleLazy> createInstance();//业务逻辑int getSubResult(){int result = dataA - dataB;cout<<"sub result = "<<result<<endl;return result;}
};//静态变量需要在类外进行初始化
mutex singleLazy::s_mute;
shared_ptr<singleLazy> singleLazy::s_instance = nullptr;
shared_ptr<singleLazy> singleLazy::createInstance()
{if (nullptr == s_instance) //未构造{s_mute.lock();cout<<"first structure"<<endl;s_instance = shared_ptr<singleLazy>(new singleLazy(3,4));s_mute.unlock();}else{cout<<"has structured"<<endl;}return s_instance;
}

完整代码如下:

#include <iostream>
#include <mutex>
#include <memory> 
using namespace std;

//饿汉模式,没有线程安全问题,无需加锁
class singleHungry
{
private:
    int dataA;
    int dataB;
private:
    //构造函数私有化
    singleHungry(int a, int b):dataA(a),dataB(b){}

//禁用默认拷贝构造、赋值运算符函数
    singleHungry(const singleHungry& s) = delete;
    singleHungry& operator= (const singleHungry& s) = delete;
public:
    ~singleHungry(){}
    static singleHungry s_instacne;
    static singleHungry& getInstacne();

//业务逻辑
    int getAddResult()
    {
        int result = dataA + dataB;
        cout<<"add result = "<<result<<endl;
        return result;
    }
};

//静态变量需要在类外进行初始化,由于对象是静态变量,存储在静态存储区,无需人为回收,进程结束自动回收内存
singleHungry singleHungry::s_instacne(1,2);
singleHungry& singleHungry::getInstacne()
{
    return s_instacne;
}

//懒汉模式,存在线程安全问题,需要加锁
class singleLazy
{
private:
    int dataA;
    int dataB;
private:
    //构造函数私有化
    singleLazy(int a, int b):dataA(a),dataB(b){}
    //禁用默认拷贝构造、赋值运算符函数
    singleLazy(const singleLazy& s) = delete;
    singleLazy& operator= (const singleLazy& s) = delete;
public:
    ~singleLazy(){}
    //互斥锁解决线程安全问题
    static mutex s_mute; 
    //智能指针管理对象,解决内存泄漏问题
    static shared_ptr<singleLazy> s_instance;
    static shared_ptr<singleLazy> createInstance();

//业务逻辑
    int getSubResult()
    {
        int result = dataA - dataB;
        cout<<"sub result = "<<result<<endl;
        return result;
    }
};

//静态变量需要在类外进行初始化
mutex singleLazy::s_mute;
shared_ptr<singleLazy> singleLazy::s_instance = nullptr;
shared_ptr<singleLazy> singleLazy::createInstance()
{
    if (nullptr == s_instance) //未构造
    {
        s_mute.lock();
        cout<<"first structure"<<endl;
        s_instance = shared_ptr<singleLazy>(new singleLazy(3,4));
        s_mute.unlock();
    }
    else
    {
        cout<<"has structured"<<endl;
    }

return s_instance;
}

//客户端
int main()
{
    //饿汉模式
    singleHungry::getInstacne().getAddResult();

//懒汉模式
    singleLazy::createInstance()->getSubResult();
    singleLazy::createInstance()->getSubResult();
    return 0;
}

【采用单例模式动机、原因】
      对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。如在Windows中就只能打开一个任务管理器。如果不使用机制对窗口对象进行唯一化,将弹出多个窗口,如果这些窗口显示的内容完全一致,则是重复对象,浪费内存资源;如果这些窗口显示的内容不一致,则意味着在某一瞬间系统有多个状态,与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。因此有时确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。
      如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。

C++单例模式 : 懒汉模式 与 饿汉模式相关推荐

  1. C++设计模式--单例模式详解(懒汉模式、饿汉模式、双重锁)

    C++设计模式--单例模式详解(懒汉模式.饿汉模式.双重锁) 应用场景 一.单例模式是什么? 二.使用步骤 1.UML图 2.代码实现 应用场景 通常我们在做通讯的时候,我们跟服务器数据交互,假如每次 ...

  2. 2023-01-26 JS设计模式-单例模式:单例模式的原理和实现,懒汉模式和饿汉模式,单例模式实现登录框

    文章目录 1.什么是单例模式? 介绍 特点 结构 2.如何实现一个单例模式? 思路 实现代码 3.单例模式的优缺点 4.懒汉模式和饿汉模式 懒汉模式:一开始不会实例化,什么时候用才new出来实例化 饿 ...

  3. 大聪明教你学Java设计模式 | 第一篇:单例模式 (懒汉模式和饿汉模式)

    前言 大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案.大聪明本着"独乐乐不如众乐乐"的宗旨与大家分享一下设计模 ...

  4. 单例模式的C++实现(懒汉模式和饿汉模式的详细讲解和实现)

    文章目录 前言 一.单例模式的概念 1.2单例模式的分类 1.2懒汉和饿汉的利弊 二.代码实现 1.饿汉模式 2.懒汉模式 总结 前言 提示:单例模式的出现.由于在某些场景中你最多而且必须有一个对象存 ...

  5. C# 设计模式之单例模式(懒汉模式、饿汉模式、静态内部类模式)

    C# 设计模式之单例模式(懒汉模式.饿汉模式.静态内部类模式) 应用场景:在整个软件运行生命周期内,一个类只允许一次实例化,例如数据库连接池的连接对象创建:通过使用单例模式来避免反复创建连接对象,从而 ...

  6. Java 懒汉模式与饿汉模式

    懒汉模式与饿汉模式 1.饿汉模式demo 来了就要吃,相当于有现成的- public class EleManSingleton { //1.创建类的唯一实例,使用private static修饰 p ...

  7. 单例模式---懒汉模式与饿汉模式

    单例模式:1)一个类只能创建一个实例2)构造函数和静态变量(加载类时即初始化)需为private3)get方法应该为public static,可供全局访问 //懒汉模式 public class l ...

  8. 设计模式——单例模式(懒汉模式,饿汉模式)

    声明: 本博客参考C语言中文网和优秀博客总结得出: (1)C语言中文网链接 (2)优秀博客链接 单例模式的定义: 指一个类只有一个实例,且该类能自行创建这个实例的一种模式.例如,Windows 中只能 ...

  9. 单例模式(懒汉模式和饿汉模式)

    单例模式 单例模式的两种方式 1.饿汉模式 2.懒汉模式 懒汉模式代码

最新文章

  1. java中ContentArea_java中TextArea怎么加载指定路径的文本内容
  2. 得到Android设备的唯一id
  3. mysql flush 使用
  4. ORM框架通过映射(反射)获取数据库的数据
  5. Cent OS yum 安装 Adobe flash player
  6. python做一个系统代码_python初学者,用python3实现基本的学生管理系统代码实例...
  7. 联想服务器自动关机_IBM 联想 DELL HP服务器自动关机|解决办法整理
  8. java 中文 转义_java下载url路径包含中文需要转义的操作
  9. 已修复的bug: 简书文章长标题换行异常,标题配图异常,首页配图异常
  10. Atitit  自动化gui 与 发帖机 技术
  11. 灵格斯!优秀的翻译软件!!!
  12. SL400在win7系统下硬盘安装Mac OS
  13. SX1278超时设置与计算
  14. 【OSX】MAC下能用的炒股软件_我是亲民_新浪博客
  15. 树莓派GPIO 基础(二)
  16. 轮盘赌算法原理(ACO算法概率选择方法)
  17. 【Quectel移远展锐平台5G模组RX500U/RG200U使用指南(一)】
  18. 室内空气流动原理图_新风系统工作原理图—新风系统工作原理介绍
  19. 电磁阀怎么使用 电磁阀的要求有哪些
  20. SocketTools库版,资源重定向的处理

热门文章

  1. 安卓手机USB调试模式打开方法
  2. 三层交换机实现多网段(VLAN)互通和某些网段限制通信
  3. Oracle入门笔记(三)——Oracle数据类型
  4. 用 Python 进行办公自动化都需要学习什么知识
  5. JavaScript入门基础2
  6. CDH6.3整合Carbondata
  7. 西门子博途安装服务器未响应,博途V13.0安装过程中出错
  8. WinCC flexible 2008项目移植到博途WinCC的具体方法
  9. 关于2的1000次方
  10. 使用Verilog语言描述计数器——脉动计数器;脉动计数器具有减法计数功能。采用模块设计和行为级设计方法。