类和对象(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.mzph.cn/news/709706.shtml

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

相关文章

ZMQ的介绍与应用

文章目录 一、ZMQ是什么二、ZMQ的特点三、ZMQ的优缺点优点:缺点 四、ZMQ的应用场景 一、ZMQ是什么 zmq是ZeroMQ的简称,它是一个传输层的socket库,旨在使Socket编程更加简单、简洁和高效。它是一个消息处理队列库,可以在多个线程、…

项目解决方案: 实时视频拼接方案介绍

目 录 1、实时视频拼接概述 2、适用场景 3、系统介绍 3.1拼接形式 3.1.1横向拼接 3.1.2纵向拼接 3.2前端选择 3.2.1前端类型 3.2.2推荐配置 3.3后端选择 3.3.1录像回放 3.3.2客户端展示 4、拼接方案介绍 4.1基于4K摄像机的拼接方案 4.1.1系统架构…

Pytorch从零开始实战19

Pytorch从零开始实战——生成手势图像 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——生成手势图像环境准备模型选择模型训练模型分析总结 环境准备 本文基于Jupyter notebook,使用Python3.8,Pytorch2.0.1cu118&…

算法|344.反转字符串 541. 反转字符串II 卡码网:54.替换数字 151.翻转字符串里的单词 卡码网:55.右旋转字符串

344.反转字符串 考察reverse, 也可以用其他方法 /** * param {character[]} s* return {void} Do not return anything, modify s in-place instead.*/ var reverseString function (s) {return s.reverse(); };541. 反转字符串 思路: 一般是i&#…

vue-router4 (七) 滚动行为(scrollBehavior )

应用场景: 从A组件进入B组件,再返回A组件后,想让A组件的页面回到进入B组件前的位置,或者自动刷新回到A组件顶部,就需配置路由的滚动行为(scrollBehavior )。 ①返回A组件时,让A组件…

webrtc

stun服务 阿里云服务器安全组添加端口开放 webrtc-streamer视屏流服务器搭建 - 简书

Prometheus-监控远程linux的主机

一、本地访问 1、访问 http://8.137.122.212:9090/2、查看监控的主机 默认只监控了本机一台主机 这里的IP地址原本是‘localhost’,为了方便我将‘localhost’换成了主机的IP地址 现在看只监控了本机一台主机 3、查看监控数据 通过http://8.137.122.212:9090/m…

RT-Thread studio上创建一个STM32F103的CAN通讯功能

前言 (1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动实习岗位,可C站直接私聊,或者邮件:zhangyixu02gmail.com,此消息至2025年1月1日前均有效 (2&#xff0…

学Python如此简单--用Python实现一个超简单的学生信息管理系统

简介 系统名称:番茄系统 实现功能:增删查改 运用技术:python基础 代码 import time student_all [] print(欢迎进入番茄系统.center(30)) print(**36,end) while True:pee 请选择功能:1、添加学生2、删除学生3、修改学生4、…

1.1 编程环境的安装

汇编语言 汇编语言环境部署 第二个运行程序直接双击安装一直下一步即可MASM文件复制到D盘路径下找到dosbox安装路径:C:\Program Files (x86)\DOSBox-0.74找到该文件双击打开它,修改一下窗口大小 把这两行改成如下所示 运行dos,黑框中输入mou…

C#,数值计算,求解微分方程的吉尔(Gear)四阶方法与源代码

1 微分方程 微分方程,是指含有未知函数及其导数的关系式。解微分方程就是找出未知函数。 微分方程是伴随着微积分学一起发展起来的。微积分学的奠基人Newton和Leibniz的著作中都处理过与微分方程有关的问题。微分方程的应用十分广泛,可以解决许多与导数…

RTCA DO-178C 机载系统和设备认证中的软件注意事项-软件配置管理流程(七)

7.0 软件配置管理流程 SOFTWARE CONFIGURATION MANAGEMENT PROCESS 本节讨论软件配置管理 (SCM) 过程的目标和活动。 SCM 流程按照软件计划流程(参见 4)和软件配置管理计划(参见 11.4)的定义进行应用。 SCM 过程的输出记录在软件…

【探索AI】Sora - 探索AI视频模型的无限可能

Sora - 探索AI视频模型的无限可能 随着人工智能技术的飞速发展,AI视频模型已成为科技领域的新热点。而在这个浪潮中,OpenAI推出的首个AI视频模型Sora,以其卓越的性能和前瞻性的技术,引领着AI视频领域的创新发展。让我们将一起探讨…

【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection

sqli-labs-master 21-37 Advanced-Injection 第一关到第二十关请见专栏 文章目录 sqli-labs-master 21-37 Advanced-Injection第二十一关-Cookie注入第二十二关-Cookie注入第二十三关-注释符过滤的报错注入第二十四关-二次注入第二十五关-过滤OR、AND双写绕过第二十五a关-过滤…

老卫带你学---leetcode刷题(190. 颠倒二进制位)

190. 颠倒二进制位 问题 颠倒给定的 32 位无符号整数的二进制位。 提示: 请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应…

《Flask入门教程》学习笔记

《Flask入门教程》官网:https://tutorial.helloflask.com/ 目录 第一章:准备工作第二章:Hello, Flask!第三章:模板第四章:静态文件第五章:数据库第六章:模板优化第七章:表单第八章&a…

【嵌入式——QT】日期与定时器

日期 QTime:时间数据类型,仅表示时间,如 16:16:16;QDate:日期数据类型,仅表示日期,如2024-1-22;QDateTime:日期时间数据类型,表示日期和时间,如2…

多个版本的Python如何不冲突?

转载文章,防止忘记或删除 转载于:电脑中存在多个版本的Python如何不冲突? - 知乎 (zhihu.com) 如何安装多版本的Python并与之共存? 如果你的工作涉及到Python多版本之间开发或测试,那么请收藏本文, 如果你…

【python】Python Turtle绘制流星雨动画效果【附源码】

在这篇技术博客中,我们将学习如何使用 Python 的 Turtle 模块绘制一个流星雨的动画效果。通过简单的代码实现,我们可以在画布上展现出流星闪耀的场景,为视觉带来一丝神秘与美感。 一、效果图: 二、准备工作 (1)、导入…

每日一题——LeetCode1544.整理字符串

方法一 字符串转数组删除元素 将字符串转为数组&#xff0c;遍历数组&#xff0c;如果碰到同一字母大写小写连续出现就原地删除这两个元素&#xff0c;最后把数组转回字符串并返回 var makeGood function(s) {let arrs.split()for(let i0;i<s.length-1;i){if(arr[i]!arr[…