【C++】特殊类设计
🌈欢迎来到C++专栏~~特殊类设计
- (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort
- 目前状态:大三非科班啃C++中
- 🌍博客主页:张小姐的猫~江湖背景
- 快上车🚘,握好方向盘跟我有一起打天下嘞!
- 送给自己的一句鸡汤🤔:
- 🔥真正的大师永远怀着一颗学徒的心
- 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
- 🎉🎉欢迎持续关注!
文章目录
- 🌈欢迎来到C++专栏~~特殊类设计
- 🎃请设计一个类,不能被拷贝
- 🎃请设计一个类,不能被继承
- ✨请设计一个类,只能在堆上创建对象
- ✨请设计一个类,只能在栈上创建对象
- 😎请设计一个类,只能创建一个对象(单例模式)
- 💢饿汉模式
- 💢懒汉模式
- 📢写在最后
🎃请设计一个类,不能被拷贝
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可
1️⃣C++98:
- 将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可
class CopyBan
{
public://...
private://C++98CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//C++11CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;
};
原因:
- 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,就可以不
能禁止拷贝了 - 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就不会防止成员函数内部拷贝了
2️⃣C++11:
delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete
,表示让编译器删除掉该默认成员函数
class CopyBan
{// ...CopyBan(const CopyBan&)=delete;CopyBan& operator=(const CopyBan&)=delete;//...
};
🎃请设计一个类,不能被继承
C++98:
- 因为子类的构造函数被调用时,必须调用父类的构造函数初始化父类的那一部分成员,但父类的私有成员在子类当中是不可见的,所以在创建子类对象时子类无法调用父类的构造函数对父类的成员进行初始化,因此该类被继承后子类无法创建出对象。
class NonInherit
{
public:static NonInherit CreateObj(){return NonInherit();}
private://将构造函数设置为私有NonInherit(){}
};
C++11:
final
关键字,final修饰类,表示该类不能被继承
class A final
{// ....
};
✨请设计一个类,只能在堆上创建对象
只能在堆上创建对象,也就是只能通过new
操作符创建对象,方式如下:
- 析构函数私有化
- 将类的构造函数私有,拷贝构造声明成私有或者
delete
掉。防止别人调用拷贝在栈上生成对象 - 提供一个静态
static
的成员函数,在该静态成员函数中完成堆对象的创建
class HeapOnly
{
public://3.提供一个公有的,获取对象的方式,对象控制是new出来的,static HeapOnly* CreatObj(){return new HeapOnly;}//防止拷贝HeapOnly(const HeapOnly& hp) = delete;HeapOnly& operator=(const HeapOnly& hp) = delete;
private://1.析构函数私有化~HeapOnly(){cout << "~HeapOnly" << endl;}//2.构造函数、拷贝构造都私有化 ~ new 也不可用了HeapOnly():_a(0){}
private:int _a;
};
int main()
{//1.析构函数私有了//HeapOnly hp1;//static HeapOnly hp2;//指针不会创建实际对象,所以不会调用到析构//HeapOnly* ptr = new HeapOnly;//ptr->Delete(ptr);HeapOnly* hp3 = HeapOnly::CreatObj();return 0;
}
🎃注意:
- 向外部提供的
CreateObj
函数必须设置为静态成员函数,因为外部调用该接口就是为了获取对象的,而非静态成员函数必须通过对象才能调用,这就变成鸡生蛋蛋生鸡的问题了 - C++98通过将拷贝构造函数声明为私有以达到防拷贝的目的,C++11可以在拷贝构造函数后面加上=delete,表示让编译器将拷贝构造函数删除,此时也能达到防拷贝的目的
✨请设计一个类,只能在栈上创建对象
方法1️⃣:
- 将构造函数设置为私有,防止外部直接调用构造函数在堆上创建对象。
- 向外部提供一个获取对象的
static
接口,该接口在栈上创建一个对象并返回。
class StackOnly
{
public:static StackOnly CreateObj(){StackOnly st;return st;}
private://构造函数私有StackOnly():_a(0){}
private:int _a;
};int main()
{StackOnly st1 = StackOnly::CreateObj();return 0;
}
但该方法有一个缺陷就是,无法防止外部调用拷贝构造函数创建对象
int main()
{StackOnly st1 = StackOnly::CreateObj();//调用拷贝构造static StackOnly copy(st1);StackOnly* copy2 = new StackOnly(st1);return 0;
}
但是我们不能将构造函数设置为私有,也不能用=delete的方式将拷贝构造函数删除,因为CreateObj函数当中创建的是局部对象,返回局部对象的过程中势必需要调用拷贝构造函数
此路不通,换一条
方法2️⃣:
- 屏蔽operator new函数和operator delete函数,或者自己声明一个不实现
class StackOnly
{
public:StackOnly(){}
private://C++98void* operator new(size_t size);void operator delete(void* p);//C++11//void* operator new(size_t size) = delete;//void operator delete(void* p) = delete;
};
new和delete默认调用的是全局的operator new函数和operator delete函数,但如果一个类重载了专属的operator new函数和operator delete函数,那么new和delete就会调用这个专属的函数。所以只要把operator new函数和operator delete函数屏蔽掉,那么就无法再使用new在堆上创建对象了。
但该方法也有一个缺陷,就是无法防止外部在静态区创建对象。
static StackOnly obj; //在静态区创建对象
😎请设计一个类,只能创建一个对象(单例模式)
什么是单例模式?
- 一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
- 比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理
单例模式有两种实现方式,分别是饿汉模式和懒汉模式:
💢饿汉模式
就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象
- 优点:简单,没有线程安全问题
- 缺点:
- 1️⃣可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序无法控制
- 2️⃣饿汉单例类,初始化时任务多,会影响程序启动速度
//饿汉模式 : 一开始(main函数之前)就创建出对象
class MemoryPool
{
public://3、提供一个全局访问点获取单例对象static MemoryPool* GetInstance(){return _pinst;}void* Alloc(size_t n){void* ptr = nullptr;return ptr;}void* Dealloc(void* ptr){//...}private://构造函数私有,并且防止拷贝MemoryPool(){}char* _ptr = nullptr;//2、提供一个指向单例对象的static指针static MemoryPool* _pinst;//声明
};//在程序入口之前完成单例对象的初始化
MemoryPool* MemoryPool::_pinst = new MemoryPool;int main()
{void* ptr1 = MemoryPool::GetInstance()->Alloc(10);MemoryPool::GetInstance()->Dealloc(ptr1);return 0;
}
💢懒汉模式
特点:延迟加载,第一次使用对象再创建实例化对象
- 优点:控制顺序、不影响启动速度
- 缺点: 相对复杂(线程安全问题)、线程安全问题要处理好、
//懒汉模式 : 第一次使用对象时,再创建实例对象
class MemoryPool
{
public://3、提供一个全局访问点获取单例对象static MemoryPool* GetInstance(){//第一次来就newif (_pinst == nullptr){_pinst = new MemoryPool;}return _pinst;}void* Alloc(size_t n){void* ptr = nullptr;return ptr;}void* Dealloc(void* ptr){//...}private://构造函数私有,并且防止拷贝MemoryPool(){//...}char* _ptr = nullptr;//2、提供一个指向单例对象的static指针static MemoryPool* _pinst;//声明
};//在程序入口之前对象初始化为空
MemoryPool* MemoryPool::_pinst = nullptr;int main()
{void* ptr1 = MemoryPool::GetInstance()->Alloc(10);MemoryPool::GetInstance()->Dealloc(ptr1);return 0;
}
我们发现以上代码中,我们new出来好像都没有去释放,这就涉及到了单例对象释放问题
- 一般情况下,单例对象是不需要释放的:整个程序运行区间都要用到
- 单例对象在进程正常结束后,也会资源释放(特殊场景:对象析构时,要进行持久化操作)
ps:往磁盘文件上写、往数据库中写就是持久化操作
📢写在最后
相关文章:

【C++】特殊类设计
🌈欢迎来到C专栏~~特殊类设计 (꒪ꇴ꒪(꒪ꇴ꒪ )🐣,我是Scort目前状态:大三非科班啃C中🌍博客主页:张小姐的猫~江湖背景快上车🚘,握好方向盘跟我有一起打天下嘞!送给自己的一句鸡汤&a…...
中创教育PMP如何轻松应对公司90%以上的沟通难题
掌握沟通技能,可以让问题从1变成0; 掌握沟通技能,可以让机会从0变成1; 掌握沟通技能,可以让成功从1变成100; 难题一、当领导问你某件事,但你又不太清楚时 【说话公式】需要思考需要确认晚点回…...

#笨鸟先飞# 数据结构与算法基础 课程笔记 第六章 图
图的定义和基本术语图:G( V , E ) Graph(Vertex,Edge)V:顶点(数据元素)的有穷非空集合;E:边的有穷集合。无向图:每条边都是无方向的有向图:每条边…...

深入浅出带你学习Apache中间件常见漏洞
前言 上一篇文章给大家总结了一下IIS中间件的漏洞,这篇文章就给大家讲一下apache中间件漏洞,说起apache大家一定不会陌生,这是我们日常中经常用到的中间件,下面由我来给大家讲解一下改中间件常见的漏洞。 Apache是什么ÿ…...
用多种指针方法访问数据元素,实现逆序输出
这里注意下数组指针的下标表示: 我们已经知道,数组名a总是指向a[0]的指针,*(ai)是对a[i]的引用,实际上,编译器中,对数组的引用,如a[i],总是被编译器改写成*(ai)的形式。 另外说明下…...

WebDAV之葫芦儿·派盘+NMM
NMM 支持WebDAV方式连接葫芦儿派盘。 推荐一款文件管理器,可以对手机中的文件进行多方面的管理,支持语法高亮和ftp等远程的文件的管理。支持从WebDav服务器连接葫芦儿派盘服务下载文件和上传文件。 NMM文本编辑器是一款文件管理器,在功能上面更加的适合于一些编程人员进行使…...

Redis多级缓存
文章目录一. 什么是多级缓存二. JVM进程缓存一. 什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后,先查询Redis,如果未命中则查询数据库,如图: 存在下面的问题: 请求要经过Tomcat处理,Tomcat的性能…...

【原创】java+swing+mysql会议室管理系统设计与实现
本文主要介绍使用javaswingmysql等技术去设计完成一个企业公司的会议室管理系统,帮助企业员工去进行会议室的预约安排。 功能分析: 会议室管理系统的使用角色,一般分为管理员和员工用户,管理员进行数据管理,员工进行…...

【Redis】Redis 常用数据类型操作 ① ( 数据库操作 | Redis 数据库连接参数 | Redis 数据库个数 | Redis 访问机制 )
文章目录一、Redis 数据库连接参数二、Redis 数据库个数三、Redis 访问机制一、Redis 数据库连接参数 连接 Redis 数据库 , 只需要 IP 地址 , 端口号 , 访问密码 即可 , 如果没有 设置 访问密码 可忽略该选项 ; Redis 默认端口号是 6379 ; 参考 【Redis】Redis 数据库 安装、…...

GAMES101-计算机图形学入门 LEC4: TRANSFORMATION-3D
本节课程视频地址:https://www.bilibili.com/video/BV1X7411F744/?p4 补充上一节课的一个内容,旋转矩阵的逆矩阵是它的转置,也就是说有R−θRθ−1RθTR_{-\theta} R_\theta^{-1}R_\theta^TR−θRθ−1RθT 上节课讲了,…...
robot实战:截取字符串
一:变量标识符号(1) Scalar型变量: "$"作为标识符号,例如:${var}, 这个打印log时只能用logset赋值:a: ${var} Set Variable abcb:${var2} Set Variable If ${Var}abc efgh ace 如果var的值和abc相等…...
【面经】滴滴测开一面
滴滴测开一面 面试官自我介绍面试者自我介绍大概实习多久?你在在校经历比较丰富,说一下打ACM那些比赛中的一些经验,找一些具体的项目说一下在打ACM中团队里几个人? 你负责什么?在上段实习的过程中都做了哪些事情&…...
数据治理-主数据
二、某企业集团旗下有房地产、供应链、物流、酒店等多个业务子公司,为了统一管理,集团推进数字化转型,建立了统一的数据仓库,各子公司将数据集成到集团信息部负责管理的 数据平台。集团在实施数据治理过程中,发现各业务…...

软考-中级-软件设计师-成绩
低分飘过,备考经验主要就是刷题。...

学习笔记<二> MySQL学习(3):分库、分表
文章目录为什么分库分表一、垂直分片、水平分片二、常用的数据分片策略三、垂直分表、垂直分库、水平分库、水平分表四、垂直切分、水平切分优缺点五、数据分片规则六、分库分表带来的问题本文参考博主「小Y是我的」的文章,原文链接:https://blog.csdn.n…...

重生之我是赏金猎人-SRC漏洞挖掘(八)-记一次移花接木的GetShell
0x00:前言 https://github.com/J0o1ey/BountyHunterInChina 欢迎亲们点个star 作者:RGM78sec 某天测厂商业务时,发现其中有一个提供音乐播放业务的资产,正好里面有我想听的歌,于是就有了这篇文章 0x01:…...
离线数仓(五):数仓搭建
文章目录一、创建数据库二、ODS 层(原始数据层)三、DWD 层(明细数据层)3.1 get_json_object 函数使用3.2 启动日志表 DWD层创建四、DWS 层(服务数据层)五、DWT 层(数据主题层)六、AD…...

安装SQL Server2017 过程中报KB29119355失败的解决方案
SQLServer 2017脱机版下载地址:http://download.microsoft.com/download/6/4/A/64A05A0F-AB28-4583-BD7F-139D0495E473/SQLServer2017-x64-CHS-Dev.isoMicrosoft SQL Server Management Studio 18管理工具下载https://learn.microsoft.com/zh-cn/sql/ssms/download-…...

2023年浙江建筑特种工(施工升降机)真题题库及答案
百分百题库提供特种工(施工升降机)考试试题、特种工(施工升降机)考试预测题、特种工(施工升降机)考试真题、特种工(施工升降机)证考试题库等,提供在线做题刷题,在线模拟考…...

2023年进入互联网行业好找工作吗?
俗话说:选择大于努力。年后求职小高峰,大家在找工作的时候选择肯定也多了。说真,不是人人都有铁饭,普通家庭的孩子想要在2023年进入互联网行业去找工作可能吗?01有一点大家要清楚,2022年是进入过一个寒冬的…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...