首页 > 其他分享 >设计模式--单例模式

设计模式--单例模式

时间:2024-02-04 17:24:51浏览次数:29  
标签:Singleton -- instance 实例 static 单例 设计模式 加载

目录


概念

单例模式(Singleton Pattern)是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在C++中,单例模式通常用于管理全局资源或提供全局配置。


使用场景

以下是C++中实现单例模式的常见方法:

  1. 饿汉式单例模式:
    饿汉式是一种实现单例模式的策略,其特点是全局的单例实例在类装载时构建。这种方式的优点是类加载比较快,因为实例化工作在类加载时就已经完成。但缺点是如果该类从未被使用,则实例化会造成不必要的性能开销。
class Singleton {
public:
    static Singleton& getInstance() {
        // 在类加载时就完成了初始化,所以类加载比较频繁时可能会造成性能问题
        static Singleton instance;
        return instance;
    }
    
    // 其他成员函数...
    
private:
    Singleton() {}  // 私有构造函数,防止外部直接实例化
    Singleton(const Singleton&) = delete;  // 禁止拷贝构造函数
    Singleton& operator=(const Singleton&) = delete;  // 禁止拷贝赋值运算符
};
  1. 懒汉式单例模式:
    懒汉式是一种延迟加载的单例模式实现方式,其特点是在第一次使用时创建实例对象,而不是在类加载时就创建。这种方式的优点在于只有在真正需要时才会进行实例化,可以节省内存空间。但如果类被频繁地加载和卸载,懒汉式可能会造成不必要的性能开销。
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton* instance = nullptr;  // 延迟初始化
        if (instance == nullptr) {
            instance = new Singleton();  // 懒加载,只会在第一次调用时创建实例
        }
        return *instance;
    }
    
    // 其他成员函数...
    
private:
    Singleton() {}  // 私有构造函数,防止外部直接实例化
    Singleton(const Singleton&) = delete;  // 禁止拷贝构造函数
    Singleton& operator=(const Singleton&) = delete;  // 禁止拷贝赋值运算符
};
  1. 双重检查锁定(线程安全):
    双重检查锁定(Double-Checked Locking)是一种在单例模式中使用的性能优化技术。这种技术旨在在并发环境下提高单例对象的创建效率,同时确保线程安全。
    双重检查锁定的基本思想是在获取单例对象时进行双重检查,即先检查实例是否已经创建,如果尚未创建,再进行同步操作来确保只有一个线程创建实例。这样可以在不必要时避免同步开销,提高性能。这种技术在单例对象的初始化上实现了懒加载(Lazy Initialization),即对象直到第一次被访问时才进行初始化。
    需要注意的是,在使用双重检查锁定时,需要特别注意内存模型的细节,以避免出现线程安全问题。例如,需要使用volatile关键字来确保对共享变量的正确读写,以及使用锁来保护临界区代码等。同时,由于双重检查锁定涉及到多线程编程的复杂性,因此在使用时需要谨慎处理线程同步和竞争条件的问题。
    为了在多线程环境下安全地实现单例模式,可以使用双重检查锁定机制。在C++11及更高版本中,可以使用std::call_once来实现。以下是一个示例:
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton* instance = nullptr;  // 延迟初始化
        std::call_once(initInstanceFlag, &Singleton::initInstance);  // 使用std::call_once确保只初始化一次实例
        return *instance;
    }
    
    // 其他成员函数...
    
private:
    Singleton() {}  // 私有构造函数,防止外部直接实例化
    Singleton(const Singleton&) = delete;  // 禁止拷贝构造函数
    Singleton& operator=(const Singleton&) = delete;  // 禁止拷贝赋值运算符
    static void initInstance() { instance = new Singleton(); }  // 静态成员函数,用于初始化实例(只执行一次)
    static std::once_flag initInstanceFlag;  // 静态成员变量,用于控制初始化实例的执行次数(只执行一次)
};

标签:Singleton,--,instance,实例,static,单例,设计模式,加载
From: https://www.cnblogs.com/yubo-guan/p/18006608

相关文章

  • map
    `include<bits/stdc++.h>usingnamespacestd;intn;map<int,int>mp;intmain(){cin>>n;vectorv(n);for(inti=0;i<n;i++){cin>>v[i];mp[v[i]]++;}intcount=0;for(inti=0;i<n;i++){v[i]+=9;mp[v[i]]++;if(mp[v[i]]!=1)......
  • NPM -  WARN  GET https://registry.npm.taobao.org/vite error (CERT_HAS_EXPIRED)
    切换了镜像源但依旧还是之前的,需要移除项目中的node_modules,重新下载依赖。可以通过rimrafnode_modules移除:重新下载依赖一切正常:......
  • AtCoder Beginner Contest 339
    基本情况A和C出的比较快但不能说秒了还是思考了几分钟的,然后B很奇怪我样例还有一些测试点都能过,但有些测试点就是过不了...A-TLD貌似没啥说的B-Langton'sTakahashi说实话现在还是不懂我的哪里错了很不科学啊,明明很多测试点都过了啊C-PerfectBus做题时的思路:要想求......
  • UniGUI 将Excel表上传,并将数据导入SQL(转)
    UniGUI将Excel表上传,并将数据导入SQL(转)采用第三方控件XLSReadWriteII实现导入数据的办法1、首先将Excel文件上传至服务器;在表单中添加UniFileUpload和XLSReadWriteII控件procedureTck_tz.UniLabel4Click(Sender:TObject);beginUniFileUpload1.Execute;end;2、用XLSR......
  • 在PowerShell中管理Windows映像主要涉及到DISM模块的Cmdlets。这些Cmdlets提供了一系
    在PowerShell中管理Windows映像主要涉及到DISM模块的Cmdlets。这些Cmdlets提供了一系列功能,包括挂载(加载)、卸载(卸下)映像,添加或删除驱动程序,应用更新等。以下是一些常用的Cmdlets和它们的参数,以及相应的实例。常用CmdletsMount-WindowsImage-ImagePath:指定WIM文件的路径。-I......
  • 东北师大附中 集训游记
    update文笔稚嫩谨慎观看。东北师大附中集训游记但是去的时候到处都在翻修(小声bb)。Day1早上一来就要先考试,太离谱了。根本没准备\(qaq\)。于是就开始刚题,第一题写了半天,感觉推出来的结论超级无敌对,但是却只拿了10分。第二题没思路,放弃了。第三题读完题也挺离谱,写了个......
  • Kali Linux 折腾记
    本篇文章在KaliLinux2022.2Firefox浏览器下写作前话放暑假在家,虽然也没闲着几天,但是看着自己手头上的没用的电脑,感觉总得干点什么好,于是我就想到了装linux系统。但是linux有这么多发行版,用什么好?一开始实际上我想到的是archlinux,但是安装好像有点麻烦,后边又想到了......
  • 学习MarkDown
    MarkDown学习标题三级标题字体HelloWord!(加粗:两边两个*)HelloWord!(斜体:两边一个*)HelloWord!(斜体且加粗:三个*)HelloWord!(字体划线:两边两个~)引用大于号后面写内容用来摘抄引用分割线用三个-或者三个*图片用感叹号加中括号加括号(名字+地址)![图片](C:\Users\2......
  • SNOI 2024 幽默记
    先贴个我之前写的幽默NOIP游记吧!T1开考看了一眼,随便想了一会就有思路了。用stl搞了一下,大概开考后20min过掉所有大样例。然后就对着剩下三道题沉默了一整场考试。感觉T3是个数据结构,长得比较眉清目秀,就先去看了T3,但是越看越迷惑,没什么思路,就扔了去想T2。理解了一......
  • EasyExcel读取resources下多个excel文件的解决办法
    最近新的业务是需要读取resources下的excel文件并入库,没有做过类似的所以踩了很多坑话不多说开始:使用ResourcePatternResolver解析该目录下的多个excel文件  读取之后直接使用EasyExcel读取文集文件并且转换为实体对象,这里只需要注意些一个ExcelListener()监听器,具体怎么写这......