类和对象(2)——距离C++又近了一步

目录

一、构造函数

1.1声明和定义构造函数

1.2成员名和参数名

1.3构造函数的使用

1.4初始化列表

二、析构函数

2.1析构函数的概念

2.2析构函数的性质

三、拷贝构造函数

四、赋值运算符重载

4.1运算符重载

4.2赋值运算符重载


一、构造函数

我们知道,C++中类的数据部分的访问状态是私有的,这就意味着程序不能直接访问数据成员,而只能通过成员函数来访问数据成员。为了让创建的实例化对象一开始都有一个合适的初始值(如果需要额外调用函数赋初值未免太过麻烦),C++提供了一个特殊的成员函数——类构造函数,C++提供了函数的名称和语法,而程序员需要提供方法定义。名称和类名相同。

构造函数是一个特殊的成员函数名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。

1.1声明和定义构造函数

已知我们的构造函数名和类名相同,现在我们来定义一个Date类的构造函数:

1.2成员名和参数名

如果我们不熟悉构造函数,我们可能会试图将类成员名称用作构造函数的参数名,如下所示:
其实这样是不对的。构造函数的参数表示的不是类成员,而是赋给类成员的值。因此,二者不能相同,否则代码就会出现上图的情况,如"year = year",虽然系统会默认传一个 this 指针,但是我们也应该避免这种混淆,以下给出两种解决方案:

我比较不听从他们的建议,我选择了在数据成员中使用 _ 前缀,其实大家也可以按照自己的喜好随意命名,这里只是提供一种思路。

1.3构造函数的使用

这里有两种使用构造函数的语法,而且提供了一个错误案例:

d3的报错也说明了系统不允许创建未初始化的对象,但是当我们没有人为提供构造函数时,系统会自动生成默认构造函数,无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个:

注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为
是默认构造函数
此时我们也可以调用 Print() 查看系统的默认构造函数:另外,C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在​​​​​​​类中声明时可以给默认值(但这只能成为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值):

1.4初始化列表

除了上述的声明和定义构造函数,还有一种初始化方式就是初始化列表,初始化列表是指以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

为什么学习完之前的构造函数还要再学这种呢?这并非画蛇添足,而是在一些情境下,必须使用初始化列表,下面列出几种情况:
1.引用成员变量
2.const成员变量
3.自定义类型成员(且该类没有默认构造函数时)

下面我们来介绍一下初始化列表的一些性质:
1.初始化列表有一个走后门之处:不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化,如果没有,再进入函数体内部寻找。
2.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

二、析构函数

2.1析构函数的概念

学指针时,我们创建一个指针后还要把它销毁,那我们能创建一个对象,如何销毁一个对象呢?
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

2.2析构函数的性质

析构函数是特殊的成员函数,其特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值类型。析构函数必须是 ~类名()
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

我们在这里创建的Date类的析构函数不承担任何重要的工作,因此可以将它编写为不执行任何操作的函数,当然,为了我们能明显地看出析构函数何时被调用,可以这样编写代码:
另外,我们还要知道的是,越早创建的对象,析构函数的调用越靠后:

最后,我们想谈的就是不同区域的函数最终按什么顺序完成析构?
局部对象(先定义后析构)-> 静态区域 -> 全局对象(先定义后析构)

三、拷贝构造函数

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

拷贝构造函数可以说是构造函数的重载形式,所以它的语法和构造函数类似:

和前面学过的两个函数类似,拷贝构造函数若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数是传值拷贝,也就是浅拷贝
注意:类中如果没有涉及资源申请时,拷贝构造函数是否自定义都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。

四、赋值运算符重载

4.1运算符重载

运算符重载是C++多态的一种体现。运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义,实际上,我们已经见过很多运算符重载的例子。如 * ,在指针运用上,它充当解引用的作用,而在两数相乘时,它有充当乘法的作用。

C++运算符重载语法如下:
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

1.如果我们要定义运算符重载,可能要访问类内private数据,此时我们可以直接将其定义为类的成员函数。
注意:这里的函数参数默认已经有了this指针,我们输入的_year其实是this->_year
           所以我们只需要再传入我们需要比较的另一个参数即可
2.如果我们要把函数定义在类外,那么我们要提前用到后面会学的友元函数(简单来说,被friend关键字修饰的函数可以访问类内的私有成员)/

4.2赋值运算符重载

我们想要类似拷贝构造函数一样的运算符重载,应该怎么办呢?下面假设我们的类 class Type

首先,我们要明确函数返回值类型应该是Type&,如下图:
然后我们现在先设计一个大概,有了之前this指针的经验,我们轻松就可以在类内设计出来: 
现在我们看一下还缺点什么?返回值!那么应该返回什么呢?环顾了四周,怎么什么都不能返回啊?非也非也,不要忘记了this指针!我们传参的时候可是默认传了个this指针呢!这个指针是谁?不就是我们要被赋值的对象吗?但要注意,我们返回的应该是解引用的this。
光说了类内,但是类外呢?我们运算符重载时可是学了两种方法啊,我记得在类外是用友元吧,那现在呢?赋值运算符重载在类外怎么实现呢?
当我们像运算符重载一样使用友元后:
哎呦呵,我才刚在类内声明呢,我类外还没实现呢,您怎么就给我报错了?
报错原因显而易见,下面我们来探讨一下为什么赋值运算符只能是成员函数呢。
答:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。
而其他的如值拷贝的内容、什么时候必须手写赋值运算符重载,就和拷贝构造函数的内容一致了,大家自行查阅:

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

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

相关文章

网络编程作业day2

1.将TPC和UDP通信模型各敲两遍 &#xff08;1&#xff09;TPC通信模型&#xff1a; 服务器代码&#xff1a; #include <myhead.h> #define SERVER_IP "192.168.125.136" #define SERVER_PORT 1314 int main(int argc, const char *argv[]) {//1、创建用于监…

Rocky Linux 运维工具 ls

一、ls 的简介 ​​ls​ 用于列出当前目录下的文件和目录&#xff0c;以及它们的属性信息。通过 ​ls​命令可以查看文件名、文件大小、创建时间等信息&#xff0c;并方便用户浏览和管理文件。 二、ls 的参数说明 序号参数描述1-a显示所有文件&#xff0c;包括以 ​.​开头的…

neo4j创建新数据库

根据网上提供的教程&#xff0c;neo4j并没有提供创建数据库的命令&#xff0c;其只有一个默认数据库graph.db&#xff0c;该数据库中的所有数据将存储在neo4j安装路径下的data/databases/graph.db目录中。 因此&#xff0c;我们猜想&#xff0c;如果我们将默认数据库的名字修改…

YOLOv8改进 | 独家创新篇 | 结合SOTA思想利用双主干网络改进YOLOv8(全网独家创新,最重磅的更新)

一、本文介绍 本文给大家带来的改进机制是结合目前SOTAYOLOv9的思想利用双主干网络来改进YOLOv8(本专栏目前发布以来改进最大的内容,同时本文内容为我个人一手整理全网独家首发 | 就连V9官方不支持的模型宽度和深度修改我都均已提供,本文内容支持YOLOv8全系列模型从n到x均可…

ardupilot 及PX4姿态误差计算算法对比分析

目录 文章目录 目录摘要1.APM姿态误差计算算法2.PX4姿态误差计算算法3.结论摘要 本节主要记录ardupilot 及PX4姿态误差计算算法差异对比过程,欢迎批评指正。 备注: 1.创作不易,有问题急时反馈 2.需要理解四元物理含义、叉乘及点乘含义、方向余弦矩阵含义、四元数乘法物理含…

C++ 网络编程学习三

C 网络编程学习三 用智能指针延长session的生命周期处理粘包问题 用智能指针延长session的生命周期 问题&#xff1a; 客户端断开后&#xff1a;会触发服务器对应session的写或读事件&#xff0c;由于是异步编程&#xff0c;需要在回调中对读写事件进行处理。客户端断开&#…

(libusb) usb口自动刷新

文章目录 libusb自动刷新程序Code目录结构Code项目文件usb包code包 效果描述重置reset热拔插使用 END libusb 在操作USB相关内容时&#xff0c;有一个比较著名的库就是libusb。 官方网址&#xff1a;libusb 下载&#xff1a; 下载源码官方编好的库github&#xff1a;Release…

@Slf4j 变量log找不到符号,可能是 Gradle 配置文件写得有问题

Slf4j 变量log找不到符号 鄙人在学习 Java 的 spring boot 项目时, 常常因为 maven 配置文件使用 xml 格式过于复杂, 所以更倾向于使用 gradle 作为构建工具. 然而, 在使用 gradle 作为构建工具时, 又需要引用 Lombok 依赖. 有时忘记在初始化项目时添加上 Lombok 依赖, 所以经…

本届挑战赛亚军方案:基于大模型和多AGENT协同的运维

“轻舟已过万重山团队”荣获本届挑战赛亚军&#xff0c;该团队来自华为集团IT-UniAI 产品和openEuler系统智能团队。 方案介绍 自ChatGPT问世以来&#xff0c;AI迎来了奇点iPhone时刻&#xff0c;这一年来大模型深入影响企业办公&#xff0c;金融&#xff0c;广告&#xff0c;…

SDWAN异地组网难在哪?怎么解决?

SD-WAN作为一种先进的网络技术&#xff0c;为企业提供了更加灵活和高效的网络连接方案。然而&#xff0c;在异地组网的过程中&#xff0c;SD-WAN也面临一些挑战。本文将探讨SD-WAN异地组网所面临的难题&#xff0c;并提供相应的解决方案。 挑战一&#xff1a;网络延迟和不稳定性…

ptython迭代器与生成器

迭代器 Python中的迭代器&#xff08;Iterator&#xff09;是一种强大的工具&#xff0c;用于访问集合元素。它是一种可以记住遍历位置的对象&#xff0c;这意味着迭代器不会一次性生成所有的元素&#xff0c;而是可以等到需要的时候才生成&#xff0c;从而节省了大量的内存资…

智慧城市:打造宜居环境,引领未来可持续发展

随着科技的不断进步与创新&#xff0c;我们的城市正步入一个崭新的时代——智慧城市。智慧城市是指运用信息技术和大数据等现代科技手段&#xff0c;对城市基础设施、公共服务和社会管理进行智能化改造&#xff0c;实现城市各领域的智能化、信息化和高效化。今天&#xff0c;就…

SQL函数学习记录

聚合函数 函数是编程语言的基础之一&#xff0c;在对数字的运算中&#xff0c;我们用的最多的就是聚合函数&#xff0c;本篇接下来就详细阐述下SQL中聚合函数的运用。 什么是聚合函数&#xff08;aggregate function&#xff09;&#xff1f; 聚合函数指的是对一组值执行计算…

Pytorch模型训练后静态量化并加载int8量化模型推理

目录 一、源码包准备1.1 源码包获取1.2 代表性验证集1.3 Pytorch模型1.4 推理测试图片 二、环境准备三、模型转换3.1 参数修改3.2 代码3.3 量化转换结果3.4 量化前后模型大小对比 四、量化模型推理4.1 参数修改4.2 代码4.3 推理结果4.4推理时间 五、总结 一、源码包准备 1.1 源…

什么是Sectigo?如何优惠申请?

Sectigo&#xff0c;全球领先的SSL/TLS证书提供商&#xff0c;以其卓越的安全性能和广泛的认可度赢得了业界的一致好评。我们的证书不仅能加密您的网站通信&#xff0c;确保敏感信息传输过程中的绝对安全&#xff0c;还能显著提升您的网站信誉&#xff0c;让访客一眼就能识别出…

价格战打响!阿里云服务器和腾讯云服务器价格对比

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器62元一年&#xff0c;2核2G3M、2核4G、4核8G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配置价格表…

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术&#xff0c;用户可以身临其境地体验各种紧急情况&#xff0c;如火灾、地震、交通事故等&#xff0c;以及应对这些紧急情况的…

第三百七十四回

文章目录 1. 概念介绍2. 实现方法2.1 基本用法2.2 特殊用法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"分享三个使用TextField的细节"相关的内容&#xff0c;本章回中将介绍如何让Text组件中的文字自动换行.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.…

leetcode刷题(剑指offer) 46.全排列

46.全排列 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a; 输入&#…

STM32F103学习笔记(七) PWR电源管理(原理篇)

目录 1. PWR电源管理简介 2. STM32F103的PWR模块概述 2.1 PWR模块的基本工作原理 2.2 电源管理的功能和特点 3. PWR模块的常见应用场景 4. 常见问题与解决方案 1. PWR电源管理简介 PWR&#xff08;Power&#xff09;模块是STM32F103系列微控制器中的一个重要组成部分&…