当前位置: 首页 > news >正文

【C++设计模式】(三)创建型模式:单例模式

文章目录

  • (三)创建型模式:单例模式
    • 饿汉式
    • 懒汉式
    • 饿汉式 v.s. 懒汉式

(三)创建型模式:单例模式

单例模式在于确保一个类只有一个实例,并提供一个全局访问点来访问该实例。在某些情况下,某些代码组件(如线程池,日志记录器)需要在整个应用程序中共享,使用单例模式可以实现组件资源的复用,并简化系统设计。

单例模式实现方式主要包括饿汉式和懒汉式两种。

饿汉式

饿汉式是指在类加载的时候就创建单例实例,不管后续是否会使用这个实例。

class Singleton {
private:static Singleton* instance; // 静态成员变量,属于类本身而不是类的任何特定对象Singleton() {}              // 私有构造函数防止外部实例化public:static Singleton* getInstance() {  // 全局访问点return instance;}
};Singleton* Singleton::instance = new Singleton();  // 在静态成员变量初始化时创建实例

在多线程环境下,饿汉式是线程安全的,因为实例在类加载时就已经创建好了,不存在并发访问创建实例的问题。

示例:

#include <iostream>  class Singleton {  
private:  static Singleton instance; // 静态实例,在类加载时构造  Singleton() {} // 私有构造函数  public:  static Singleton& getInstance() {  return instance;  }  void doSomething() {  std::cout << "Doing something..." << std::endl;  }  
};  Singleton Singleton::instance; // 静态实例初始化  int main() {  Singleton& s1 = Singleton::getInstance();  Singleton& s2 = Singleton::getInstance();  if (&s1 == &s2) {  std::cout << "s1 and s2 are the same instance" << std::endl;  }  s1.doSomething();  return 0;  
}
s1 and s2 are the same instance
Doing something...

懒汉式

懒汉式是指在第一次使用时才会创建单例实例,实例的创建被延迟到第一次使用 getInstance() 方法时。

class Singleton {
private:static Singleton* instance;Singleton() {}  public:static Singleton* getInstance() {if (instance == nullptr) { // 第一次使用时才会创建单例实例instance = new Singleton();}return instance;}
};Singleton* Singleton::instance = nullptr;

示例:

#include <iostream>  class Singleton {  
private:  static Singleton* instance;  Singleton() {} // 私有构造函数  public:  static Singleton* getInstance() {  if (instance == nullptr) {  instance = new Singleton();  }  return instance;  }  ~Singleton() {  delete instance; // 注意:在程序结束时需要确保只调用一次析构函数  instance = nullptr;  }  void doSomething() {  std::cout << "Doing something..." << std::endl;  }  
};  Singleton* Singleton::instance = nullptr; // 静态成员变量初始化  int main() {  Singleton* s1 = Singleton::getInstance();  Singleton* s2 = Singleton::getInstance();  if (s1 == s2) {  std::cout << "s1 and s2 are the same instance" << std::endl;  }  s1->doSomething();  return 0;  
}
s1 and s2 are the same instance
Doing something...

懒汉式在多线程环境下是不安全的,因为多个线程可能同时进入判断条件,导致创建多个实例。因此,需要通过加锁等机制来保证线程安全:

 static std::mutex mtx;static Singleton* instance;Singleton* Singleton::getInstance() {// 使用互斥锁(`std::mutex`)来保证只有一个线程能够创建实例。std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}return instance;}

为了避免每次调用都加锁,产生额外的性能开销,可以在加锁的基础上,进行双重检查:

  static std::mutex mtx;static Singleton* instance;Singleton* Singleton::getInstance() {if (instance == nullptr) {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}}return instance;}

饿汉式 v.s. 懒汉式

在饿汉式单例模式中,单例的实例在程序启动时就立即创建。这种方式的好处在于它的简单性和线程安全性(无需额外的同步机制)。

在懒汉式单例模式中,单例的实例是在首次被需要时才被创建。这种方式的好处在于它可以延迟实例的创建,从而减少程序启动时的资源消耗和初始化时间。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 构建智能化Web应用防火墙与自动化攻击测试系统
  • 医院建筑的电气设计——保障医疗质量与安全的坚固基石
  • 点餐API接口对接的过程中需要注意哪些问题
  • 数据结构与算法---排序算法
  • 使用统计方法在AMD GPU上使用JAX Profiler可靠地比较大型生成AI模型中的算法性能
  • 详解PyTorch中的`remove_self_loops`函数及其在图神经网络中的应用
  • 白手起家的七个逆向思维
  • 软件测试 | 测试用例
  • SpringCloud Alibaba】(十三)学习 RocketMQ 消息队列
  • 003.精读《MapReduce: Simplified Data Processing on Large Clusters》
  • Npm install 原理
  • Dockerfile应用、私有仓库
  • 昇腾AI处理器的计算核心 - AI Core即DaVinci Core
  • 机器学习数学公式推导之高斯分布
  • 逆向工程核心原理 Chapter22 | 恶意键盘记录器
  • 【mysql】环境安装、服务启动、密码设置
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Bootstrap JS插件Alert源码分析
  • canvas 五子棋游戏
  • echarts花样作死的坑
  • Effective Java 笔记(一)
  • ES6 学习笔记(一)let,const和解构赋值
  • extjs4学习之配置
  • js中的正则表达式入门
  • nodejs调试方法
  • Promise初体验
  • Vue.js-Day01
  • Xmanager 远程桌面 CentOS 7
  • Zepto.js源码学习之二
  • 彻底搞懂浏览器Event-loop
  • 机器学习中为什么要做归一化normalization
  • 区块链将重新定义世界
  • 我从编程教室毕业
  • 智能合约Solidity教程-事件和日志(一)
  • 交换综合实验一
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​卜东波研究员:高观点下的少儿计算思维
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • ( 10 )MySQL中的外键
  • (02)vite环境变量配置
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (C语言)字符分类函数
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (多级缓存)缓存同步
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (四) Graphivz 颜色选择
  • (四)库存超卖案例实战——优化redis分布式锁
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)可以带来幸福的一本书
  • ***监测系统的构建(chkrootkit )