秒懂C++之特殊类设计

fe594ea5bf754ddbb223a54d8fb1e7bc.gif

目录

 

设计一个类,不能被拷贝

设计一个类,只能在堆上创建对象

设计一个类,只能在栈上创建对象

设计一个类,无法被继承

设计一个类,只能创建一个对象(单例模式)

饿汉模式

懒汉模式


设计一个类,不能被拷贝

这个很简单,利用C11新特性中的关键字delete给到拷贝构造与赋值重载即可~

class BanCopy
{//...BanCopy(const BanCopy&) = delete;BanCopy& operator=(const BanCopy&) = delete;//...
};

设计一个类,只能在堆上创建对象

既然是要在堆上创建对象,那么首先要做的就是确保该对象是new出来的而非是由构造函数生成的~

class HeapOnly
{
public://禁止赋值重载HeapOnly& operator=(const HeapOnly&) = delete;//禁止拷贝构造HeapOnly(const HeapOnly&) = delete;
private://构造私有化//无参HeapOnly(){}//有参HeapOnly(int x, int y):_x(x),_y(y){}int _x;int _y;
};int main()
{HeapOnly ho1;HeapOnly* ho2 = new HeapOnly;return 0;
}

不过这样new的时候也无法调用构造了,所以我们再包装一层~

不过还是遇到问题,OBJ是创建对象用的,但调用OBJ得是对象调用,那么我们就不要让它作为成员函数,而是超脱其作用域~

然后再把默认的拷贝函数与赋值重载禁掉,防止在栈上拷贝对象~

class HeapOnly
{
public:template<class... Args>static HeapOnly* CreateObject(Args&&... args){return new HeapOnly(args...);}/*static HeapOnly* CreateObject(){return new HeapOnly;}*///禁止赋值重载HeapOnly& operator=(const HeapOnly&) = delete;//禁止拷贝构造HeapOnly(const HeapOnly&) = delete;
private://构造私有化//无参HeapOnly(){}//有参HeapOnly(int x, int y):_x(x),_y(y){}int _x =1;int _y =2;
};int main()
{/*HeapOnly ho1;HeapOnly* ho2 = new HeapOnly;*/HeapOnly* ho2 = HeapOnly::CreateObject();HeapOnly* ho3 = HeapOnly::CreateObject(3,4);//禁止拷贝//HeapOnly copy(*ho2);return 0;
}

ps:可搭配上前面所学的可变参数模板使用~

设计一个类,只能在栈上创建对象

只能在栈上的话思路和前面差不多,先把构造给私有化,由我们来控制在那开辟对象,再把new给禁止掉,防止在堆上开辟~

class StackOnly
{
public:template<class... Args>static StackOnly CreateObj(Args&&... args){return StackOnly(args...);}// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
private:StackOnly():_a(0){}
private:int _a;int _b;
};int main()
{StackOnly so1 = StackOnly::CreateObj();StackOnly so2 = StackOnly::CreateObj(3,4);//无法使用StackOnly* ptr3 = new StackOnly(obj);return 0;
}

设计一个类,无法被继承

class A final
{//...
};

直接用C11新特性的关键字final即可~

设计一个类,只能创建一个对象(单例模式)

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个 访问它的全局访问点,该实例被所有程序模块共享

饿汉模式

饿汉:一开始(main之前)就创建出对象。就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。

想让一些数据,当前程序只有一份,那就可以把这些数据放到这个类里面,再把这个类设计成单例,这个数据就只有一份了

namespace hunger
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){return &_sint;}void Print(){cout << _x << endl;cout << _y << endl;}//禁止拷贝构造与赋值重载,防止其他对象生成Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;private://构造函数私有防止构造其他对象Singleton(int x,int y):_x(x), _y(y){}int _x;int _y;// 静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制// 这才符合在main之前创建对象static Singleton _sint;};//静态成员声明:成员类型+成员所处內域Singleton Singleton::_sint(1, 1);
}
int main()
{//直接调静态函数拿到对象hunger::Singleton::GetInstance()->Print();
}

ps:之所以拿指针而非对象一个是安全问题,指针销毁方便~但我感觉无论用指针还是引用返回都差不多~

不过饿汉模式有两个问题存在:

  • 如果单例对象数据较多,构造初始化成本较高,那么会影响程序启动的速度。迟迟进不了main函数
  • 多个单例类有初始化启动依赖关系,饿汉无法控制。假设:A和B两个单例,假设要求A先初始化,B再初始化,饿汉无法保证

懒汉模式

懒汉优点:第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控
制。
如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊,初始化网络连接啊,读取
文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,
就会导致程序启动时非常的缓慢。所以这种情况使用懒汉模式( 延迟加载 )更好。
//在饿汉模式基础上进行改造
namespace lazy
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){// 第一次调用时,创建单例对象// 线程安全问题,需要加锁if (_psint == nullptr){_psint = new Singleton;}return _psint;}static void DelInstance(){if (_psint){delete _psint;_psint = nullptr;}}void Print(){cout << _x << endl;cout << _y << endl;}//禁止拷贝构造与赋值重载,防止其他对象生成Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;private://构造函数私有防止构造其他对象Singleton(int x =0,int y=0):_x(x), _y(y){}~Singleton(){cout << "~Singleton()" << endl;}int _x;int _y;// 静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制static Singleton* _psint;// 内部类class GC{public:~GC(){Singleton::DelInstance();}};// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象static GC gc;};Singleton* Singleton::_psint = nullptr;Singleton::GC Singleton::gc;
}
int main()
{//直接调静态函数拿到对象lazy::Singleton::GetInstance()->Print();return 0;
}

在懒汉模式中我们最开始是构建出一个对象指针,只有在第一次被调用的时候才会创建对象,这样可以减少初始化时的开销~由于静态成员变量是指针,那就需要写对应的析构函数及时释放其资源,如果我们不想手动释放也可以学一下构建内部类的方式让其自动调用对指针的析构函数~

如果不想用GC内部类析构对象指针也可以这样写:

namespace lazy
{class Singleton{public://利用静态成员函数拿到静态成员static Singleton* GetInstance(){// 第一次调用时,创建单例对象// 线程安全问题,需要加锁//局部静态对象,在第一次调用该函数时才初始化static Singleton _sint;return &_sint;}static void DelInstance(){if (_psint){delete _psint;_psint = nullptr;}}void Print(){cout << _x << endl;cout << _y << endl;}//禁止拷贝构造与赋值重载,防止其他对象生成Singleton(Singleton const&) = delete;Singleton& operator=(Singleton const&) = delete;private://构造函数私有防止构造其他对象Singleton(int x = 0, int y = 0):_x(x), _y(y){}~Singleton(){cout << "~Singleton()" << endl;}int _x;int _y;// 静态成员对象,不存在对象中,存在静态区,相当于全局的,定义在类中,受类域限制static Singleton* _psint;};Singleton* Singleton::_psint = nullptr;
}int main()
{//直接调静态函数拿到对象lazy::Singleton::GetInstance()->Print();return 0;
}

不用new而是直接创建对象~

总结:在main之前初始化就是饿汉,在main中第一次调用就是懒汉~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143002.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

从数据仓库到数据中台再到数据飞轮:我了解的数据技术进化史

这里写目录标题 前言数据仓库&#xff1a;数据整合的起点数据中台&#xff1a;数据共享的桥梁数据飞轮&#xff1a;业务与数据的双向驱动结语 前言 在当今这个数据驱动的时代&#xff0c;企业发展离不开对数据的深度挖掘和高效利用。从最初的数据仓库&#xff0c;到后来的数据…

字节跳动冯佳时:大语言模型在计算机视觉领域的应用、问题和我们的解法

演讲嘉宾&#xff5c;冯佳时 编辑 &#xff5c;蔡芳芳 近年来&#xff0c;大语言模型 (LLMs) 在文本理解与生成领域取得了显著进展。然而&#xff0c;LLMs 在理解和生成自然信号&#xff08;例如图像&#xff0c;视频&#xff09;等&#xff0c;还处在比较早期的探索阶段。为…

单例模式(饿汉式-懒汉式)

我给面试官讲解了单例模式后&#xff0c;他对我竖起了大拇指&#xff01;https://blog.csdn.net/weixin_41949328/article/details/107296517?ops_request_misc%257B%2522request%255Fid%2522%253A%2522FAEE9ABD-432D-416C-98C6-9DD939138DEB%2522%252C%2522scm%2522%253A%252…

HTML中的文字/分区标记/特殊符号

1.font标记&#xff1a;用来设置文字的字体&#xff0c;大小&#xff0c;颜色&#xff0c;等属性 <!--font:font标记用来设置字体大小颜色属性size:设置字号&#xff0c;默认是3号&#xff0c;1表示4号&#xff0c;-1表示2号&#xff0c;取值范围是[1,7]或[-7,-1]color:设置…

【Manim】用manim描述二次曲面——上

二次曲面是可以化为一般形式的任意方程的图形 这里面A,...,J是常数。我们不可能把它们都列出来&#xff0c;但是有一些标准方程所以这里是一些更常见的二次曲面的列表。 1. 椭球体 这是椭球体的一般方程。。 这是一个典型椭球体的草图。 接下来我们用Manim实现该椭球体的绘制…

【CanMV K230 AI视觉】 人脸识别

【CanMV K230 AI视觉】 人脸识别 人脸识别 动态测试效果可以去下面网站自己看。&#xff09; B站视频链接&#xff1a;已做成合集 抖音链接&#xff1a;已做成合集 人脸识别 前面学习过的人脸检测&#xff0c;只检测出人脸&#xff0c;而本实验要做的人脸识别&#xff0c;会学…

嵌入式人工智能项目及人工智能应用项目——大合集列表查阅

本文的项目合集列表可能更新不及时&#xff08;会及时更新&#xff09;&#xff0c;可查阅实时更新的链接如下。 嵌入式人工智能及人工智能应用项目合集实时更新链接如下&#xff1a; 阿齐嵌入式人工智能及人工智能应用项目合集 (kdocs.cn)https://www.kdocs.cn/l/cc97tuieys4…

Python urllib

Python urllib 库用于操作网页 URL&#xff0c;并对网页的内容进行抓取处理。 本文主要介绍 Python3 的 urllib。 urllib 包 包含以下几个模块&#xff1a; urllib.request - 打开和读取 URL。urllib.error - 包含 urllib.request 抛出的异常。urllib.parse - 解析 URL。url…

心觉:不能成事的根本原因

很多人一直都很努力&#xff0c;每天都很忙 每天都学习很多东西&#xff0c;学习各种道&#xff0c;各种方法论 但是许多年过去了依然一事无成 自己的目标没有达成&#xff0c;梦想没有实现 为什么呢 关键是没有开悟 那么什么是开悟呢 现在很多人都在讲开悟 貌似开悟很…

回收站永久删除的文件还能恢复吗?教你恢复技巧

在数字时代&#xff0c;电脑是我们工作、学习和娱乐的重要工具。然而&#xff0c;随着我们对电脑的频繁使用&#xff0c;误删文件的情况也时有发生。当我们在回收站中不小心永久删除了某个重要文件时&#xff0c;内心可能会充满焦虑和疑惑&#xff1a;这些文件还能恢复吗&#…

基于springboot+vue实现的智能垃圾分类系统 (源码+L文+ppt)4-063

摘 要 本论文主要完成不同用户的权限划分&#xff0c;不同用户具有不同权限的操作功能&#xff0c;系统包括用户、物业和管理员模块&#xff0c;主要功能有用户、物业、垃圾站点、垃圾投放、验收信息、积分商城、积分充值、通知物业等管理操作。 关键词&#xff1a;智能垃圾…

【LLM】中国在 GPT/LLM 大模型上是否已经实现了弯道超车?

还是谈一下现状吧。中国的大模型公司与美国的大模型公司其实在数量上可能中国更多一些吧。 美国的 OpenAI&#xff1a;No.1&#xff0c;毫无疑问&#xff01;Google&#xff1a;尽管落了&#xff0c;但是依然是全球第二的实力吧&#xff1f;Meta&#xff1a;开源全靠它家的Ll…

【代码随想录训练营第42期 Day60打卡 - 图论Part10 - Bellman_ford算法系列运用

目录 一、Bellman_ford算法的应用 二、题目与题解 题目一&#xff1a;卡码网 94. 城市间货物运输 I 题目链接 题解&#xff1a;队列优化Bellman-Ford算法&#xff08;SPFA&#xff09; 题目二&#xff1a;卡码网 95. 城市间货物运输 II 题目链接 题解&#xff1a; 队列优…

Untangle电脑上网行为管理软件有哪些?(一口气看完,第一款建议收藏!)

控制上网的软件通常被称为上网行为管理软件或上网行为监控软件。 这类软件主要用于管理网络用户的上网行为&#xff0c;帮助企业或组织提升网络使用效率和工作效率&#xff0c;同时最大限度地避免不当上网行为带来的潜在风险和损失。 以下是一些值得推荐的电脑上网行为管理软件…

【C++】——继承与虚继承

文章目录 继承继承的概念继承的定义继承类模版基类与派生类的赋值转换继承的作用域派生类的默认成员函数构造函数与析构函数拷贝构造 不能被继承的类继承与友元继承与静态成员多继承与菱形继承 虚继承继承与组合 继承 什么是继承&#xff1f; 继承其实就是胆码复用的一种手段&…

江科大笔记—OLED显示屏

OLED显示屏 OLED的GND接到负极&#xff0c;OLED的VCC接正极&#xff0c;同时也会接到stm32上的PB6和PB7 SCL接PB8 SDA接PB9 在Hardware文件夹里面放3个文件&#xff1a;OLED.c、OLED.h、OLED_Font.h OLED_Font.h:存的是OLED的字库数据&#xff0c;因OLED是不带字库的&#xf…

APP测试--含【学车不】项目实战

本文参考黑马程序员以下课程; 1-002-App应用架构_哔哩哔哩_bilibili 1. APP环境 1.1 app应用系统架构 json是一种轻量级的数据交换格式&#xff0c;采用完全独立于编程语言的文本格式来储存和表示数据 1.2 app 后台开发测试环境 预发布环境&#xff1a; 使用后端的测试代码&a…

Meta-Learning数学原理

文章目录 什么是元学习元学习的目标元学习的类型数学推导1. 传统机器学习的数学表述2. 元学习的基本思想3. MAML 算法推导3.1 元任务设置3.2 内层优化&#xff1a;任务级别学习3.3 外层优化&#xff1a;元级别学习3.4 元梯度计算3.5 最终更新规则 4. 算法合并5. 理解 MAML 的优…

钢索缺陷检测系统源码分享

钢索缺陷检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

在线制作PPT组织架构图!这个AI工具简单又好用!

ppt组织架构图如何制作&#xff0c;用哪个软件好&#xff1f; 在现代商业世界中&#xff0c;组织架构图是展示公司结构和层级关系的重要工具&#xff0c;譬如内部沟通或者对外展示等场合下&#xff0c;一个精美且清晰的组织架构图都能有效传达信息&#xff0c;提升企业形象。 …