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

c++两种设计模式 单例和工厂模式

c++两种设计模式 单例和工厂模式

一.单例

1.单例的概念

1.当前的类最多只能创建一个实例

2.当前这个唯一的实例,必须由当前类创建(自主创建),而不是调用者创建

3.必须向整个系统提供全局的访问点,来获取唯一的实例

2.单例的代码

#include <iostream>
using namespace std;class CSingleton {CSingleton(){}CSingleton(const CSingleton&) = delete;//弃用拷贝构造函数static CSingleton* m_spring;~CSingleton() {}
public:static struct DeleteSingleton {//保证申请的堆空间一定被回收~DeleteSingleton() {if(m_spring)delete m_spring;m_spring = nullptr;}} del;//静态对象,在程序结束时静态对象会自动被回收,然后就会调用析构函数,就一定能保证申请的堆空间被回收//有问题的代码,在多线程下,可能会创建多个对象static CSingleton* CreatCSingleton() {//加锁if (!m_spring) {//如果指针为空,则创建对象m_spring = new  CSingleton;}//解锁return m_spring;}static void DestoryCSingleton(CSingleton*& psin) {if (m_spring)delete m_spring;m_spring = nullptr;psin = nullptr;}/*~CSingleton() {//这里不能使用析构进行回收,这里回收的是对象,这样的话就会不断的调用析构if (m_spring) {delete m_spring;m_spring = nullptr;}}*/};
CSingleton::DeleteSingleton CSingleton::del;//类外定义初始化, 格式: 类型 类名::静态变量名
CSingleton* CSingleton:: m_spring(nullptr);int main() {//主函数进行测试CSingleton* p1 = CSingleton::CreatCSingleton();CSingleton* p2 = CSingleton::CreatCSingleton();cout << p1 << "   " << p2 << endl;CSingleton::DestoryCSingleton(p1);return 0;
}

3.懒汉式和饿汉式

懒汉式:当第一次调用这个接口函数时,先创建单例 时间换空间的做法

饿汉式:无论是否调用获取单例接口函数,都会提前创建单例 空间换时间的做法

懒汉式代码就是上面的代码

饿汉式代码

//饿汉式
class CSingleton {CSingleton() {}CSingleton(const CSingleton&) = delete;static CSingleton sing;~CSingleton() {}
public:static CSingleton* CreatCSingleton() {return &sing;}
};CSingleton CSingleton::sing; 

4.单例模式的优点

1.单例模式提供了严格的对唯一实例的创建,访问和销毁,安全性高

2.单例模式的实现可以节省系统资源

二.工厂模式

1.概念

工厂模式主要用来集中创建对象的,如果在任何使用的地方创建对象那就造成了类或方法之间的耦合,如果要更换对象那么在所有使用到的地方都要修改一遍,不利于后期的维护,也违背了开闭设计原则,如果使用工厂来创建对象,那么就彻底解耦合了,如果要修改著需要修改工厂类即可,工厂模式最大的优势:解耦

2.简单工厂

class CEngine {
public:virtual void woring() = 0;
};class  CEngine2L: public CEngine {void woring() {cout<<"2.0自然吸气发动机正在工作" <<endl;}
};class CEngine2T : public CEngine {void woring() {cout<<"2.0涡轮增压发动机正在工作" << endl;}class CCar {
public:CEngine* m_engine;CCar():m_engine(new CEngine2L){}CCar(const string&type) :m_engine(type=="2.0L"?(CEngine*)new CEngine2L: (CEngine*)new CEngine2T) {}//这里发生了耦合void dirve() {if (m_engine) {m_engine->woring();cout << "汽车正在行驶" << endl;}}~CCar() {if (m_engine) {delete m_engine;m_engine = nullptr;}}
};
int main() {CCar tst1;CCar tst2("2.0L");tst1.dirve();tst2.dirve();
}

简单工厂就是在上面代码的基础上进行解耦

耦合这里来看就是:如果发动机函数增加参数的话,那么汽车类中与发动机函数有交互的函数的内容也需要改,就是牵一发而动全身

进行解耦代码为

class CEngine {
public:virtual void woring() = 0;
};class  CEngine2L : public CEngine {void woring() {cout << "2.0自然吸气发动机正在工作" << endl;}
};class CEngine2T : public CEngine {void woring() {cout << "2.0涡轮增压发动机正在工作" << endl;}
};
//创建发动机的具体代码写在这里
class CFactoryEngine {
public:CEngine* CreatEngine(const string& type) {if (type == "2.0L") {return new CEngine2L;}else if (type == "2.0T") {return new CEngine2T;}else {return nullptr;}}
};class CCar {
public:CEngine* m_engine;CCar() :m_engine(new CEngine2L) {}//引入简单工厂后的写法CCar(CFactoryEngine* pFac,const string& type):m_engine(pFac? pFac->CreatEngine(type):nullptr){}void dirve() {if (m_engine) {m_engine->woring();cout << "汽车正在行驶" << endl;}}~CCar() {if (m_engine) {delete m_engine;m_engine = nullptr;}}
};
int main(){CFactoryEngine Fac;CCar audi(&Fac, "2.0L");audi.dirve();CCar benzi(&Fac, "2.0L"); benzi.dirve();
}

3.工厂方法

工厂方法就是在简单工厂的基础上 把工厂进行细化 每个产品对应一个工厂(之前的简单工厂每有一个新产品就要将工厂的功能进行修改很麻烦,工厂进行细化之后,如果有新的产品我们只需要增加工厂的功能就行了)

代码如下

#include <iostream>
using namespace std;class CEngine {
public:virtual void woring() = 0;
};class  CEngine2L : public CEngine {void woring() {cout << "2.0自然吸气发动机正在工作" << endl;}
};class CEngine2T : public CEngine {void woring() {cout << "2.0涡轮增压发动机正在工作" << endl;}
};class CFactoryEngine {
public:virtual CEngine* CreatEngine() = 0;
};class CFactoryEngine2L :public CFactoryEngine {
public:virtual CEngine* CreatEngine() {return new CEngine2L;}};class CFactoryEngine2T :public CFactoryEngine {
public:virtual CEngine* CreatEngine() {return new CEngine2T;}};class CCar {
public:CEngine* m_engine;CCar() :m_engine(new CEngine2L) {}CCar(CFactoryEngine* pFac) :m_engine(pFac ? pFac->CreatEngine() : nullptr) {}void dirve() {if (m_engine) {m_engine->woring();cout << "汽车正在行驶" << endl;}}~CCar() {if (m_engine) {delete m_engine;m_engine = nullptr;}}
};int main() {CFactoryEngine* Fac2L = new CFactoryEngine2L;CFactoryEngine* Fac2T = new CFactoryEngine2T;CCar audi(Fac2L);audi.dirve();CCar benzi(Fac2T);benzi.dirve();return 0;
}

4.抽象工厂

抽象工厂就是在工厂方法的基础上将所有工厂统一管理

代码如下

#include <iostream>
using namespace std;class CEngine {
public:virtual void woring() = 0;
};class  CEngine2L : public CEngine {void woring() {cout << "2.0自然吸气发动机正在工作" << endl;}
};class CEngine2T : public CEngine {void woring() {cout << "2.0涡轮增压发动机正在工作" << endl;}
};class CGearBox {
public:virtual void woring() = 0;
};class  CGearBoxAuto : public CGearBox {void woring() {cout << "自动变速器正在工作" << endl;}
};class CGearBoxMaual : public CGearBox {void woring() {cout << "手动变速器正在工作" << endl;}
};
//加速器
class CFactoryEngine {
public:virtual CEngine* CreatEngine() = 0;
};class CFactoryEngine2L :public CFactoryEngine {
public:virtual CEngine* CreatEngine() {return new CEngine2L;}};class CFactoryEngine2T :public CFactoryEngine {
public:virtual CEngine* CreatEngine() {return new CEngine2T;}};//变速器
class CFactoryEngineGearBox {
public:virtual CGearBox* CreatBox() = 0;
};class CFactoryEngineGearBoxAuto :public CFactoryEngineGearBox {
public:virtual CGearBox* CreatBox() {return new CGearBoxAuto;}};class CFactoryEngineGearBoxMaual :public CFactoryEngineGearBox {
public:virtual CGearBox* CreatBox() {return new CGearBoxMaual;}};//统一工厂
class CFactory {
public:virtual CGearBox* CreatBox() = 0;virtual void woring() = 0;
};class CFactory2TAuto :public CFactory {
public:virtual CGearBox* CreatBox() {return new CGearBoxAuto;}virtual CEngine* CreatEngine() {return new CEngine2T;}
};class CFactory2TMaual :public CFactory {
public:virtual CGearBox* CreatBox() {return new CGearBoxMaual;}virtual CEngine* CreatEngine() {return new CEngine2T;}
};
class CCar {
public:CEngine* m_engine;CGearBox* m_gearbox;CCar() :m_engine(new CEngine2L) {}CCar(CFactoryEngine* pFacEngine, CFactoryEngineGearBox* pFacGearBox) :m_engine(pFacEngine ? pFacEngine->CreatEngine() : nullptr), m_gearbox(pFacGearBox ? pFacGearBox->CreatBox() : nullptr){}void dirve() {if (m_engine) {m_engine->woring();cout << "汽车正在行驶" << endl;}if (m_gearbox) {m_gearbox->woring();cout << "变速器正在工作" << endl;}}~CCar() {if (m_engine) {delete m_engine;m_engine = nullptr;}if (m_gearbox) {delete m_gearbox;m_gearbox = nullptr;}}
};int main() {CFactoryEngine* PFa1 = new CFactoryEngine2L;CFactoryEngineGearBox* PFa2 = new CFactoryEngineGearBoxAuto;CCar audi(PFa1,PFa2);audi.dirve();return 0;
}

相关文章:

c++两种设计模式 单例和工厂模式

c两种设计模式 单例和工厂模式 一.单例 1.单例的概念 1.当前的类最多只能创建一个实例 2.当前这个唯一的实例&#xff0c;必须由当前类创建&#xff08;自主创建&#xff09;&#xff0c;而不是调用者创建 3.必须向整个系统提供全局的访问点&#xff0c;来获取唯一的实例 …...

2023-08-05——JVM 栈

栈 stack 栈&#xff1a;数据结构 程序数据结构算法 栈&#xff1a;先进后出&#xff0c;后进先出 好比一个&#xff1a;桶 队列&#xff1a;先进先出&#xff08;FIFO &#xff1a;First Input First Out&#xff09; 好比一个&#xff1a;管道 栈&#xff1a;喝多了吐。队列…...

Camera之PhysicalCameraSettingsList/SurfaceMap/CameraMetadata/RequestList的关系(三十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…...

【ONE·Linux || 基础IO(二)】

总言 文件系统与动静态库相关介绍。 文章目录 总言2、文件系统2.1、背景知识2.2、磁盘管理2.2.1、磁盘文件系统图2.2.2、inode与文件名 2.3、软硬链接 3、动静态库3.1、站在编写库的人的角度&#xff1a;如何写一个库&#xff1f;3.1.1、静态库制作3.1.3、动态库制作 3.2、站在…...

【LeetCode 算法】Power of Heroes 英雄的力量

文章目录 Power of Heroes 英雄的力量问题描述&#xff1a;分析代码Math Tag Power of Heroes 英雄的力量 问题描述&#xff1a; 给你一个下标从 0 开始的整数数组 nums &#xff0c;它表示英雄的能力值。如果我们选出一部分英雄&#xff0c;这组英雄的 力量 定义为&#xff…...

合宙Air724UG LuatOS-Air script lib API--ntp

ntp Table of Contents ntp ntp.timeSync(period, fnc, fun) ntp 模块功能&#xff1a;网络授时. 重要提醒&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 本功能模块采用多个免费公共的NTP服务器来同步时间 并不能保证任何时间任何地点都能百分…...

LangChain+ChatGLM大模型应用落地实践(一)

LLMs的落地框架&#xff08;LangChain&#xff09;&#xff0c;给LLMs套上一层盔甲&#xff0c;快速构建自己的新一代人工智能产品。 一、简介二、LangChain源码三、租用云服务器实例四、部署实例 一、简介 LangChain是一个近期非常活跃的开源代码库&#xff0c;目前也还在快速…...

PSO粒子群优化算法

PSO粒子群优化算法 算法思想matlab代码python代码 算法思想 粒子群算法&#xff08;Particle Swarm Optimization&#xff09; 优点: 1&#xff09;原理比较简单&#xff0c;实现容易&#xff0c;参数少。 缺点: 1&#xff09;易早熟收敛至局部最优、迭代后期收敛速度慢的…...

记一次 .NET某医疗器械清洗系统 卡死分析

一&#xff1a;背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题&#xff0c;回过头来看这个案例比较经典&#xff0c;这篇稍微整理一下供后来者少踩坑吧。 二&#xff1a;WinDbg 分析 1. 为什么会卡死 因为是窗体程序&#xff0c;理所当然就是看主…...

C# 基于Rijndael对文件进行加解密

介绍&#xff1a; Rijndael 是一种对称加密算法&#xff0c;也是 AES&#xff08;Advanced Encryption Standard&#xff09;的前身。它用于数据的加密和解密&#xff0c;并提供了安全且高效的加密功能。 在.NET Framework 中&#xff0c;Rijndael 类是一个实现了 Rijndael 算法…...

Elasticsearchr入门

首先在官网下载elasticsearch8.9版本&#xff0c;以及8.9版本的kibana。 解压&#xff0c;点击es8.9bin目录下的elasticsearch.bat文件启动es 如图所示即为成功。 启动之后打开idea&#xff0c;添加依赖 <dependency><groupId>com.fasterxml.jackson.core</g…...

【ARM】imx6ul移植kernel记录,恩智浦github提供的最新kernel(2023年7月31)

❤️作者主页:凉开水白菜 ❤️作者简介:共同学习,互相监督,热于分享,多加讨论,一起进步! ❤️专栏目录: ❤️专栏资料: ❤️点赞 👍 收藏 ⭐再看,养成习惯 订阅的粉丝可通过PC端文末加我微信,可对文章的内容进行一对一答疑! 文章目录 一、简介二、源码下载三、官方…...

eeglab(自用)

目录 1.加载、显示数据 2.绘制脑电头皮图 3.绘制通道光谱图 4.预处理工具 5.ICA去除伪迹 5. 提取数据epoch 1.加载、显示数据 观察事件值(Event values)&#xff1a;该数据集中包含2400个事件&#xff0c;每个事件指定了EEG.event结构的字段Type(类型)、position(位置)和…...

Dockerfile构建Tomcat镜像(源码)

Dockerfile构建Tomcat镜像 目录 Dockerfile构建Tomcat镜像 1、建立工作目录 2、编写Dockerfile文件 3、构建镜像 4、测试容器 5、浏览器访问测试&#xff1a; 1、建立工作目录 [roothuyang1 ~]# mkdir tomcat[roothuyang1 ~]# cd tomcat/[roothuyang1 tomcat]# lsapach…...

Frida Error: getPackageInfoNoCheck(): has more than one overload的解决方法

使用frida绕过证书的时候执行代码&#xff1a; frida -U -f de.robv.android.xposed.installer --codeshare akabe1/frida-multiple-unpinning --no-pause遇到这样的错误 Error: getPackageInfoNoCheck(): has more than one overload, use .overload() to choose from: 网上查…...

flutter开发实战-RawKeyboardListener监听键盘事件及keycode。

flutter开发实战-RawKeyboardListener监听键盘事件及keycode。 最近开发过程中遇到外设备的按钮点击触发相应的操作&#xff0c;需要监听对应的keycode来开启游戏或者相关操作。 这里用到了RawKeyboardListener 一、RawKeyboardListener是什么&#xff1f; RawKeyboardListe…...

Temu、希音们全托管引争议,跨境电商应变“工贸一体化”

自7月27日Shopee宣布正式上线全托管模式起&#xff0c;全托管似乎突然又进入了爆发期。 在7月31日至8月1日举行的2023第八届深圳国际跨境电商贸易博览会上&#xff0c;全托管成为SHEIN、Wish、Lazada等平台力推的运营模式。进入8月&#xff0c;跨境圈突然涌现大批传言称&#…...

某科技公司提前批测试岗

文章目录 题目 今天给大家带来一家提前批测试岗的真题&#xff0c;目前已经发offer 题目 1.自我介绍 2.登录页面测试用例设计 3.如何模拟多用户登录 可以使用Jmeter,loadRunner性能测试工具来模拟大量用户登录操作去观察一些参数变化 4.有使用过Jmeter,loadRunner做过性能压…...

一次redis缓存不均衡优化经验

背景 高并发接口&#xff0c;引入redis作为缓存之后&#xff0c;运行一段时间发现redis各个节点在高峰时段的访问量严重不均衡&#xff0c;有的节点访问量7000次/s&#xff0c;有的节点访问量500次/s 此种现象虽然暂时不影响系统使用&#xff0c;但是始终是个安全隐患&#x…...

npm发布包

1.npm 登录 在控制台输入命令 npm login 按提示输入用户名&#xff0c;密码&#xff0c;邮箱后登录 如果出现如下提示 需要将淘宝镜像源切换为npm源&#xff0c;删除或注释以下内容就行 2.发布 进入准备发布的代码的根目录下&#xff0c;输入命令 npm publish 3.删除已发…...

别再死记命令了!用ENSP模拟企业网,手把手教你配置VRRP+MSTP实现网关和链路双备份

企业网络高可用实战&#xff1a;用ENSP构建VRRPMSTP双冗余架构 刚接触企业网络设计的工程师常陷入一个误区&#xff1a;把网络设备配置等同于命令记忆。我曾见过一位学员能完整背诵VRRP的配置指令&#xff0c;却在真实网络故障时手足无措——因为他从未理解这些命令背后的网络逻…...

初创公司如何利用Taotoken管理多模型API成本与用量

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初创公司如何利用Taotoken管理多模型API成本与用量 对于初创公司而言&#xff0c;在有限的预算内高效利用大模型能力是技术决策的关…...

【鸿蒙软件开发】ArkTS基础组件实战:Select与Slider在智能家居控制面板中的应用

1. 智能家居控制面板中的交互设计需求 现代智能家居系统越来越注重用户体验&#xff0c;而控制面板作为用户与设备交互的核心界面&#xff0c;其设计直接影响使用效率。在实际项目中&#xff0c;我发现很多开发者容易陷入"功能堆砌"的误区&#xff0c;忽略了交互设计…...

Perplexity+本地新闻知识库构建全流程,含Geo-Tagged新闻切片、时效性分级索引、突发新闻优先推送机制

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Perplexity本地新闻查询 Perplexity 是一款以实时信息检索与引用溯源见长的 AI 助手&#xff0c;其默认依赖联网搜索获取新闻内容。但在离线或隐私敏感场景下&#xff0c;用户可通过本地化部署方案构建轻量级…...

CANN/asc-devkit Mins矢量计算

Mins&#xff08;灵活标量位置&#xff09; 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 …...

RimSort:三分钟告别RimWorld模组管理噩梦的终极方案

RimSort&#xff1a;三分钟告别RimWorld模组管理噩梦的终极方案 【免费下载链接】RimSort RimSort is an open source mod manager for the video game RimWorld. There is support for Linux, Mac, and Windows, built from the ground up to be a reliable, community-manage…...

手把手教你学Simulink——电动汽车防溜坡功能中的电机零扭矩闭环保持控制仿真

目录 手把手教你学Simulink——电动汽车防溜坡功能中的电机零扭矩闭环保持控制仿真 一、背景与挑战 1.1 为什么“关断电机”不等于“刹住车”? 1.2 核心痛点与防溜坡设计目标 二、系统架构与核心控制推导 2.1 整体架构:从“驾驶意图”到“零速电磁抱死” 2.2 核心数学推…...

一张表算清账:发券营销的ROI该怎么算?

一、 别被“领券量”忽悠了 后台显示发了5000张券&#xff0c;老板很高兴&#xff0c;觉得生意稳了。结果月底一算账&#xff0c;发现不仅没赚&#xff0c;还贴进去几千块广告费。问题出在哪&#xff1f;​ 只看“领”&#xff0c;不看“核”。二、 核心指标&#xff1a;核销率…...

蓝桥杯JavaB组赛后复盘:从‘类斐波那契’到‘星际旅行’,我的解题思路与踩坑实录

蓝桥杯JavaB组赛后复盘&#xff1a;从‘类斐波那契’到‘星际旅行’&#xff0c;我的解题思路与踩坑实录 1. 考场策略与时间分配 比赛开始前15分钟&#xff0c;我快速浏览了所有题目&#xff0c;用铅笔在草稿纸上标注了每道题的预估难度和解题方向。这种策略让我避免了"死…...

【Perplexity商业搜索避坑白皮书】:5类典型误搜场景、4种权威信源验证法,附Gartner认证验证清单

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;【Perplexity商业搜索避坑白皮书】&#xff1a;5类典型误搜场景、4种权威信源验证法&#xff0c;附Gartner认证验证清单 高频误搜场景识别 在企业级商业情报检索中&#xff0c;以下五类误搜行为显著降低决策可…...