C++特殊类的设计

目录

一、不能被拷贝的类

二、只能在堆上创建对象的类

三、只能在栈上创建对象的类

四、不能被继承的类

五、只能创建一个对象的类(单例模式)


下面说几种特殊要求的类的设置,主要学习其中所运用的一些思想,融会贯通

一、不能被拷贝的类

C++98可以将拷贝构造函数与赋值运算符重载只声明不定义,且将其访问权限设置为私有即可

声明不定义且设置为私有,用户就无法调用,且也无法在类外重新定义

C++11直接使用delete关键字即可, 在默认成员函数后跟上 =delete,表示让编译器删除掉该默认成员函数,用法如下所示:


二、只能在堆上创建对象的类

有三种方式创建类对象,要求设计一个只能在堆上创建对象的类

方法①:析构函数设置为私有

此时前两种方式会报错,因为正常定义的对象是必须要调用析构函数的,所以前两种创建对象的方式调用不了析构函数,所以报错

而第三种new创建对象的方式不会自己调用析构,指针ptr需要我们手动调用,所以不会报错

但是这时想手动delete ptr的话,也没办法释放ptr,会报错,因为delete底层也是调用析构函数,ptr同样无法调用析构函数

解决方案就是由于析构函数私有,所以类外调用不了,但是类内是可以调用的,所以在CreHeap类中可以提供一个公有的静态成员函数Delete(),在Delete()中就可以使用delete,从而调用析构函数了,如下图:

同样下面这种方式也是可以的:

因为指针ptr调用Delete()时就传给了this,所以Delete()中delete this也就等同于上面的delete p


方法②:构造函数设置为私有

构造函数私有,即如下图:

但是此时,三种方式都会报错,因为都无法调用构造函数

解决方案就是在CreHeap类中增加一个公有的静态的Create函数,用于在堆上创建对象:

之所以用static,就是因为若不用静态,代码就变为了Create* h3 = Create();Create函数是成员函数,想要调用成员函数就得先有对象,而想要有对象,又必须先有成员函数Create

所以这里就会有冲突,这时加上static,就可以做到Create函数并不是成员函数,就不会再存在刚刚的冲突问题了

这里提供了一个公有的获取对象的方式,可以控制对象是new出来的

最后还有个小bug,如果有人进行拷贝构造,拷贝的对象又是在栈上创建的,所以这里结合第一种特殊类的处理,将拷贝构造函数与赋值运算符重载后面加上delete,避免出现这种情况:


三、只能在栈上创建对象的类

设计一个只能在栈上创建对象,还是可以从构造函数私有这个方向入手,因为构造函数私有,将三种创建对象的方式都限制了,所以依然可以在CreStack类中创建一个Create函数,进行相关设计:

但是这种方法也会有小漏洞,如果调用拷贝构造的话,还是会出现其他两种方式创建对象

例如下图的s2、s3都可以成功创建出对象,一个创建在静态区,一个创建在堆上:

这时有一种思路是也同样在拷贝构造函数与赋值运算符重载后面加上delete,可是这样做不但s2、s3会报错,s1也会报错

因为new底层会调用operator new,所以我们可以在operator new后面加上delete,这样可以限制住s3:

而剩下的static CreStack s2(s1);创建的s2对象没有好的方式处理,算是小缺陷


四、不能被继承的类

C++98中,可以将父类的构造函数私有化,子类无法调用到父类的构造函数,所以无法继承父类:

C++11则可以直接使用关键字final,表示该类不能被继承:


五、只能创建一个对象的类(单例模式)

说单例模式之前,首先谈谈设计模式,设计模式就是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。

使用设计模式就是为了代码的可重用性,让代码更容易被他人理解、保证代码可靠性。

我们之前学过的迭代器、适配器都是设计模式的思想

单例模式:

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

单例模式有两种实现模式:饿汉模式、懒汉模式

饿汉模式

饿汉模式是指:在一开始(main函数开始之前)就创建出对象

单例模式的要求是一个类只能创建一个对象,所以还是老方法,将构造函数私有化,这样在类外就不能无限制的创建对象了;然后在类中设置一个Getsingle函数来满足这个条件

饿汉模式的优点:简单、没有线程安全的问题

饿汉模式的缺点:

①在一个程序中,有多个单例(即有多个单例类),无法控制先后创建初始化的顺序

②饿汉单例类,如果初始化任务非常多的话,会影响程序的启动速度,因为饿汉单例是要在main函数之前完成这些工作的


懒汉模式

懒汉模式是指:第一次使用对象之前再创建示例对象

刚开始默认_sin为nullptr,当第一次创建对象,即调用Getsingle函数时,判断_sin是否为nullptr,如果是表明是第一次创建对象,此时才会创建对象,而当第二次第三次使用时,_sin不为nullptr了,也就不会再创建对象了,也能满足单例模式的要求。

懒汉模式的优点:

①可以控制顺序,想先创建哪个单例类的对象,就先调用哪个单例类的Getsingle函数

②不会影响程序的启动速度,因为懒汉模式并不要求main函数之前完成各种初始化工作

懒汉模式的缺点:

①是相对复杂的

②存在线程安全问题,需要处理好线程安全问题


关于单例的释放问题:

1、一般情况下,单例对象不需要释放的,因为一般整个程序运行期间都可能会用它,单例对象在进程正常结束后,也会资源释放。

2、有些特殊场景需要释放,比如单例对象析构时,要进行一些持久化(往文件、数据库写)操作。

这种情况比较好的处理方法是:可以单独在Single类中写一个内部类Del,定义一个静态的全局的回收对象del,main函数结束后del会调用它的析构函数,从而释放单例对象:

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

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

相关文章

高质量谷歌seo外链平台有哪些?

明确的说,没有任何必要,这里说的没必要指的是没必要寻找什么高质量的外链平台 所谓高质量的外链平台是什么?你期待在这种平台发外链能获得什么效果?高质量的外链平台,无非就是网站排名高,能发相关的外链的平…

iOS推送通知

文章目录 一、推送通知的介绍1. 简介2. 通知的分类 二、本地通知1. 本地通知的介绍2. 实现本地通知3. 监听本地通知的点击 三、远程通知1. 什么是远程通知2. 为什么需要远程通知3. 远程通知的原理4. 如何做远程通知5. 远程通知证书配置6. 获取远程推送要用的 DeviceToken7. 测试…

外贸SOHO产品怎么选?海洋建站选品方法?

外贸SOHO应该如何选产品?跨境电商独立站选品策略? 越来越多的人选择通过外贸SOHO创业,将业务拓展到国际市场。然而,面对琳琅满目的外贸SOHO产品,许多初创企业主可能会感到困惑。海洋建站将为您提供一些建议&#xff0…

直播核心岗位基础内容

一.直播间核心岗位 1.直播间前端岗位 前端岗位分工 (1)主播岗位职责 (2)场控岗位职责 (3)助理岗位职责 中端岗位分工 (1)运营岗位职责 (2)中控岗位职责 …

2024年Java SpringBoot 计算机软件毕业设计题目推荐

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容:SpringBoot、Vue、SSM、HLM…

Hbuilder从gitlab上面拉取项目

要先下载TortoiseGit-2.15.0.0-64bit这个软件 在HBuilder中从GitLab上拉取项目,请按照以下步骤操作: 1. 打开HBuilder,点击左上角的“文件”菜单,然后选择“新建”->“项目”。 2. 在弹出的对话框中,选择“从Git导…

解决 [Vue warn]:Avoid mutating a prop directly 警告

错误信息 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “xxx” 错误原因 所有的 prop 都使得…

vue中使用canvas给图片绘制水印,即使下载图片也是带水印的

先看效果 话不多说直接上组件 1、Watermark.vue <template><div><canvas ref"canvas" :width"width" :height"height"></canvas></div> </template><script>export default {props: {// 图片地址ur…

Java服务端使用freemarker+wkhtmltoimage生成Echart图片

目录 1.通过 freemarker 将ftl转成html 1.1 freemarker 手册: 1.2 添加freemarker maven依赖 1.3 添加 echart-test.ftl 模版文件 1.4 添加 FreemarkerTool 工具类 1.5 添加测试main方法 1.6 运行,生成echart-test-时间戳.html 文件 2. 通过wkhtmltoimage将html 转为p…

【复现】JieLink+智能终端操作平台弱口令漏洞_28

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 JeLink智能终端操作平台 (JSOTC2016 fJeLink)是捷顺历经多年行业经验积累&#xff0c;集智能硬件技术视频分析技术、互联网技术等…

【HarmonyOS应用开发】ArkTS基础知识(三)

一、浅析ArkTS的起源和演进 1、引言 Mozilla创造了JS&#xff0c;Microsoft创建了TS&#xff0c;Huawei进一步推出了ArkTS。 从最初的基础的逻辑交互能力&#xff0c;到具备类型系统的高效工程开发能力&#xff0c;再到融合声明式UI、多维状态管理等丰富的应用开发能力&#xf…

如何解决服务器端口被占用的问题,减少带来的影响

在现代网络环境中&#xff0c;服务器扮演着至关重要的角色&#xff0c;其稳定性和安全性对企业的正常运营具有重要意义。然而&#xff0c;服务器端口被占用的问题却时常困扰着企业网络管理员。本文将深入探讨服务器端口被占用的影响&#xff0c;并提出相应的解决方案。 一、服务…

大数据学习之Redis、从零基础到入门(二)

二、Redis安装配置 1. VMWare本地虚拟机 VMWare准备的为64位 查看自己的VMWare是32位还是64位 getconf LONG_BIT 2. Redis的安装 2.1 系统选择 选择Linux系统 2.2 Linux版安装 2.2.1 Linux环境安装Redis必须先具备gcc编译环境 ①什么是gcc gcc是linux下的一个编译程序&…

Python模块与包:扩展功能、提高效率的利器

文章目录 一、引言1.1 模块与包对于Python开发的重要性1.2 Python作为拥有丰富生态系统的编程语言 二、为什么学习模块与包2.1 复用代码&#xff1a;利用现有模块与包加速开发过程2.2 扩展功能&#xff1a;通过模块与包提供的功能增强应用的能力 三、模块的使用3.1 导入模块&am…

网站域名一定要部署SSL证书吗?

随着互联网的发展&#xff0c;网络安全问题越来越受到重视。为网站域名部署SSL证书更是成为站长们维护网站安全的基础措施之一&#xff0c;但是这并非是强制性的&#xff0c;因此有不少人对部署SSL证书的必要性产生疑惑&#xff0c;网站域名一定要部署SSL证书吗&#xff1f;在本…

part1. jdk8新特性详解

1.Lambda //1.匿名内部类new Thread(new Runnable() {Overridepublic void run() {System.out.println("新线程中执行的代码&#xff1a;"Thread.currentThread().getName());}}).start();System.out.println("主线程中的代码:"Thread.currentThread().ge…

CI/CD

介绍一下CI/CD CI/CD的出现改变了开发人员和测试人员发布软件的方式,从最初的瀑布模型,到最后的敏捷开发(Agile Development),再到今天的DevOps,这是现代开发人员构建出色产品的技术路线 随着DevOps的兴起,出现了持续集成,持续交付和持续部署的新方法,传统的软件开发和交付方…

Maven(上):Maven介绍、安装配置及工程构建

1. Maven介绍 Maven 是一款为 Java 项目管理构建、依赖管理的工具&#xff08;软件&#xff09;&#xff0c;使用 Maven 可以自动化构建、测试、打包和发布项目&#xff0c;大大提高了开发效率和质量。 Maven就是一个软件&#xff0c;掌握安装、配置、以及基本功能 &#xff…

19 python快速上手

面向对象高级和应用 1. 继承【补充】1.1 mro和c3算法1.2 py2和py3区别&#xff08;了解&#xff09; 2. 内置函数补充3.异常处理3.1 异常细分3.2 自定义异常&抛出异常3.4 特殊的finally 4.反射4.1 一些皆对象4.2 import_module 反射 总结 各位小伙伴想要博客相关资料的话关…

vue3---inputRef.value.focus()报错Cannot read properties of null (reading ‘focus‘)

问题描述&#xff1a;点击编辑按钮&#xff0c;出现el-input框&#xff08;el-input显示隐藏通过v-if控制&#xff09; <el-input ref"inputRef" v-if"isEdit" v-model"modelName" blur"isEdit false" /> <el-button text …