C++语法(26)--- 特殊类设计
C++语法(25)--- 异常与智能指针_哈里沃克的博客-CSDN博客
https://blog.csdn.net/m0_63488627/article/details/131537799?spm=1001.2014.3001.5501
目录
1.特殊类设计
1.设计一个类,不能被拷贝
C++98
C++11
2.设计一个类,只能在堆上创建对象
1.封掉所有拷贝
C++98
C++11
2.封掉析构函数
3.设计一个类,只能在栈上创建对象
4.设计一个类,不能被继承
1.C++98
2.C++11 final
2.单例模式
1.设计模式
2.单例模式
1.饿汉模式
2.懒汉模式
3.单例对象释放问题
1.特殊类设计
1.设计一个类,不能被拷贝
C++98
将拷贝函数只声明不实现,并且放到私有处。(只不过,在类型内部调用另外的函数进行拷贝就没有办法防止了)
class CopyBan {// ... private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//... };C++11
在函数申明后面加入 =delete
class CopyBan {// ...CopyBan(const CopyBan&)=delete;CopyBan& operator=(const CopyBan&)=delete;//... };2.设计一个类,只能在堆上创建对象
1.封掉所有拷贝
C++98
1.先将构造函数封死,这样就无法在栈上创造对象了。但是我们需要提供一个函数调用,使得其在堆上创造对象。
2.创造堆上的函数不能直接修饰,这样会出现逻辑谬论(即想要创造对象,需要调用函数;想要调用函数,需要先创造对象)。所以这里的解决方式是设置静态函数,不需要this指针,所以不需要生成所谓对象才能调用,可以直接调用。
3.特别注意,其实拷贝构造函数也需要被处理一下,因为如果在外部先构造堆上的,随后通过解指针调用给拷贝构造,那么其实也是不算合格的。
class HeapOnly { public:static HeapOnly* CreateObject(){return new HeapOnly;} private:HeapOnly() {}HeapOnly(const HeapOnly&) {} }int main() {HeapOnly* php = HeapOnly::CreateObject(); }C++11
class HeapOnly { public:static HeapOnly* CreateObject(){return new HeapOnly;}HeapOnly(const HeapOnly&) = delete;HeapOnly(const HeapOnly&) = delete; };2.封掉析构函数
1.将析构函数封掉也能达到相同的效果,因为构造了就需要被析构,类型没有检查到可以析构就会报错。
2.此时堆上的类需要被释放掉,也需要重新构造一个destory函数,其类型是类型的指针,不可以是对象本身,因为这样就是手动调用析构函数了。只要调用destory就能释放堆上的空间。
3.设计一个类,只能在栈上创建对象
这样设计使得不能创建在堆和静态上。
class StackOnly { public:static StackOnly CreateObj(){return StackOnly();} private:StackOnly():_a(0){} private:int _a; };这样的设计使得不能在堆上创建但是,能产生静态的对象。
// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉 void* operator new(size_t size) = delete; void operator delete(void* p) = delete;4.设计一个类,不能被继承
1.C++98
构造函数私有化,子类本来要调用父类的构造函数,没有则不能被继承。
class NonInherit { public:static NonInherit GetInstance(){return NonInherit();} private:NonInherit(){} };2.C++11 final
class A final {// .... };
2.单例模式
1.设计模式
设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
一些设计理念:迭代器模式,配接器模式,单例模式,工厂模式,观察者模式
2.单例模式
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
使用样例:内存池的申请1.饿汉模式
特点:
一开始(在main函数之前)就创造对象,就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象
缺点:
1.由于初始化在main函数之前,这样的类数据过多,会使得启动慢;
2.多个单例类有初始化依赖关系,饿汉模式无法控制类的初始化先后关系
class InfoSingleton { public:static InfoSingleton& GetInstance(){return _sins;}void Insert(string name, int money){_info[name] = money;}void Print(){for (auto kv : _info){cout << kv.first << " " << kv.second << endl;}}private:InfoSingleton(){}InfoSingleton(const InfoSingleton& info) = delete;InfoSingleton& operator=(const InfoSingleton& info) = delete;map<string, int> _info;private:static InfoSingleton _sins; };InfoSingleton InfoSingleton::_sins;int main() {InfoSingleton::GetInstance().Insert("张三", 1000);InfoSingleton& info = InfoSingleton::GetInstance();info.Insert("李四", 100);//InfoSingleton copy = InfoSingleton::GetInstance(); //拷贝构造//copy.Insert("***", 10000);return 0; }2.懒汉模式
1.如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。
2.如果类之间存在依赖关系,也可以使用懒汉模式(延迟加载)。
template<class Lock> class LockGuard { public:LockGuard(Lock& lk):_lk(lk){_lk.lock();}~LockGuard(){_lk.unlock();}private:Lock& _lk; };class _InfoSingleton { public://线程安全问题,多线程一起调用创建对象static _InfoSingleton& GetInstance(){//双检查增加效率if (_psins == nullptr) {LockGuard<mutex> lock(*_smtx);if (_psins == nullptr){_psins = new _InfoSingleton;}}return *_psins;}void Insert(string name, int money){_info[name] = money;}void Print(){for (auto kv : _info){cout << kv.first << " " << kv.second << endl;}}private:_InfoSingleton(){}_InfoSingleton(const _InfoSingleton& info) = delete;_InfoSingleton& operator=(const _InfoSingleton& info) = delete;map<string, int> _info;private:static _InfoSingleton* _psins;static mutex* _smtx; };static _InfoSingleton* _psins = nullptr; static mutex* _smtx;1.这样写是懒汉模式,只创建一次,并且在main函数调用之后创建。
2.该代码有线程安全问题,在C++11后得到解决。
static _InfoSingleton& GetInstance() {static _InfoSingleton sinst;return sinst; }注意:
1.懒汉模式需要注意线程安全问题,所以我们在类中需要有一个唯一的锁,确保判断时是串行访问的。
2.每次都先加锁再进行判断是否为空,其实是非常低效,所以我们需要双判断,第一次判断是为了抛去已经创建过的节省加锁的时间,第二次判断是为了创建对象使用的,而锁夹在中间确保第二次的判断是串行的。
3.饿汉模式不需要注意线程安全问题,因为饿汉在main调用之前就已经存在了,没有所谓的线程可以创建其他的对象。
3.单例对象释放问题
1.一般而言单例类不需要释放内存,因为单例出现的环境就是全局的,它的目的就是陪到进程执行到最后,那么其实不释放,进程结束后,操作系统也会将这一部分的资源回收。
2.特别的,如果我们需要在最后单例有一定要求,我们可以手写出析构,比如进程结束需要保存一些数据到文件中,那么我们析构可以手写要求。
相关文章:
C++语法(26)--- 特殊类设计
C语法(25)--- 异常与智能指针_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131537799?spm1001.2014.3001.5501 目录 1.特殊类设计 1.设计一个类,不能被拷贝 C98 C11 2.设计一个类,只能在堆上…...
YAML+PyYAML笔记 2 | YAML缩进、分离、注释简单使用
2 | YAML缩进、分离、注释简单使用 1 简介2 缩进3 分离4 多行文本4.1 折叠块4.2 字面块4.3 引用块 5 注释5.1 行内注释5.2 块注释5.3 完美注释示例 1 简介 YAML 不是一种标记语言,而是一种数据格式;使用缩进和分离来表示数据结构,不需要使用…...
Array(20) 和 Array.apply(null, {length: 20})
1.Array(20) 其结果是: 创建了一个长度为20,但元素均为 empty 的数组。 2.Array.apply(null, { length: 20 }) 其结果是: 创建了一个长度为20,但元素均为 undefined 的数组。 3.异同 3.1相同 console.log(arr1[0] arr2[0]) /…...
Mind+积木编程控制小水泵给宠物喂水
前期用scratch,带着小朋友做了大鱼吃小鱼、桌面弹球、小学生计算器3个作品,小朋友收获不小。关键是小家伙感兴趣,做出来后给家人炫耀了一圈后,兴趣大增,嚷嚷着要做更好玩的。 最近,娃妈从抖音上买了个小猫喝…...
【Linux从入门到精通】进程的控制(进程替换)
本篇文章会对进程替换进行讲解。希望本篇文章会对你有所帮助 文章目录 一、进程替换概念 二、进程替换函数 2、1 execl 2、2 execlp 2、3 execv 2、3 execle 2、4 execve 三、总结 🙋♂️ 作者:Ggggggtm 🙋♂️ 👀 专栏&…...
rancher平台上强制删除pod服务操作
背景: 在日常paas平台运维工作中需要对rancher平台进行巡检的工作,在巡检时发现在rancher管理界面无法删除异常的pod服务, 处理: 像这样的情况就是k8s集群的pod无法通过默认的方式去删除掉pod服务,这时候只能是手工强制…...
【Docker】Docker的通信安全
Docker的通信安全 前言一、Docker 容器与虚拟机的区别1. 隔离与共享2. 性能与损耗 二、Docker 存在的安全问题1. Docker 自身漏洞2. Docker 源码问题 三、Docker 架构缺陷与安全机制1. 容器之间的局域网攻击2. DDoS 攻击耗尽资源3. 有漏洞的系统调用4. 共享 root 用户权限 四、…...
c# 函数中可选参数太多,想设置最后一个参数,又不想修改前面默认参数
C#中,你可以使用命名参数来指定你想要设置的可选参数,而保留其他参数的默认值不变。通过使用命名参数,你可以根据需要选择要为哪些参数提供值,而无需按照它们在函数签名中的顺序提供参数值。 以下是一个示例,演示如何…...
openvino资料(1)
1、c++ - OpenVino model outputs zeroes - Stack Overflow 2、https://chinait-intel.oss-cn-beijing.aliyuncs.com/OpenVINO/Ubuntu20.04%E7%8E%AF%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8OpenVINO%E9%83%A8%E7%BD%B2BiSeNetV2%E6%A8%A1%E5%9E%8B.pdf 3、c++ - How to cre...
第71篇:某银行外网打点到内网核心区红队评估复盘
Part1 前言 大家好,我是ABC_123。本期分享一篇ABC_123曾经做的针对一家银行的红队评估项目,持续时间两周,难度非常大,但是最终打到了银行核心业务区,今天就复盘一下全过程,希望红蓝双方都能得到一些启示&a…...
网络安全 Day21-数据库知识
数据库知识 1. 什么是数据库2. 为什么需要数据库(分类不清晰)3. 数据库的种类3.1 关系型数据库3.2 NOSQL 数据库3.3 new sql (国产数据库)分布式数据库3.4 云数据库 4. mysql 关系型数据库5. 安装mariadb6. 为mariadb设置密码7. M…...
python测试开发面试常考题:装饰器
目录 简介 应用 第一类对象 装饰器 描述器descriptor 资料获取方法 简介 Python 装饰器是一个可调用的(函数、方法或类),它获得一个函数对象 func_in 作为输入,并返回另一函数对象 func_out。它用于扩展函数、方法或类的行为。 装饰器模式通常用…...
语音同声翻译软件让你不再为语言障碍困扰
从前有一个叫黄俊的小伙子,他有一个大梦想:环游世界!但是,他只会说中文,而去到外国又怎么跟当地人交流呢?为了实现自己的梦想,黄俊开始了寻找能帮他解决问题的捷径。这时,方娜向他介…...
又有一个手艺人震惊了B站用户
飞瓜数据(B站版)【热门视频榜】周榜显示,霸占全站视频流量第一的是来自UP主爱捣鼓的邢志磊发布的作品《我花了半年时间给猫做了个房子》。 视频在一周时间内新增播放1232.2万,新增点赞139.4万。 根据视频详细数据显示,…...
HDFS的设计目标和重要特性
HDFS的设计目标和重要特性 设计目标HDFS重要特性主从架构分块存储机制副本机制namespace元数据管理数据块存储 设计目标 硬件故障(Hardware Failure)是常态,HDFS可能有成百上千的服务器组成,每一个组件都有可能出现故障。因此古见检测和自动快速恢复的H…...
【JMeter】JMeter添加插件
目录 一、前言 二、插件管理器 三、推荐插件 1.Custom Thread Groups (1)Ultmate Thread Group (2)Stepping Thread Group 2.3 Basic Graph 资料获取方法 一、前言 在我们的工作中,我们可以利用一些插件来帮…...
测牛学堂:车载测试面试总结之语音助手相关
车载语音助手的工作原理? 语音助手的工作原理总结下来可以分为4个步骤: 1 通过麦克风采集驾驶员的语音指令 2将语音信号转换为数字信号 3过语音识别技术将语音指令转换为计算机可以理解的指令 4 通过语音合成技术将计算机的回应转换为语音输出 车载…...
Android开发之Fragment动态添加与管理
文章目录 主界面布局资源两个工具Fragment主程序 主界面布局资源 在activity_main.xml中,声明两个按钮备用,再加入一个帧布局,待会儿用来展示Fragment。 <?xml version"1.0" encoding"utf-8"?> <LinearLayo…...
Python爬虫+数据可视化:分析唯品会商品数据
目录 前言数据来源分析1. 明确需求2. 抓包分析:通过浏览器自带工具: 开发者工具 代码实现步骤: 发送请求 -> 获取数据 -> 解析数据 -> 保存数据发送请求解析数据保存数据 数据可视化先读取数据泳衣商品性别占比商品品牌分布占比各大品牌商品售价平均价格各…...
el-tree数据渲染超出省略
el-tree数据渲染超出省略 问题 <el-tree:data"deptOptions":props"defaultProps":expand-on-click-node"false":filter-node-method"filterNode"ref"tree"default-expand-allhighlight-currentnode-click"handleNo…...
从TCP BBR到网卡中断绑定:给K8s节点和游戏服务器做一次网络延迟‘大保健’
从TCP BBR到网卡中断绑定:给K8s节点和游戏服务器做一次网络延迟‘大保健’ 在云原生和高性能计算领域,网络延迟的毫秒级波动可能引发连锁反应——Kubernetes集群中某个Pod的响应延迟会导致整个微服务链路雪崩,而游戏服务器上50ms的卡顿足以让…...
OFA-VE系统在网络安全领域的视觉分析应用
OFA-VE系统在网络安全领域的视觉分析应用 1. 引言 网络安全监控正面临前所未有的挑战。随着网络攻击手段的日益复杂和隐蔽,传统的基于规则和签名的检测方法已经难以应对新型威胁。每天都有海量的图像和文本数据在网络中流动,其中可能隐藏着恶意内容、虚…...
【回眸】系统读书笔记(十)盘点调动资源
目录 前言 资源盘点可以帮你创造选择 三类人生资源 直接价值资源 知识技能类:认知储备和实操能力、学科知识、行业认知、上手操作的技能 记录行为和结果:干成过什么、搞定过什么、负责过什么? 能力逆向推导:把行为翻译成资源…...
LN2266 超小型 低电压启动 PWM 控制 升压 DC/DC 电压调整器
■ 产品概述 LN2266 是一款微型、高效率、升压 DC/DC 调整器。电路由电流模 PWM 控制环路,误差放大器,斜波产生电路,比较器和一个功率开关等模块组成。该芯片可在较宽负载范围内高效稳定的工作。低于 1V 的启动电压,可以使用 1-4节…...
红烧肉制作技术详解
红烧肉制作技术详解 红烧肉是一道传统的中式美食,以其色泽红亮、口感酥烂、味道浓郁而闻名。本文将详细介绍红烧肉的制作步骤及技巧,帮助你在家也能做出美味的红烧肉。 材料准备 五花肉 500克生姜 适量大葱 适量八角 2颗桂皮 1小块冰糖 适量料酒 适量老抽…...
Anaconda 虚拟环境创建后,切换Python 版本
Anaconda 虚拟环境创建后,Python 版本可以更换!完全不用删除重建环境,一行命令就能直接修改 / 切换 Python 版本,非常方便。一、切换 Python 版本的命令先激活你的虚拟环境,再执行升级 / 降级命令:1. 先激活…...
OpenClaw场景合集:Qwen3-4B在10个日常任务中的高效应用
OpenClaw场景合集:Qwen3-4B在10个日常任务中的高效应用 1. 为什么选择OpenClawQwen3-4B组合 去年冬天,当我第一次尝试用OpenClaw自动化处理堆积如山的邮件时,这个组合就成了我的效率利器。OpenClaw作为本地化智能体框架,配合Qwe…...
OpenClaw+千问3.5-9B自动化测试:自然语言描述生成单元测试用例
OpenClaw千问3.5-9B自动化测试:自然语言描述生成单元测试用例 1. 为什么需要自然语言生成测试用例 作为一名长期奋战在代码一线的开发者,我深知单元测试的重要性,但编写测试用例往往比实现功能本身更耗时。特别是在快速迭代的项目中&#x…...
LPS331AP SPI嵌入式驱动库:Mbed平台高精度气压温度传感器底层控制
1. LPS331AP_SPI 库概述LPS331AP_SPI 是一个专为 Mbed OS 平台设计的轻量级 SPI 驱动库,面向意法半导体(STMicroelectronics)推出的高精度数字气压/温度传感器 LPS331AP。该器件采用 MEMS 技术,集成压力传感单元与温度传感单元&am…...
Cadence Virtuoso保姆级教程:从零完成反相器版图绘制、DRC到后仿真的完整流程
Cadence Virtuoso保姆级教程:从零完成反相器版图绘制、DRC到后仿真的完整流程 在集成电路设计领域,Cadence Virtuoso是业界公认的标准工具之一。对于初学者而言,掌握从原理图到版图再到后仿真的完整流程至关重要。本文将带领你一步步完成反相…...
