【c++初阶】类与对象(中)

请添加图片描述

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 追风赶月莫停留 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 平芜尽处是春山🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅

🍋类与对象

  • 🍑类的默认成员函数
  • 🍑构造函数
    • 🍍定义
    • 🍍特点
    • 🍍实际用法
  • 🍑析构函数
    • 🍍定义
    • 🍍特点
    • 🍍实际用法
  • 🍑拷贝构造函数
    • 🍍定义
    • 🍍特点
    • 🍍实际用法
  • 🍑赋值重载函数
    • 🍍运算符重载
      • 🍌定义
      • 🍌特点
      • 🍌实际用法
    • 🍍赋值运算符重载
  • 🍑取地址及const取地址操作符重载

🍑类的默认成员函数

上一个篇章,我讲解了类的基本概念和一些简单的语法,今天我就来讲解类中重要的几个成员函数,这几个成员函数,在我们今后学习过程对我们有非常大的重用,今天就单独拿出来,详细的为大家讲解。

类里面大致有六个成员函数:

  1. 初始化和清理:起初始化作用的成员函数,是构造函数。起清理作用的成员函数,是析构函数。

  2. 拷贝赋值:起拷贝作用的成员函数,是拷贝函数。起赋值作用的成员函数,是赋值重载。赋值重载又分为运算符重载和函数重载。

  3. 取地址重载: 大家可以按照字面意思理解。

🍑构造函数

🍍定义

构造函数是一种特殊的方法,主要用于在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。构造函数的名称应与类的名称完全相同,它不具有任何类型,也没有返回值。构造函数的主要目的是在创建对象时执行一些初始化操作,确保对象在创建时处于正确的状态。

构造函数是一个特殊的成员函数,需要注意的是构造函数虽然名称叫构造,但是构造函数的主要任务并不是看空间创建对象,而是初始化对象。

🍍特点

  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载。
  5. 构造函数可以带参数,这使得程序员能够在创建对象时提供初始值,这种带参数的构造被称为带参构造函数。
  6. 如果在类中没有显示定义构造函数,系统会自动提供一个默认构造函数,这个默认构造函数不会执行任何操作,所有的成员变量都将使用其默认值进行初始化。无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

注意
8. 我们不写构造函数,编译器默认生成的那个函数,叫默认构造函数。
9. 无参构造函数也可以叫默认构造函数。
10. 全缺省函数也可以叫默认构造函数。

默认构造还有一个缺陷:C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char/double等等,自定义类型就是我们自己根据语法规则重新定义的class/struct等等。系统只会处理自定义类型,而不会处理内置类型成员。但是在C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。

🍍实际用法

  1. 现在我们根据上面构造函数的特点实际用代码给大家演示:

在这里插入图片描述
构造函数名称与类名相同,且无返回值。

构造函数可以重载,在这里也就是一个带参数,一个不带参数。

  1. 调用无参构造函数时,对象后面不用跟括号,否则就成了函数声明。

如:

在这里插入图片描述
这样写就不是调用该函数了,只是声明了v3函数,该函数无参,返回一个Add类型的对象。

  1. 现在针对默认构造解释:

在这里插入图片描述

在这里插入图片描述

在类中没有显示定义时,从上图中可以看出left和right是随机值。这是系统默认生成了默认构造。

在这里插入图片描述

在这里插入图片描述

上图中,程序成功运行,也就是说全缺省构造函数也是相当于默认构造函数,但是半缺省不是默认构造函数。

在这里插入图片描述
在这里插入图片描述

当有显示定义构造后,系统就不会生成默认的构造函数,这里就会报错。

  1. 上面在构造函数特点中写到,“C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。”

在这里插入图片描述

在C++11中类里面自定义类型可以在声明时赋初值但是自定义类型还不可以。

🍑析构函数

🍍定义

析构函数是C++中的一个特殊成员函数,它在对象的生命周期结束时自动被调用。析构函数的主要任务是释放对象在生命周期中可能获取的所有资源,如动态分配的内存等等。

析构函数与构造函数的功能相反,。析构函数不是完成对象本身的销毁。局部对象销毁工作时由编译器完成,而对象在销毁时会自动调用析构函数,完成对象中资源的清理

🍍特点

  1. 析构函数名与类名相同,只不过需要在名前加字符~。
  2. 无参数和无返回值。
  3. 一个类只能有一个析构函数,若未显示定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。
  4. 对象生命周期结束时,C++编译系统自动调用析构函数。
  5. 析构函数的执行顺序与构造函数相反。首先构造的对象,最后析构,最后构造的对象,首先析构。

🍍实际用法

  1. 普通写法:

在这里插入图片描述
这是普通函数的写法,没有涉及到空间的释放。当然也可以不写。没有空间使用时,都可以使用系统提供的默认析构函数就可以了。

  1. 有空间释放的析构函数的写法:
    在这里插入图片描述
    这就是栈中析构函数的写法。

  2. 析构函数与构造函数的执行顺序:

在这里插入图片描述
在这里插入图片描述

大家从上图中应该就可以看出,析构函数和构造函数的执行顺序是相反。

🍑拷贝构造函数

🍍定义

拷贝构造函数是一个特殊的构造函数,用于创建一个新对象作为现有对象的副本。

拷贝构造函数大家可以从字面来理解,什么是拷贝,不就是复制吗,专业语就是赋值,下面会为大家详细解释。

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

但是需要注意的是拷贝有深拷贝和浅拷贝。大致的说就是有部分开了空间,就需要深拷贝。没有开空间就只要浅拷贝。

🍍特点

  1. 拷贝构造函数是构造函数的一个重载形式。
  2. 无返回值但有一个参数。
  3. 拷贝分为浅拷贝和深拷贝。
  4. 每个类都存在拷贝构造函数,尽管不显示定义,编译器会提供默认的拷贝构造函数。
  5. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引起无限递归

🍍实际用法

  1. 浅拷贝,也就是没有占用空间:

在这里插入图片描述
在这里插入图片描述

该类中拷贝构造就如上图所写,拷贝构造有两种写法。

  1. 深拷贝,占用空间:

在这里插入图片描述
典型的拷贝构造函数,就是栈中的拷贝构造函数,由于栈是占用空间的,它的拷贝构造是一定会深拷贝。

当然还有一种特殊的情况,就是队列,队列虽然也占用了空间,但是实际上它是调用栈的拷贝构造函数,大家有兴趣可以去试试。

  1. 传值引发的无限递归拷贝:

在这里插入图片描述
错误写法就是传值拷贝,会引发无限递归。

过程:

在这里插入图片描述
值传递是会调用拷贝构造。

传值拷贝本身并不会直接导致程序无限递归,无限递归是由于函数不断的调用自身,且没有适当结束的条件,就形成了无限递归。

为了防止这种错误,拷贝构造必须使用指针或者引用,不过现在常用的是引用,很少指针。

总结:

  1. 内置类型成员完成值拷贝。
  2. 自定义类型成员调用这个成员的拷贝构造(前提是有一个成员的拷贝构造,如:队列调用栈的拷贝构造)。
  3. 顺序表、链表、二叉树等等的类,都需要深拷贝。

🍑赋值重载函数

🍍运算符重载

🍌定义

运算符重载是C++中一项强大的特性,它允许程序员重新定义或重载大部分C++内置的运算符,以便它们能用于用户自定义的类型。通过运算符重载,可以使自定义类型的对象像内置类型一样使用运算符,从而提高代码的可读性和易用性。

🍌特点

  1. 不能通过连接其他符号来创建新的操作符:比如operator@
  2. 重载操作符必须有一个类类型参数
  3. 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义。
  4. 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  5. (.* :: sizeof ? : .) , 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

🍌实际用法

  1. 内置类型对象可以直接使用各种运算符,内置类型都是简单类型。

在这里插入图片描述
2. 自定义类型需要用关键字才能用运算符:

在这里插入图片描述
在这里插入图片描述
下面那种是operator不放在类里面的写法,不过operator基本都写在类里面,所以还有一种写法:
在这里插入图片描述

当然不仅仅只有这一种,还有减法等等。
在这里插入图片描述
大家从程序执行结果来看运算符==是看两者是否相等,相等返回1,不相等返回0。而<和>也是同样如此。返回的都是布尔值。

实际上operator是一个函数,如:

在这里插入图片描述

在这里插入图片描述
这就是operator在类中的写法。

有的人可能会问传过去的不是两个参数吗,为什么在operator中只接收了一个参数?问出这个问题的可能是忘了C++中的this指针,this指针已经指向了第一个参数,所以不用传第一个参数过去。

🍍赋值运算符重载

  1. 参数类型:const T&,传递引用可以提高传参效率
  2. 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  3. 检测是否自己给自己赋值
  4. 返回*this :要复合连续赋值的含义

在这里插入图片描述

上图中就是赋值运算符重载的写法。

赋值运算符只能重载成类的成员函数不能重载成全局函数,否则就要传同等数量的参数了。

在前面有写了默认构造函数和默认析构函数等等,这里赋值运算符重载,也是有相关默认赋值运算符重载,用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝,内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。对于一些没有涉及到资源管理的可以用系统默认的赋值运算符重载,而涉及到的就必须自己重新写,比如栈等等。

🍑取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

在这里插入图片描述
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需
要重载,比如想让别人获取到指定的内容!

本次所写到的六个类的默认成员函数的知识点,到此就写完了,如果有些知识点我写的有误或者没写到,欢迎大家指正!!!

请添加图片描述
请添加图片描述

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

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

相关文章

Transformer论文阅读

Transformer论文阅读 摘要结论1 Introduction &#xff08;导言&#xff09;2 Background3 Model Architecture3.1 Encoder and Decoder StacksEncoderLayer NormDecoder 3.2 Attention3.2.1 Scaled Dot-Product Attention3.2.2 Scaled Dot-Product Attention3.2.3 Application…

4月1日起,未备案App小程序将下架

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 最后2天了、最后2天了。 从2024年4月1日起&#xff0c;工信部要求所有的APP、小程序都要备案&#xff0c;否则下架、关停、限制更新。这是去年8月份出的新规&#xff0c;没想到十个月这么快就过去了。 现在广东省…

深入解析大语言模型显存占用:训练与推理

深入解析大语言模型显存占用&#xff1a;训练与推理 文章脉络 估算模型保存大小 估算模型在训练时占用显存的大小 全量参数训练 PEFT训练 估算模型在推理时占用显存的大小 总结 对于NLP领域的从业者和研究人员来说&#xff0c;有没有遇到过这样一个场景&#xff0c;你的…

某东推荐的十大3C热榜第一名!2024随身wifi靠谱品牌推荐!2024随身wifi怎么选?

一、鼠标金榜&#xff1a;戴尔 商务办公有线鼠标 售价:19.9&#xffe5; 50万人好评 二、平板电脑金榜&#xff1a;Apple iPod 10.2英寸 售价:2939&#xffe5; 200万人好评 三、随身WiFi金榜&#xff1a;格行随身WiFi 售价:69&#xffe5; 15万人好评 四、游戏本金榜&#xff…

Gromacs模拟一:配体-双链蛋白质复合物体系准备

1、蛋白质的准备&#xff1a; 在RCSB网站下载想要的蛋白晶体&#xff08;教程里是3htb&#xff09;&#xff0c;用notepad等编辑器或是分子可视化软件除去里面的非蛋白分子或离子。 这里采用的是一个经过分子对接后的蛋白质pdb和配体小分子的pdb。 教程里提到的配体是2-丙基…

【Java多线程】5——Lock底层原理

5 Lock底层原理 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&…

新能源汽车充电桩常见类型及充电桩站场的智能监管方案

随着新能源汽车市场的迅猛发展&#xff0c;充电桩作为支持其运行的基础设施&#xff0c;也呈现出多样化的类型。这些充电桩不仅在外形和功能上存在差异&#xff0c;更在充电速度、充电方式以及使用场景等方面展现出独特的优势。 一、充电桩类型及区别 1、慢充桩&#xff08;交…

Go 之 Gin 框架

Gin 是一个 Go (Golang) 编写的轻量级 web 框架&#xff0c;运行速度非常快&#xff0c;擅长 Api 接口的高并发&#xff0c;如果项目的规模不大&#xff0c;业务相对简单&#xff0c;这个时候我们也推荐您使用 Gin&#xff0c;特别适合微服务框架。 简单路由配置 package mai…

Linux 系统快速安装 nginx (新手版)

1、安装所需依赖 yum -y install pcre pcre-devel gcc openssl openssl-devel zlib zlib-devel &#xff08;pcre&#xff1a; 包括 perl 兼容的正则表达式库 openssl&#xff1a; 支持安全传输协议https(和财务有关系的请求会走的协议) 创建运行用户、组 useradd -M -…

变分信息瓶颈

变分信息瓶颈和互信息的定义 1 变分信息瓶颈 定义&#xff1a;变分信息瓶颈&#xff08;Variational Information Bottleneck&#xff09;是一种用于学习数据表示的方法&#xff0c;它旨在通过最小化输入和表示之间的互信息来实现数据的压缩和表示学习。这种方法通常用于无监…

Oracle VM(虚拟机)性能监控工具

Oracle VM是一个独立的虚拟化环境&#xff0c;由 Oracle 提供支持和设计&#xff0c;旨在为运行虚拟机提供轻量级、安全的基于服务器的平台。Oracle VM 能够在受支持的虚拟化环境中部署操作系统和应用软件&#xff0c;Oracle VM 将用户和管理员与底层虚拟化技术隔离开来&#x…

ctfshow xxe web373-378

web373 libxml_disable_entity_loader(false)&#xff1a;这行代码用于启用实体加载器&#xff0c;允许加载外部实体。 $xmlfile file_get_contents(php://input)&#xff1a;从输入流中读取XML数据并存储在 $xmlfile 变量中。 $dom->loadXML($xmlfile, LIBXML_NOENT |…

FebHost:意大利.IT域名一张意大利网络名片

.IT域名是意大利的国家顶级域名&#xff0c;对于意大利企业和个人而言,拥有一个属于自己的”.IT”域名无疑是件令人自豪的事。这个被誉为意大利互联网标志性代表的域名,不仅隐含着浓厚的意大利文化特色,还为使用者在当地市场的推广铺平了道路。 对于那些希望在意大利市场建立强…

微信开发者工具接入短剧播放器插件

接入短剧播放插线 申请添加插件基础接入app.jsonapp.jsplayerManager.js数据加密跳转到播放器页面运行出错示例小程序页面页面使用的方法小程序输入框绑定申请添加插件 添加插件:登录微信开发者平台 ——> 设置 ——> 第三方设置 ——> 插件管理 ——> 搜索“短剧…

基于SpringBoot + Vue实现的养老院管理系统设计与实现+毕业论文(12000字)+搭建视频

介绍 养老院管理系统是一款运用软件开发技术设计实现的应用系统&#xff0c;在信息处理上可以达到快速的目的&#xff0c;不管是针对数据添加&#xff0c;数据维护和统计&#xff0c;以及数据查询等处理要求&#xff0c;养老院管理系统都可以轻松应对。 系统包含登录、注册、…

Linux 系统 docker搭建LNMP环境

1、安装nginx docker pull nginx (默认安装的是最新版本) 2、运行nginx docker run --name nginx -p 80:80 -d nginx:latest 备注&#xff1a;--name nginx 表示容器名为 nginx -d 表示后台运行 -p 80:80 表示把本地80端口绑定到Nginx服务端的 80端口 nginx:lates…

【YOLOv5改进系列(9)】高效涨点----使用CAM(上下文增强模块)替换掉yolov5中的SPPF模块

文章目录 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ CAM模块详细介绍二、2️⃣CAM模块的三种融合模式三、3️⃣如何添加CAM模块3.1 &#x1f393; 添加CAM模块代码3.2 ✨添加yolov5s_CAM.yaml文件3.3 ⭐️修改yolo.py文相关文件 四、4️⃣实验结果4.1 &#x1f39…

Leetcode 82. 删除排序链表中的重复元素 II

给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5] 提示&#xff1a; 链表中节点数目在范围 [0, 300] 内 -100 < Node.…

一些实用的功能函数

1. 【算法】求两个数中&#xff0c;bit位不同的个数&#xff08;在计网那道题中用过&#xff09; 解法&#xff1a;首先把两位数异或&#xff0c;得到的结果&#xff0c;通过自身跟自身-1相与&#xff0c;直到等于0为止 代码如下&#xff1a; int calculateNotSam(int a,int …

uniapp怎么使用接口返回的iconfont图标

uniapp怎么使用接口返回的iconfont图标 首先在你的项目中添加该图标&#xff0c;名称要对应 实际应用 item.ICONFONT_NAME“tools”; item.ICONFONT_COLOR“FA5151”; <view class"iconfont" :class"icon-item.ICONFONT_NAME" :color"item.ICON…