当前位置: 首页 > 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.删除已发…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...