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

(一)创建型设计模式:2、单例模式(C++实现实例 线程安全)

目录

1、单例模式(Singleton Pattern)的含义

2、单例模式的优缺点

(1)优点:

(2)缺点:

3、C++实现单例模式的示例(简单)

4、C++实现单例模式的示例(实际项目中使用)

(1)构造一个单例基类(无线程安全)

(2)构造一个单例基类(二次保证线程安全)

(3)目标类成为单例类,继承这个单例类即可

(4)如何使用这个目标单例类


1、单例模式(Singleton Pattern)的含义

(1)单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。

(2)单例模式的主要目的是限制一个类的实例化次数,以便在整个应用程序中共享该实例。它常用于需要全局访问某个对象的场景,例如日志记录器、数据库连接池等。

2、单例模式的优缺点

(1)优点:

1)全局访问:单例模式可以提供一个全局访问点,使得其他对象可以方便地访问该实例。

2)节省资源:由于单例模式只创建一个实例,可以节省系统资源,特别是在需要频繁创建和销毁对象的场景下。

3)数据共享:单例模式可以实现数据的共享,多个对象可以共享同一个实例,避免了数据不一致的问题。

4)延迟实例化:单例模式可以延迟实例化,即在第一次使用时才创建实例,提高了系统的性能和效率。

(2)缺点:

1)难以扩展:由于单例模式只允许存在一个实例,因此扩展时可能会受到限制。

2)违反单一职责原则:单例模式将创建实例和业务逻辑耦合在一起,违反了单一职责原则,增加了代码的复杂性和维护成本。

3)对象生命周期管理困难:由于单例模式的实例在整个应用程序的生命周期中存在,因此对其生命周期的管理可能较为困难。

4)可能引发线程安全问题:在多线程环境下,如果没有正确处理并发访问的情况,可能会引发线程安全问题。

因此,在使用单例模式时需要权衡其优缺点,并根据具体的业务需求和场景来决定是否使用。

3、C++实现单例模式的示例(简单)

class Singleton 
{
private:static Singleton* instance; // 静态成员变量,保存唯一实例的指针// 将构造函数和拷贝构造函数声明为私有,防止外部直接实例化和复制对象Singleton() {}Singleton(const Singleton& other) {}public:static Singleton* getInstance(){if (instance == nullptr){instance = new Singleton();}return instance;}void someMethod() {// 单例类的其他方法}
};Singleton* Singleton::instance = nullptr; // 初始化静态成员变量int main() 
{Singleton* obj1 = Singleton::getInstance(); // 获取单例实例obj1->someMethod(); // 调用单例对象的方法Singleton* obj2 = Singleton::getInstance(); // 再次获取单例实例,与obj1相同return 0;
}

在上述示例中,通过将构造函数和拷贝构造函数声明为私有,外部无法直接实例化和复制对象。通过静态成员变量instance保存唯一实例的指针,并提供静态方法getInstance()来获取该实例。

4、C++实现单例模式的示例(实际项目中使用)

(1)构造一个单例基类(无线程安全)

/*
单例类
*/
#pragma once
#include <map>
#include <string>
#include <vector>
using namespace std;template <typename T>
class SingleTon
{
public:static T* getInstance(){if (NULL == m_pInstance){//m_singleCS.Lock();if (NULL == m_pInstance){m_pInstance = new T();}//m_singleCS.Unlock();}return m_pInstance;}protected:SingleTon(void){}virtual ~SingleTon(void){if (NULL != m_pInstance){delete m_pInstance;m_pInstance = NULL;}}static T* m_pInstance;private:SingleTon(const SingleTon&);SingleTon& operator = (const SingleTon&);
};template <typename T>
T* SingleTon<T>::m_pInstance = NULL;

(2)构造一个单例基类(二次保证线程安全)

/** @Description: 单例类工厂* @Author: Ivy* @Date: 2023-05-09 09:34:43* @LastEditTime: 2023-02-24 11:28:29* @LastEditors: XTZJ-2022OQEHLZ*/
#pragma once
#include <vector>
#include <string>
#include <iostream>
#include <QMutex>using namespace std;
template <typename T>
class Singleton
{
public:static T* getInstance(){if (m_pInstance == NULL){// 二次保证线程安全m_pMutexCreate.lock();if (m_pInstance == NULL){m_pInstance = new T();}m_pMutexCreate.unlock();}return m_pInstance;}// 尽量多的将单例共有的方法放到基类,子类继承即可virtual void startWork() {}
protected:Singleton() {}virtual ~Singleton(){if (m_pInstance != NULL){delete [] m_pInstance;m_pInstance = NULL;}}static T* m_pInstance;static QMutex m_pMutexCreate;QMutex m_mutex;
private:Singleton(const Singleton&);Singleton& operator =(const Singleton&);public:void lock() { m_mutex.lock(); }void unLock() { m_mutex.unlock(); }
};template <typename T>
QMutex Singleton<T>::m_pMutexCreate;template <typename T>
T* Singleton<T>::m_pInstance = NULL;

(3)目标类成为单例类,继承这个单例类即可

/** @Description: XXX 管理类*/
#pragma once
#include "Singleton.h"class testManager : public Singleton<testManager>
{friend class Singleton<testManager>;//要声明友元类public:virtual ~testManager();void getData();void setData();private:testManager();
}

(4)如何使用这个目标单例类

// 实例演示:包含该类的头文件
testManager::getInstance()->getData();

相关文章:

(一)创建型设计模式:2、单例模式(C++实现实例 线程安全)

目录 1、单例模式&#xff08;Singleton Pattern&#xff09;的含义 2、单例模式的优缺点 &#xff08;1&#xff09;优点&#xff1a; &#xff08;2&#xff09;缺点&#xff1a; 3、C实现单例模式的示例&#xff08;简单&#xff09; 4、C实现单例模式的示例&#xff…...

《练习100》86~90

题目86 # 生成一个包含20个随机整数&#xff08;100以内&#xff09;的列表&#xff0c;对其中偶数索引&#xff08;下标&#xff09;的数据进行降序排列&#xff0c;奇数索引的元素不变 import random list1 [random.randint(0,100) for _ in range(20)] list2 list1[::2] …...

C++——命名空间、输入、输出

在我们接触C之前&#xff0c;C语言中有时候会有使用全局变量&#xff0c;全局变量在使用过程中可能会发生冲突&#xff0c;这个冲突有时会是我们与库之间的冲突&#xff0c;有时又会是我们自己定义的之间的冲突&#xff0c;那么这时候命名空间的出现将很好的解决这个问题&#…...

解锁滴滴ES的性能潜力:JDK 17和ZGC的升级之路

前文介绍了滴滴自研的ES强一致性多活是如何实现的&#xff0c;其中也提到为了提升查询性能和解决查询毛刺问题&#xff0c;滴滴ES原地升级JDK17和ZGC&#xff0c;在这个过程中我们遇到了哪些问题&#xff0c;怎样解决的&#xff0c;以及最终上线效果如何&#xff0c;这篇文章就…...

Permutation and Primes 2023牛客暑期多校训练营8 J

登录—专业IT笔试面试备考平台_牛客网 题目大意&#xff1a;给出一个数n&#xff0c;要求构造一个n的排列&#xff0c;满足相邻两个数的差或和是一个奇质数 2<n<1e5 思路&#xff1a;要满足相邻数的差或和是奇质数的话只有三种情况&#xff0c;要么当前数a[i]a[i-1]pr…...

centos如何配置IP地址?

CentOS如何查看和临时配置IP地址 CentOS系统中&#xff0c;可以通过使用ifconfig命令来查看当前本机的IP地址信息。输入ifconfig即可显示当前网络接口的IP地址、网络掩码和网关信息。如果需要设置临时IP地址&#xff0c;可以使用ifconfig命令后接网卡名称和需要设置的IP地址、网…...

git clone 报错Filename too long

1.使用git clone代码&#xff0c;爆出Filename too long错误 2.原因分析 因为我很少看git clone日志&#xff0c;所以从未想过是clone异常&#xff0c;而且也看到代码clone下来了&#xff0c;所以我就显然以为代码clone成功&#xff0c;但是使用idea打开代码后发现大量代码无法…...

【雕爷学编程】Arduino动手做(184)---快餐盒盖,极低成本搭建机器人实验平台3

吃完快餐粥&#xff0c;除了粥的味道不错之外&#xff0c;我对个快餐盒的圆盖子产生了兴趣&#xff0c;能否做个极低成本的简易机器人呢&#xff1f;也许只需要二十元左右 知识点&#xff1a;轮子&#xff08;wheel&#xff09; 中国词语。是用不同材料制成的圆形滚动物体。简…...

redis String类型命令

Redis的String类型是一种简单的键值对数据结构&#xff0c;常用的String类型命令有&#xff1a; SET key value&#xff1a;设置指定key的值为value。GET key&#xff1a;获取指定key的值。DEL key&#xff1a;删除指定key及其对应的值。INCR key&#xff1a;将指定key的值加1…...

Blazor 简单组件(0):简单介绍

文章目录 前言说明环境安装 前言 Blazor 这个技术还是比较新&#xff0c;相关的UI组件还在完善&#xff0c;我这里提供一下我个人的组件开发。 说明 本UI组件是基于BootstrapBlazor(以下简称BB)开发。 BootstrapBlazor 文档 环境安装 C#小轮子&#xff1a;Visual Studio自…...

在vue3+vite项目中使用jsx语法

如果我掏出下图&#xff0c;阁下除了私信我加入学习群&#xff0c;还能如何应对&#xff1f; 正文开始 前言一、下载资源二、利用vite工具引入babel插件总结 前言 最近在为部署人员开发辅助部署的工具&#xff0c;技术栈是vue3viteelectron&#xff0c;在使用jsx语法时&#x…...

HCIA 路由器工作原理 及其 静态路由配置

目录 1、路由器工作原理 2、获取未知网段的方法&#xff1a; 3、静态路由 1&#xff09;写法&#xff1a; 2&#xff09;扩展配置 a、环回接口 配置命令&#xff1a; 环回接口的作用&#xff1a; b、手工汇总 手工汇总作用&#xff1a; c、路由黑洞 d、缺省路由 配置…...

【Git】—— git的配置

目录 &#xff08;一&#xff09;忽略特殊⽂件 &#xff08;二&#xff09;给命令配置别名 &#xff08;一&#xff09;忽略特殊⽂件 在⽇常开发中&#xff0c;我们有些⽂件不想或者不应该提交到远端&#xff0c;⽐如保存了数据库密码的配置⽂件&#xff0c;那怎么让Git知道呢…...

[git] git基础知识

git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目 git易于学习&#xff0c;性能极快 什么是版本控制&#xff1f; 版本控制是一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况&#xff0c;可以记录文件修改历史…...

【从零学习python 】15.深入了解字符串及字符集编码

文章目录 字符集字符和编码相互转换编码规则 学习目标成员运算符in运算符not in 运算符 进阶案例 字符集 计算机只能处理数字(其实就是数字0和数字1)&#xff0c;如果要处理文本&#xff0c;就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特&#xff08;bi…...

【LeetCode】打家劫舍||

打家劫舍|| 题目描述算法分析编程代码 链接: 打家劫舍|| 在做这个题之前&#xff0c;建议大家做一下这个链接: 按摩师 我的博客里也有这个题的讲解&#xff0c;名字是按摩师 题目描述 算法分析 编程代码 class Solution { public:int maxrob(vector<int>nums,int left,…...

【Nginx】Nginx的重定向——location

location 匹配URI location 匹配的规则和优先级&#xff1b;***重点 nginx常用的变量&#xff1b;要求掌握 rewrite 重定向&#xff1b;掌握/理解 location匹配&#xff1a;*** 正则表达式&#xff1a;匹配的是文件内容 常见的正则表达式&#xff1a…...

每日一题——滑动窗口的最大值

滑动窗口的最大值 题目链接 暴力解法 最容易想到的当然还是通过两层循环来暴力求解&#xff1a;一层循环用来移动窗口&#xff0c;一层循环用来在窗口内找到最大值。这种做法的时间复杂度为O(kN)&#xff0c;会超出时间限制&#xff0c;因此&#xff0c;我们要找到更加高效的…...

【使用go开发区块链】之获取链上数据(03)

上篇文章&#xff0c;我们完成了数据库的连接&#xff0c;本章节&#xff0c;我们将完成ethclient的配置以及初始化 1、ethclient配置 1.1、安装go-ethereum 在命令行终端输入下面代码安装&#xff1a; go get github.com/ethereum/go-ethereum1.2、Ethclient配置 1.2.1、新…...

js 动态设置transformOrigin

transformOrigin属性用于指定元素变换的原点。 // 获取要设置的元素 const element document.getElementById(your-element-id);// 设置transformOrigin属性 element.style.transformOrigin 50% 50%; // 以元素中心为原点// 或者使用变量来设置 const x 0; // x坐标 const …...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...