特殊设计模式

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

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

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

class CopyBan
{
public:
	// c++11
	CopyBan() = 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,如果普通函数,就需要先有对象才能访问函数,但是不能创建对象——必须是static
	static 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,如果普通函数,就需要先有对象才能访问函数,但是不能创建对象——必须是static
	static 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.mfbz.cn/a/421859.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数学建模获奖经验】2023第八届数维杯数学建模:华中科技大学本科组创新奖获奖分享

2024年第九届数维杯大学生数学建模挑战赛将于&#xff1a;2024年5月10日08:00-5月13日09:00举行&#xff0c;近期同学们都开始陆续进入了备赛阶段&#xff0c;今天我们就一起来看看上一届优秀的创新奖选手都有什么获奖感言吧~希望能帮到更多热爱数学建模的同学。据说点赞的大佬…

javaWebssh票据管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh票据管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模 式开发。开发环境为TOMCAT7.0,My…

npm digital envelope routines::unsupported

问题描述&#xff1a;npm运行命令报错&#xff1a;digital envelope routines::unsupported 原因&#xff1a;node版本过高 解决方案&#xff1a;在运行命令之前加上 SET NODE_OPTIONS--openssl-legacy-provider && SET NODE_OPTIONS--openssl-legacy-provider &&a…

【机器学习基础】层次聚类-BIRCH聚类

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;机器学习 欢迎订阅&#xff01;相对完整的机器学习基础教学&#xff01; ⭐特别提醒&#xff1a;针对机器学习&#xff0c;特别开始专栏&#xff1a;机器学习python实战…

【JavaEE】_Spring Web MVC简介

目录 1. Spring Web MVC简介 2. MVC简介 3. Spring MVC 1. Spring Web MVC简介 官网对于Spring Web MVC的介绍如下&#xff1a; 链接如下&#xff1a; https://docs.spring.io/spring-framework/reference/web/webmvc.html#https://docs.spring.io/spring-framework/refer…

14.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-数据包分析工具界面与通信设计

内容参考于&#xff1a; 易道云信息技术研究院VIP课 上一个内容&#xff1a;13.如果没有工具就创造工具 码云地址&#xff08;master 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/titan 码云版本号&#xff1a;fef5089bd11dfb86ae8b4e26f25cf59e85f896…

缓存穿透解决方案之布隆过滤器

布隆过滤器可以快速判断数据是否存在&#xff0c;避免从数据库中查询数据是否存在&#xff0c;减轻数据库的压力 布隆过滤器是由一个初值为0的bit数组和N个哈希函数&#xff0c;可以用来快速的判断某个数据是否存在 当我们想要标记某个数据是否存在时&#xff0c;布隆过滤器会…

《Spring Security 简易速速上手小册》第6章 Web 安全性(2024 最新版)

文章目录 6.1 CSRF 防护6.1.1 基础知识详解CSRF 攻击原理CSRF 防护机制最佳实践 6.1.2 重点案例&#xff1a;Spring Security 中的 CSRF 防护案例 Demo测试 CSRF 防护 6.1.3 拓展案例 1&#xff1a;自定义 CSRF 令牌仓库案例 Demo测试自定义 CSRF 令牌仓库 6.1.4 拓展案例 2&am…

动态规划(算法竞赛、蓝桥杯)--分组背包DP

1、B站视频链接&#xff1a;E16 背包DP 分组背包_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; const int N110; int v[N][N],w[N][N],s[N]; // v[i,j]:第i组第j个物品的体积 s[i]:第i组物品的个数 int f[N][N]; // f[i,j]:前i组物品&#xff0c;能放…

【如何像网吧一样弄个游戏菜单在家里】

GGmenu 个人家庭版游戏、应用管理 桌面图标管理器

Tomcat概念、安装及相关文件介绍

目录 一、web技术 1、C/S架构与B/S架构 1.1 http协议与C/S架构 1.2 http协议与B/S架构 2、前端三大核心技术 2.1 HTML&#xff08;Hypertext Markup Language&#xff09; 2.2 css&#xff08;Cascading Style Sheets&#xff09; 2.3 JavaScript 3、同步和异步 4、…

day08_分类品牌管理商品规格管理商品管理

文章目录 1 分类品牌管理1.1 菜单添加1.2 表结构介绍1.3 页面制作1.4 品牌列表加载1.4.1 后端接口BrandControllerBrandServiceBrandMapperBrandMapper.xml 1.4.2 前端对接brand.jscategoryBrand.vue 1.5 分类数据加载1.6 列表查询1.6.1 需求说明1.6.2 后端接口需求分析Categor…

高中数学:函数解析式的求法

一、待定系数法 用于&#xff0c;已知函数f(x)类型&#xff0c;求具体解析式的题目 关键解题步骤&#xff1a; 二、换元法 针对f(表达式)&#xff0c;表达式较复杂&#xff0c;且可以被换元表示的情况 关键解题步骤&#xff1a; 三、整体代换法 针对f(表达式1)表达式2…

C++的引用

目录 引用 常引用 指针与引用的关系 小拓展 引用的价值 做形参 传值、传引用的效率比较 做返回值 函数传值返回 函数传引用返回&#xff08;错误示范&#xff09; 野引用&#xff08;错误示范&#xff09; 引用的正常应用 值和引用作为返回值类型的性能比较 引用和…

人才测评系统的作用与应用场景有哪些?

人才测评有助于我们对于人才进行量化&#xff0c;例如&#xff1a;专业技能测评&#xff0c;性格的测评&#xff0c;以及智商和情商的测评&#xff0c;那么这些的集合就是一种人才的量化&#xff0c;通过这些属性参数&#xff0c;我们可以客观描述什么是“人才”。 那么人才测…

opencv VideoCapture

videocapture顾名思义视频捕捉&#xff0c;主要是从视频文件、摄像头或网络摄像头获取视频流数据&#xff0c;并将其作为一系列帧进行处理。 我们这里主要实现了获取项目文件夹下的1.mp4视频文件&#xff0c;然后经过灰度变化、均值滤波、边缘检测然后将视频显示出来 #include…

Xcode15与苹果ios17适配以及遇到的问题

大家好&#xff0c;我是你们的好朋友咕噜铁蛋&#xff01;最近&#xff0c;苹果发布了全新的iOS17系统&#xff0c;而作为开发者&#xff0c;我们需要确保我们的应用程序能够与这个新系统完美适配。因此&#xff0c;今天我将和大家分享一些关于Xcode15与苹果17系统适配的经验&a…

回溯例题(leetcode17/37)

文章目录 leetcode37leetcode17 回溯跟枚举差不多。要注意“回溯”&#xff0c;别忘记“回”之前把之前的改动都复原。 leetcode37 leetcode37是解数独问题。本题保证有且仅有唯一解。 思路&#xff1a;先把空格子的位置存下来&#xff0c;然后对每一个空位置挨个枚举1-9。枚…

【OpenGL的着色器03】内置变量(gl_Position等)

目录 一、说明 二、着色器的变量 2.1 着色器变量 2.2 着色器内置变量 三、最常见内置变量使用范例 3.1 常见着色器变量 3.2 示例1&#xff1a; gl_PointSize 3.3 示例2&#xff1a;gl_Position 3.4 gl_FragColor 3.5 渲染点片元坐标gl_PointCoord 3.6 gl_PointCoo…

Python中re模块的使用

正则表达式是一种强大的工具&#xff0c;用于处理字符串的匹配、搜索和替换操作。在Python中&#xff0c;我们可以使用内置的re模块来执行各种正则表达式操作。 1 基本用法 re.match(pattern, string): 从字符串的开头匹配一个模式。返回match对象或None。re.search(pattern,…
最新文章