特殊设计模式

▶实现一个类,不能被拷贝
▶实现一个类,只能在堆上创建
❗实现一个类,只能创建在栈上
❗设计一个不能继承的类
❗单例模式——一个类只能生成一个对象
  ❔饿汉模式——在每次程序启动都会自动生成一个对象
  ❓懒汉模式——在第一次需要的时候创建

🔱实现一个类,不能被拷贝

拷贝可能需要调用拷贝构造,operator=

class CopyBan
{
public:// c++11CopyBan() = default;CopyBan(const CopyBan&) = delete;CopyBan& operator=(const CopyBan&) = delete;
private:// c98// CopyBan(const CopyBan&);// CopyBan& operator=(const CopyBan&) ;
};

第一种采用c++11delete关键字
第二种采用c++98声明成私有的方式实现


🔱实现一个类,只能在堆上创建

因为new HeapOnly() 需要调用默认构造函数,所以不能将默认构造函数禁掉,需要将默认构造函数管理起来
new HeapOnly(...) 可能调用有参构造,拷贝构造

// 设计一个只能创建在堆上的类
class HeapOnly
{
public:static HeapOnly* CreateObject(); 
private:// 因为new HeapOnly() 需要调用默认构造函数,所以不能将默认构造函数禁掉,需要将默认构造函数管理起来// new HeapOnly(...) 可能调用有参构造,拷贝构造// HeapOnly(){cout << "HeapOnly()" << endl;}// HeapOnly* b = new HeapOnly;// HeapOnly a(b); 这种是创建在栈上// 所以为了严格管理创建在堆上,需要不能写HeapOnly(const HeapOnly*);HeapOnly(const HeapOnly&) = delete;HeapOnly& operator=(const HeapOnly&) = delete;
};
HeapOnly* HeapOnly::CreateObject()
{return new HeapOnly();
}
  1. 堆上创建对象,都是需要通过new进行创建
  2. 可能会想返回值是new的对象能不能表示创建在堆上???
    答案是不能;返回值是堆上的对象,只能说返回的是堆上的对象,但是你自己的这个对象还是栈上开辟的

🔱实现一个类,只能创建在栈上

无参构造是需要的——需要在栈上创建
但是不能在堆上创建,所以不能使用new StackOnly,这个会调用默认构造函数,所以要将默认构造函数管理起来
只需要将new禁掉就行了,还有delete

// 设计一个只能创建在栈上的类
class StackOnly
{
public:void* operator new(size_t size) = delete;void operator delete(void* p) = delete;
private:// 无参构造是需要的——需要在栈上创建// 但是不能在对上创建,所以不能使用new StackOnly,这个会调用默认构造函数,所以要将默认构造函数管理起来// 只需要将new禁掉就行了,还有delete
};

🔱设计一个不能继承的类

需要明确继承是需要默认调用父类的构造函数——默认构造,有参构造,拷贝构造,operator=
所以需要将这写函数管理起来,首先不能将这些函数禁掉,所以就需要手动管理起来

c++98的方式

默认构造,有参构造,拷贝构造,operator= 写成private

class NonInherit
{
public:// 需要明确继承是需要默认父类的构造函数——默认构造,有参构造,拷贝构造,operator=// 所以需要将这写函数管理起来,首先不能将这些函数禁掉,所以就需要手动管理起来// c++11 的方式 final这个方法更好,支持在堆上创建,而且使用final编译器会有报错// c++98 的方式 private
private:// 如果使用c++98的方式,这个类就不能在堆上创建对象了,所以不太好,需要换种方式NonInherit();NonInherit(const NonInherit&);NonInherit& operator=(const NonInherit&);
};

在这里插入图片描述

如果使用private方式,这个类就不能在堆上创建对象,所以不太好,需要换种方式

我们额外在多想一下,为什么不能将父类构造函数分别放到protect,private中,子类使用protect,private继承

  1. 对于public,protect 属性取与继承方式范围小的那个
    比如说,protect属性+private继承方式=子类中private可见——父类protect属性成员转变成子类的private成员;public属性也是类似
  2. 对于private属性使用任何继承方式在子类中都是不可见的——就像爸爸的私有物品,儿子使用什么方式都是看不到的

这也是为什么不将父类构造函数写成protect的原因,所以将父类构造函数写成private属性很安全
不懂的可以看一下这个文章——各种继承方式在子类中的可见性


c++11的方式

定义父类名使用final

class NonInherit final
{
public:// 需要明确继承是需要默认父类的构造函数——默认构造,有参构造,拷贝构造,operator=// 所以需要将这写函数管理起来,首先不能将这些函数禁掉,所以就需要手动管理起来// c++11 的方式 final这个方法更好,支持在堆上创建,而且使用final编译器会有报错// c++98 的方式 private
private:// 如果使用c++98的方式,这个类就不能在堆上创建对象了,所以不太好,需要换种方式//NonInherit();//NonInherit(const NonInherit&);//NonInherit& operator=(const NonInherit&);
};

在这里插入图片描述

c++11 的方式 final这个方法更好,支持在堆上创建,而且使用final编译器会有报错


🔱单例模式——一个类只能生成一个对象

饿汉模式——在每次程序启动都会自动生成一个对象

比如在某个服务器程序中,该服务器的配置
信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再
通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。

// 饿汉模式
class Singleton_hunger
{// 在程序运行起来就已经准备好了对象,并且这个对象只能有一个
public:Singleton_hunger(const Singleton_hunger&) = delete;Singleton_hunger& operator=(const Singleton_hunger&) = delete;// 这个函数必须是static,如果普通函数,就需要先有对象才能访问函数,但是不能创建对象——必须是staticstatic Singleton_hunger* GetSingleton_hunger(){return &tem;}
private:Singleton_hunger(){cout << "Singleton_hunger" << endl;}// 静态成员也受访问区域限制static Singleton_hunger tem;
};
Singleton_hunger Singleton_hunger::tem;

静态成员可以调用构造函数


懒汉模式——在第一次需要的时候创建

如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取
文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,
就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

// 懒汉模式
class Singleton_lazy
{// 懒汉模式——在需要的时候创建,并且符合单例模式
public:Singleton_lazy(const Singleton_lazy&) = delete;Singleton_lazy& operator=(const Singleton_lazy&) = delete;// 这个函数必须是static,如果普通函数,就需要先有对象才能访问函数,但是不能创建对象——必须是staticstatic Singleton_lazy* GetSingleton_lazy(){if (tem == nullptr)tem = new Singleton_lazy;return tem;}
private:Singleton_lazy(){cout << "Singleton_lazy" << endl;}static Singleton_lazy* tem;
};
Singleton_lazy* Singleton_lazy::tem = nullptr;

在懒汉模式中需要需要使用指针来记录对象

  1. 可以使用nullptr表示没有初始化,一举两得,可以省去用另一个变量标记是否初始化
  2. 另一个原因
	static Singleton_lazy GetSingleton_lazy(){if (_flag == 0)tem = Singleton_lazy();return tem;}

在这里插入图片描述
单例模式并未结束,后来会添加线程知识

本次学习到此就结束了,只是讲了最基本的设计模式,还有很多设计模式需要我们去学习,加油!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学编程怎么样才能更快入手,编程怎么简单易学

学编程怎么样才能更快入手&#xff0c;编程怎么简单易学 一、前言 对于初学编程建议先从简单入手&#xff0c;然后再学习其他复杂的编程语言。 今天给大家分享的中文编程开发语言工具 进度条构件的用法。 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 …

JAVA集合4-HashMap

介绍 HashMap 它实现了 Map 接口&#xff0c;提供了键值对的存储和检索功能。HashMap 的底层数据结构是基于哈希表实现的,JDK7 是数组链表&#xff0c;JDK8 是数组链表红黑 树。其中有两个重要的参数&#xff1a; 容量负载因子 容量的默认大小是 16&#xff0c;负载因子是 0…

代码随想录算法训练营第四十六天| 139.单词拆分、卡码网第56题

代码随想录算法训练营第四十六天| 139.单词拆分、卡码网第56题 139.单词拆分卡码网第56题 139.单词拆分 题目链接 文章讲解 class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {int bagSize s.size(), n wordDict.size();vector<boo…

数字化转型导师坚鹏:成为数字化转型顾问 引领数字化美好未来

成为数字化转型顾问 引领数字化美好未来 ——数字化人才与企业的共赢之路 数字经济新时代&#xff0c;中国企业向数字化转型要效益&#xff1b; 转型顾问创未来&#xff0c;职场精英借数字化转型成良师。 我们中国政府特别重视数字经济发展及数字化人才培养。早在2020年8月2…

idea内置的database和chat2DB如何?

捉妖啦 最近由于某些众所周知的因素&#xff0c;要求卸载navicat,所以寻找替代品是当下任务。如果知识MySQL数据库的话&#xff0c;那替代品可太多了&#xff0c;由于使用的是MongoDB&#xff0c;所以至今没有找到一个称手的工具。 需要一款像Navicat一样&#xff0c;可以直…

什么样的跨网数据交换产品 能实现数据摆渡和数据同步?

首先&#xff0c;为什么会产生跨网数据摆渡的需求和场景呢&#xff1f;那是因为做了网络隔离&#xff0c;企业进行网络隔离的原因主要包括以下几点&#xff1a; 1、提高安全性&#xff1a;网络隔离是防止未授权访问和网络攻击的有效手段。通过将网络划分为多个独立的子网&…

L2785(Java). 将字符串中的元音字母排序

题目 1.如何以char类型便利字符串 2.自定义优先队列解决 class Solution {public String sortVowels(String s) {Map<Character,Integer> m new HashMap<>();m.put(a,1);m.put(e,1);m.put(i,1);m.put(o,1);m.put(u,1);m.put(A,1);m.put(E,1);m.put(I,1);m.put(O,…

[AIGC] 深入理解Flink中的窗口、水位线和定时器

Apache Flink是一种流处理和批处理的混合引擎&#xff0c;它提供了一套丰富的APIs&#xff0c;以满足不同的数据处理需求。在本文中&#xff0c;我们主要讨论Flink中的三个核心机制&#xff1a;窗口&#xff08;Windows&#xff09;、水位线&#xff08;Watermarks&#xff09;…

wait() 、notify()、notifyAll() 的详细用法

文章目录 &#x1f490;wait() 讲解&#x1f490;notify() 讲解&#x1f490;notifyAll()&#x1f4a1;wait() 和 sleep() 的区别 首先&#xff0c;我们知道&#xff0c;线程的执行顺序是随机的(操作系统随机调度的&#xff0c;抢占式执行)&#xff0c;但是有时候&#xff0c;我…

C语言内存池实现-对齐、重用、双向链表管理

概述 在项目上&#xff0c;经常遇到芯片内存不够导致编码困扰问题&#xff0c;在此写个笔录&#xff0c;方便后续查阅。 此示例&#xff0c;考虑了一些额外的功能和边界条件&#xff0c;例如内存分配的对齐、内存池的重用等。这个示例使用了双向链表来管理内存块。 源码如下&a…

【MySQL】视图、索引

目录 视图视图的用途优点视图的缺点创建视图查看视图修改视图删除视图注意事项 索引索引的原理索引的数据结构二分查找法Hash结构Hash冲突&#xff01;&#xff01;&#xff01; B树二叉查找树 存在问题改造二叉树——B树降低树的高度 B树特点案例继续优化的方向 改造B树——B树…

Java反射,动态代理。笔记

1.pathClass Loader 和 Dex ClassLoader 在Android 5.0以下的版本中,两者之间的区别为: DexClassLoader:可加载jar、apk和dex」可以从SD卡中加载PathClassLoader:只能加载已安裝到系統中(即/data/app目录下)的apk文件但是随着Android版本的升级,到Android …

ip https证书360元买一年送一月

随着互联网的发展&#xff0c;不论是用户还是开发者&#xff0c;都越来越重视互联网环境的安全性。IP https证书是一种网络安全协议&#xff0c;用于保护网络通信的安全性和机密性。IP https数字证书是CA认证机构为只有公网IP地址&#xff0c;没有域名的站点颁发的数字证书&…

构建信息蓝图:概念模型与E-R图的技术解析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

【JavaEE进阶】CSS选择器的常见用法

CSS选择器的主要功能就是选中页面指定的标签元素&#xff0c;选中了元素&#xff0c;才可以设置元素的属性。 CSS选择器主要有以下几种: 标签选择器类选择器id选择器复合选择器通配符选择器 接下来用代码来学习这几个选择器的使用。 <!DOCTYPE html> <html lang&q…

【Algorithms 4】算法(第4版)学习笔记 15 - 4.1 无向图

文章目录 前言参考目录学习笔记1&#xff1a;图表介绍1.1&#xff1a;定义1.2&#xff1a;常见应用1.3&#xff1a;术语1.4&#xff1a;一些图表处理问题2&#xff1a;图表 API2.1&#xff1a;图的表示2.2&#xff1a;无向图 API2.3&#xff1a;典型图处理代码2.4&#xff1a;图…

基于Apifox实现javaweb的数据响应与请求

前言 之前文章已经写过了怎么基于springboat以及maven创建javaweb项目&#xff0c;这里就不在讲述了 可以看看我之前的文章&#xff0c;前一篇发布的javaweb的数据请求与响应&#xff0c;下面具体介绍怎么基于 Apifox实现javaweb的数据响应与请求&#xff0c;顺便给大家介绍…

全网最全 Linux 命令总结,建议收藏!

1、基本命令 uname -m 显示机器的处理器架构 uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 (SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性 hdparm -tT /dev/sda 在磁盘上执行测试性读取操作系统信息 arch 显示机器的处理器架构 uname -m 显示机…

类与对象(二)--类的六个默认成员函数超详细讲解

目录 1.类的默认六个成员函数✒️ 2.构造函数 2.1构造函数的概念✒️ 2.2构造函数的特性✒️ 3.析构函数 3.1析构函数的概念✒️ 3.2析构函数的特征✒️ 4.拷贝构造函数 4.1拷贝构造函数的概念✒️ 4.2拷贝构造函数的特征✒️ 4.3思考❓ 4.4深拷贝和浅拷贝⭐️…

UE5 C++ TPS开发 学习记录(九

p20 首先我们现在有一个多人游戏的系统类MultiplayerSessionsSubsystem 在这个系统内提供了很多会话系统的接口SessionInterface 当现在我们有一些SessionInterfaceDelegates的委托,这个委托的来源是SessionInterface,所以我们使用的委托可以接收到来自SessionInterface的消息(…