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

news2024/11/19 17:34:31

目录

一、构造函数

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.coloradmin.cn/o/1478616.html

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

相关文章

利用R语言进行因子分析实战(数据+代码+可视化+详细分析)

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

C++重新入门-string容器

目录 1.包含头文件 2.创建字符串 3.获取字符串长度 4.字符串拼接 5.字符串比较 相等性比较 大小比较 使用比较函数 6.访问字符串 7.查找子串 8.字符串修改 替换子串 插入字符或子串 删除字符或子串 9.提取子串 10.总结 当谈到C中的字符串时,std::str…

蓝桥杯刷题3

目录: 1. 天干地支 2. 明明的随机数 3. ISBN号码 4. 缩位求和 5. 幸运数字 6. 串的处理 7. 最长递增 8. 灌溉 9. 特殊日期 10. 最大距离 1. 天干地支 import java.util.*;public class Main {public static void main(String[] args) {Scanner scan new Scanner(Sys…

spring boot集成Elasticsearch 7.16.3

环境&#xff1a;Elasticsearch 版本 7.16.3 Elasticsearch for windows下载地址 windows 若依 spring boot版本 2.6.0 pom文件添加 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch<…

Automated Testing for LLMOps 01:使用CircleCI进行持续集成CI

Automated Testing for LLMOps 这是学习https://www.deeplearning.ai/short-courses/automated-testing-llmops/ 这门课的笔记 Learn how LLM-based testing differs from traditional software testing and implement rules-based testing to assess your LLM application. …

Java实战:构建高效预报名管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

基于transform的scale属性,动态缩放整个页面,实现数据可视化大屏自适应,保持比例不变形,满足不同分辨率的需求

文章目录 一、需求背景&#xff1a;二、需求分析&#xff1a;三、选择方案&#xff1a;四、实现代码&#xff1a;五、效果预览&#xff1a;六、封装组件&#xff1a; 一、需求背景&#xff1a; 数据可视化大屏是一种将数据、信息和可视化效果集中展示在一块或多块大屏幕上的技…

GL绘制自定义线条4_使用OpenGL ES实现钢笔效果

在以前的文章里http://t.csdnimg.cn/TgCtl&#xff0c;我简述了如何使用OpenGL ES实现光滑的粗线条的绘制效果&#xff0c;在闲暇时间我把它再进一步进化&#xff0c;实现了端点长度按照压感大小实现伸缩的逻辑&#xff0c;从而实现了如下的笔锋效果&#xff1a; 书写过程中的效…

MCBPS配置成SPI

MCBPS配置成SPI 典型的SPI接口 McBSP作为SPI主机 以McBSP为主的SPI接口如图所示。当McBSP被配置为主控器时,发送输出信号(DX)被用作SPI协议的SPISIMO信号,并且接收输入信号(DR)被用作SPISOMI信号。 表列出了将McBSP配置为主控器所需的寄存器位值。下表是有关配置要求…

动环监控是什么?为什么说它是3d可视化机房的眼睛?

在信息化时代的背景下&#xff0c;数据中心机房的重要性日益凸显&#xff0c;传统的人工管理模式显然已经无法应对持续增长的机房数量和规模、日益复杂的网络、频繁更新迭代的资产硬件......搭建3d可视化机房成为了许多企事业单位的共同选择。想要搭建3d可视化机房&#xff0c;…

iOS中卡顿产生的主要原因及优化思路

卡顿本质上是一个UI体验上的问题&#xff0c;而UI的渲染及显示&#xff0c;主要涉及CPU和GPU两个层面。若 CPUGPU渲染耗时超过16.7ms&#xff0c;就会在屏幕vsync信号到来时无法更新屏幕内容&#xff0c;进而导致卡顿。 iOS中UI渲染主要包含Layout->Draw->Prepare->Co…

在原有项目进行业务逻辑开发:同一用户短时间不得提交多次申请,以及更新主表时数据刷新掉了角色权限以及密码重置的问题,详细思路及代码

开发背景&#xff1a; 用户提交表单后&#xff0c;插入到对应数据库表的字段中去&#xff0c;因需要保存是哪一个用户提交的&#xff0c;所以需要拿到主表的user_id&#xff0c;更新功能为记录提交时间&#xff0c;短时间不得再次提交 在对一个已有角色权限分配&#xff0c;登录…

蓝牙耳机和笔记本电脑配对连接上了,播放设备里没有显示蓝牙耳机这个设备,选不了输出设备

环境&#xff1a; WIN10 杂牌蓝牙耳机6s 问题描述&#xff1a; 蓝牙耳机和笔记本电脑配对连接上了&#xff0c;播放设备里没有显示蓝牙耳机这个设备&#xff0c;选不了输出设备 解决方案&#xff1a; 1.打开设备和打印机&#xff0c;找到这个设备 2.选中这个设备&#…

【iOS ARKit】协作 Session 实例

协作 Session 使用注意事项 协作 Session 是在 ARWorldMap 基础上发展起来的技术&#xff0c;ARWorldMap 包含了一系列的地标、ARAnchor 及在观察这些地标和 ARAnchor 时摄像机的视场&#xff08;View&#xff09;。如果用户在某一个位置新创建了一个 ARAnchor&#xff0c;这时…

C++之善用const修饰成员函数

C之善用const修饰成员函数 文章目录 C之善用const修饰成员函数前言1. 约束函数对成员变量的修改2. 允许 const 对象调用3. 在重载函数中提供重载决策总结 前言 ​ 在C编程中&#xff0c;使用const修饰成员函数是一种非常重要的技术手段&#xff0c;它能够提高代码的可维护性、…

基于Python微博舆情数据爬虫可视化分析系统+可视化+情感分析+爬虫+机器学习(完整系统源码+数据库+详细文档)

文章目录 基于Python微博舆情数据爬虫可视化分析系统可视化情感分析爬虫机器学习&#xff08;完整系统源码数据库详细文档&#xff09;源码资料获取在文章末尾1、项目介绍 Pycharm介绍Python语言Echarts简介Navicat Premium 15简介MySQL简介Flask简介 2、项目界面UI详情源码资料…

事物管理(黑马学习笔记)

事物回顾 在数据库阶段我们已学习过事务了&#xff0c;我们讲到&#xff1a; 事物是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功&#xff0c;要么同时…

Windows PowerShell 命令行历史记录补全

Windows 命令行历史记录补全 使用 powershell 安装PSReadLine 2.1.0 Install-Module PSReadLine -RequiredVersion 2.1.0检查是否存在配置文件 Test-path $profile # 为 false 则执行命令创建 New-item –type file –force $profile编辑配置文件 notepad $profile# 输入如下…

springboot 实现本地文件存储

springboot 实现本地文件存储 实现过程 上传文件保存文件&#xff08;本地磁盘&#xff09;返回文件HTTP访问服务器路径给前端&#xff0c;进行效果展示 存储 服务端接收上传的目的是提供文件的访问服务&#xff0c;对于SpringBoot而言&#xff0c;其对静态资源访问提供了很…

Python程序的流程

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 年轻是我们唯一拥有权利去编制梦想的时…