【C++】特殊类设计 — 不能被拷贝的类 , 只能在堆/栈上创建对象的类 ,不能被继承的类

news2024/11/24 23:24:47

在这里插入图片描述

苟活者在淡红的血色中,会依稀看见微茫的希望;
真的猛士,将更奋然而前行。
--- 鲁迅 ---

@toc

1 特殊类

在实践中,常常会有一些比较有意思的特殊场景:

  1. 不能被拷贝的类 - 独一无二的魔法宝物:
    在一个角色扮演游戏(RPG)。在这个游戏中,玩家可以通过工匠进行装备的拷贝,但是有一件神秘的魔法宝物,被称为“永恒之心”,它拥有赋予持有者永生的力量 ,是独一无二的,因此它不能被复制或克隆。
    每当玩家尝试复制“永恒之心”时,游戏会抛出一个错误:“魔法宝物独一无二,无法复制!”。这确保了游戏中只有一个“永恒之心”,增加了它的神秘感和价值。
  2. 只能在堆上创建对象的类 - 豪华游艇
    有一个豪华游艇模拟器。在这个模拟器中,游艇是一个复杂且昂贵的对象,它需要在堆上动态分配资源,比如内存来存储游艇的详细规格和状态。
    每当玩家想要创建一艘新的游艇时,他们必须通过“造船厂”接口来请求,这实际上是在堆上分配了一个新的游艇对象。
  3. 只能在栈上创建对象的类 - 一次性密码
    你正在为银行的安全系统编写代码。为了防止密码被复制或存储在不可靠的地方,你设计了一个“一次性密码”类,它只能在栈上创建,并在使用后立即销毁
    当用户进行一次交易时,系统会生成一个一次性密码,一旦交易完成,密码就会“消失”,保证了密码的安全性。

    在这些特殊场景中,我们需要按照需求设计是特殊类!

2 不能被拷贝的类

拷贝只会发生在两个场景中:拷贝构造函数以及赋值运算符重载
因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可
在C++98中我们会将拷贝构造函数和赋值重载函数进行私有化,这样外部就调用不到他们了!

class A
{
	A()
	{}
	~A()
	{}
private:
	A(const A& a)
	{
	}
	A& operator=(const A& a)
	{
	}
private:
	int _a1;
};
  1. 必须设置成私有:如果只声明没有设置成private,如果在类外定义拷贝构造和赋值重载,就不能禁止拷贝了!
  2. 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单,而且如果定义了就不能防止成员函数内部拷贝了!

C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数。

class A
{
	A()
	{}
	~A()
	{}

	A(const A& a) = delete;
	A& operator=(const A& a) = delete;

private:
	int _a1;
};

这样就轻松的解决了问题!

3 只能在堆上创建对象的类

使用使用的类,就不能让用户,可以显式调用到构造函数,不然就在栈区创建了对象!我们需要写出一个接口,让用户可以获取到堆上的对象地址!这样就涉及到了先有鸡先有蛋的问题了,所以我们要将这个接口设置成静态成员函数,才能正常调用!

class HeapOnly
{
public:
	static HeapOnly* CreateObj()
	{
		return new HeapOnly;
	}
private:
	HeapOnly()
	{
	}
	HeapOnly(const HeapOnly& h) = delete;
	HeapOnly& operator=(const HeapOnly& a) = delete;
private:
	int _a1;
};

注意:除了处理构造函数,还要处理拷贝构造和赋值拷贝函数。因为拷贝的对象也是在栈上的!必须把所有可能的方法都要封死!

这样一个只能在堆上创建对象的类就写好了!

还有一个十分新奇的写法:将析构函数私有化!这样在栈上创建对象就会报错,迫使用户只能在堆上构造对象!我们可以通过一个显式的release方法来释放空间,来完善在堆上创建对象的操作!

4 只能在栈上创建对象的类

同上将构造函数私有化,然后设计静态方法创建对象返回.注意为了防止在堆上创建对象,我们需要将new delete操作符重载函数进行删除!这样就将在堆上创建彻底封死了!

class StackOnly
{
public:
	static StackOnly CreateObj()
	{
		return StackOnly();
	}
	// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
	// StackOnly obj = StackOnly::CreateObj();
	// StackOnly* ptr3 = new StackOnly(obj);
	void* operator new(size_t size) = delete;
	void operator delete(void* p) = delete;
private:
	StackOnly()
		:_a(0)
	{}
private:
	int _a;
};

5 不能被继承的类

回顾一下继承的知识:从零开始认识继承

不能被继承的类很简单!C++98是将构造函数进行私有化,在C++11之后直接使用final关键字就可以了!

class A final
{
	// ....
};

总结

C++的世界里,一些特别的类真是挺有讲究的。就像游戏里的独门魔法宝物,模拟豪华游艇的细节,还有银行系统里那些用完就丢的密码,每一个都是针对特定情况精心设计的。那些不能复制的类,就像是在说“我是特别的,不能随便复制”;只能在堆上或者栈上创建对象的类,就像是给内存管理上了把锁,保证了东西放在该放的地方;而不让继承的类,就像是定了规矩,让功能保持原汁原味。

这些设计不仅展示了C++的强大,也让我们看到程序员先辈们是如何巧妙地解决难题的。通过这几个特殊的类,我们的代码能力肯定有许多长进,C++的学习过程也变得更加丰富多彩了!

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

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

相关文章

『大模型笔记』虚拟机(Virtual Machine,VM)与Docker对比!

『大模型笔记』虚拟机(Virtual Machine,VM)与Docker对比! 文章目录 一. 虚拟机(Virtual Machine,VM)与Docker对比!1. 定义这两种技术2. 工作原理3. 关于如何选择适合工作负载的技术的指导二. 参考文献Docker 只是一个轻量级的虚拟机吗?虽然二者确实有一个共同点,即 虚…

【RISC-V设计-13】- RISC-V处理器设计K0A之指令测试

【RISC-V设计-13】- RISC-V处理器设计K0A之指令测试 文章目录 【RISC-V设计-13】- RISC-V处理器设计K0A之指令测试1.简介2.验证用例3.指令代码4.链接脚本5.编译脚本6.仿真结果6.1 复位结束6.2 运行成功6.3 终端打印 7.总结 1.简介 借助上一篇文章所提及的验证环境,…

对象引用对于非静态的字段、方法或属性是必需的

CS0120 对象引用对于非静态的字段、方法或属性“Person.FirstName”是必需的 类Person internal class Person{// public static string FirstName { get;set; }"sss";public string FirstName { get; set; } "sss";public static string MiddleName …

k8s挂载nginx配置文件

文章目录 步骤一:启动指定服务的工作负载时,指定需要挂载的配置文件,替换工作负载内置的配置文件步骤二: 在配置字典中新增配置文件步骤三:自定义挂载的配置文件 步骤一:启动指定服务的工作负载时,指定需要…

深度学习 —— 个人学习笔记17(锚框、多尺度锚框)

声明 本文章为个人学习使用,版面观感若有不适请谅解,文中知识仅代表个人观点,若出现错误,欢迎各位批评指正。 三十四、锚框 import torch import matplotlib.pyplot as plt from matplotlib_inline import backend_inlinetorch.…

Python 绘图进阶之箱线图:揭示数据的分布和异常值

Python 绘图进阶之箱线图:揭示数据的分布和异常值 引言 在数据分析中,理解数据的分布情况和识别异常值是非常重要的任务。箱线图(Box Plot)作为一种简洁有效的统计图表,能够直观地展示数据的中位数、四分位数、极值以…

除了画图,你还需要透视平面设计师的日常工作

平面设计师是市场上较为稀缺且需求旺盛的职业,许多企业都在争相聘请优秀的设计师。平面设计在日常生活中无处不在,应用领域广泛,如广告设计、logo设计和名片设计等。因此,本篇文章将为你详细介绍平面设计。 1、什么是平面设计&am…

YOLT论文精读

引言 很早之前,在本校老师的带领下接触到了目标检测领域。在卫星遥感图像方面有一篇经典的论文《You Only Look Twice: Rapid Multi-Scale Object Detection In Satellite Imagery》。科研小白一开始反复看了几遍也没弄懂,决定写博客来加深自己的理解。…

Vue 3+Vite+Eectron从入门到实战系列之(五)一后台管理登录页

前面已经讲了不少基础知识,这篇开始,我们进行实操,做个后台管理系统,打包成多端的,可安装的桌面app!!其中,登录,退出的提示信息用系统的提示,不使用elemengplus的弹窗提示!&#xff…

Java生成图形验证码

1、加依赖 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency> 2、写接口&#xff0c;这块不需要登录成功才能操作的&#xff0c;所以写controller就行了…

基于Hadoop的网购笔记本电脑大数据分析与可视化系统

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍数据采集过程数据预处理Hadoop大数据分析可视化展示每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 本项目首先通过爬虫获取京东…

【C++】产生拷贝构造的三种形式

目录 用已存在的类对象去初始化同类另一个对象当函数类的形参是对象&#xff0c;调用函数形参和实参进行结合当函数的返回值是对象&#xff0c;函数执行完成返回调用者时 用已存在的类对象去初始化同类另一个对象 Date d1; Date d2(d1); Date d3 d2; //也会调用拷贝构造注意赋…

谷粒商城实战笔记-168-缓存-SpringCache-整合体验@Cacheable

文章目录 一&#xff0c;168-缓存-SpringCache-整合&体验Cacheable1&#xff0c;引入Spring Cache依赖2&#xff0c;配置3&#xff0c;启用cache4&#xff0c;在查询数据库的方法上加上注解Cacheable5&#xff0c;测试 二&#xff0c;169-缓存-SpringCache-Cacheable细节设…

LeetCode_sql_day16(601.体育馆的人流量)

描述&#xff1a;601. 体育馆的人流量 - 力扣&#xff08;LeetCode&#xff09; 编写解决方案找出每行的人数大于或等于 100 且 id 连续的三行或更多行记录。 返回按 visit_date 升序排列 的结果表。 输入Stadium表: ----------------------------- | id | visit_date | peop…

Linux系统移植——系统移植初步介绍(一)

一、嵌入式Linux系统软件组成及分布 1.1 内核&#xff08;Kernel&#xff09; 功能&#xff1a;负责管理硬件资源、进程调度、内存管理、文件系统、网络等。分布&#xff1a;通常是定制的Linux内核&#xff0c;以适应特定的硬件平台和应用需求。 1.2 根文件系统&#xff08;…

sql实验代码整理:创建表文件Student、Course、Sc完成下列问题

使用SQL语句创建数据库students. create database students; 创建表文件Student、Course、Sc&#xff0c;表结构如表3-7~表3-9所示。 代码及运行结果&#xff1a; 代码及运行结果&#xff1a; 代码及运行结果&#xff1a; 为表Student 添加地址列Address&#xff0c;数据类型为…

14.3 Matplotlib与Seaborn数据可视化

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

汽车保养系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;门店信息管理&#xff0c;员工信息管理&#xff0c;配件信息管理&#xff0c;保养信息管理&#xff0c;管理员管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页…

k8s部署ingress-nginx

一、拉取ingress-nginx的安装代码 地址&#xff1a;https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.1/deploy/static/provider/cloud/deploy.yaml 如果上面的地址访问不通的话&#xff0c;可以直接使用下面的内容&#xff1a; 由于官方镜像存放…

Keepalived详解

目录 1、高可用集群keepalived 高可用集群 VRRP 相关概念 keepalived 简介 2、基础实验环境搭建 3、keepalived的虚拟路由管理 全局配置 ​编辑 配置虚拟路由器 4、虚拟路由的通讯设置 5、keepalived的日志分离 6、实现独立子配置文件 7、keepalived的抢占模式和非抢占…