“三步走”带你拿下C++类与对象(下)

在学习了“上”篇和“中”篇后,我们对类和对象以及一些析构函数有了一定的理解,本文我们将继续深入讲解有关的其他内容。

一、初始化列表的引入

我们以之前的队列为例子(创建两个队列一个用于入栈一个用于出栈)

这个myqueue对内置类型不做处理,对自定义类型会调用其相应的构造函数,这是我们根据之前的知识得来的结论,但现在如果我们的栈不提供默认构造呢?(声明一下:在栈中,我们之前写的显示构造函数是全缺省的开辟空间的函数)此时,myqueue也无法生成其对应的构造,为了使程序正常运行,办法就是在myqueue下的类显示地去写构造,也就引入了初始化列表。

初始化列表的格式:冒号开始,逗号分割,写在构造函数的下方,如图所示

这里作者的理解是,因为stack的类已经没有默认构造函数了,它的同名函数可能是一个需要传参才能进行初始化的函数。此时需要我们写一个queue的构造函数,通过走这个函数来进行对stack类的初始化。注意,下面的{}不可省略。这样,内置类型_size就初始化为0,而作为自定义类型pushst和popst此时就可以调用他们自己创建的类之下的构造函数了(因为已经传参n了),当然,这个queue处写缺省值也是可以的。

初始化列表和函数体内初始化也可以混用,比如上面也可以这么写

初始化列表的本质可以理解为每个对象中成员定义的地方。(这里再强调一下,在queue这个类中,private中的成员只是声明,并没有开空间,而在初始化列表的地方就是将声明的成员进行定义,也就是开空间)

然而,有些对象必须在初始化列表进行初始化,在函数体内初始化就会报错。

比如1.const成员对象

这是因为,const变量必须在定义时被初始化,而我们刚才说初始化列表是成员定义的地方,所以要在上方初始化而不是函数体内部。

2.引用的对象

为了便于引用的初始化,我们增加一个形参。 

3.没有默认构造自定义类型成员(必须显示传参调构造)

——————————————————————————

初始化列表,不管我们写不写,每个对象都会走一遍,对于自定义类型就会去调用默认构造

即使我的初始化列表出什么也没写他也会将每个对象走一遍(此时stack类已经有默认构造函数才没有报错)

我们来看下面的一端代码

首先A类进行初始化,走初始化列表,由于main函数中传了参数所以_a1被初始化为1,然后_a1又作为参数进行_a2的初始化,按道理来讲运行结果应该是1 1,但结果确实1和随机值,为什么呢?关于初始化列表最后一个特点:成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。也就是说,在这个程序中,因为a2先声明,我们在走初始化列表的时候先走a2的初始化,由于此时a1是随机值所以a2的初始化为随机值,然后a1被初始化为1。至此,初始化列表的相关知识基本就这么多。接下来我们来看一个有意思的东西。

第一行是进行初始化,第二行是我们之前讲过的拷贝构造,可是第三行呢?为什么它不会报错。其实背后的猫腻是——隐式类型转换。也就是说,1并没有直接赋值给aa3,而是先构造一个A的临时对象,在用这个临时对象拷贝构造aa3,在这里进行了优化,也就是连续构造加拷贝构造优化为了直接构造。这个与我们之前学过的内置类型就对得上了。那再看看下面这个

56行的引用赋值为什么就会报错呢?首先这里也肯定有构造,也就是2创建一个A类型的临时对象,但不同的是这里面就没有拷贝构造了。也就是说aa4引用的是类型转换中用2构造的临时对象。但报错的原因其实是权限的放大,所以我们在前面加const即可。

这个东西到底有啥用呢?我们引入一个实例,栈的压栈操作。

这是正常写法,但不足的是,它首先要构造,然后作为参数传参又要拷贝构造造成浪费。此时,我们上面的操作就起作用了。

209行代码就可以平替207+208行,这样就直接实现相同的压栈操作了(2的隐式类型转换给了push函数,且注意要加const否则会报错,因为会造成权限的放大)那多参数的怎么搞呢?这里是这样规定的

同理,237+238行与240的压栈操作结果相同。

二、explicit关键字

如果我们不想进行隐式类型转换,把构造函数用explicit关键字修饰即可。

三、静态成员变量与静态成员函数

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量

如果我们去计算这个类的大小会发现是8而不是12,因为静态成员变量在静态区存储,类中不存储成员函数,不存储静态成员变量。此时我们不能在此处给缺省值,因为这个类走初始化列表的时候是不对静态成员变量进行初始化的。应该在全局进行定义。我们想访问的话,用以下两种办法均可

注意,此时是对静态成员变量进行了public处理,如果放在private中就会无法访问,但也有静态成员变量即是private同时我们也能访问的办法,用静态成员函数。

用static修饰的 成员函数,称之为静态成员函数。

注意,在静态成员函数中,我们无法访问类中其他对象的成员,只能访问静态成员,因为在静态成员函数中是没有this指针的。

这样就可以解决问题了。我们再总结一下静态成员变量和函数的一些特性:1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区   2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明   3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问   4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员   5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

四、友元

1.我们在(中)篇已经讲解了它的语法和用途,在此就简单再回顾一下即可,我们在实现日期类的时候,为了输出类中的内容,实现<<和>>运算符重载函数,发现为了符合我们所认知的cout和cin用法,这两个函数只能写在类域的外部,这就造成了无法访问类中成员的问题,为了解决我们引入了友元。

2.友元类

我们有时候创建两个类的时候,会想在其中一个类中去访问另一个类的成员,显然这是不可以的,但我们把它写成友元类即可,它的写法和友元函数相同 friend class 类名,可以写在想访问的类的任意位置。

这个地方声明的位置不要颠倒,这里是date类可以访问time类的成员,而time类仍无法访问date类 的成员。

五、内部类

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。它仅仅是受到外部类的类域限制。

看,我们在定义B类的变量时不可以直接去像A类那样写,就是因为类域的限制。但如果计算A类的大小,B类中的成员变量并不算入其中,这也进一步说明内部类和外部类的独立性。

但是B天生就是A的友元,这也是内部类的一个特点。内部类随便访问外部类,但外部类不可访问内部类。

六、匿名对象(了解即可)

假设我们随便写一个类,然后创建一个变量,但有时候我们创建的变量没有名字,就叫匿名对象,我们来感受一下他们的差别

35行就是匿名,37行就是我们平常所定义的变量。那么他们在功能上有什么差别呢?

匿名对象的生命周期只在当前这一行,也就是说代码走到35行时开始初始化,构造,一旦走到36行它就调析构函数。而且,我们用匿名对象去调用成员函数也可以在一行实现

————

此系列到此就完结撒花了,希望朋友们多多点赞,后续继续更新高质量文章。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全志R329 AP6256 蓝牙调试

1、在全志r329平台移植AP6256,移植了一个星期,记录下过程。 2、本来产品只需要wifi,不需要蓝牙的。但是我们使用的是正基AP6256的wifi、BT二合一的模组。 该模块只要有BT功能就需要做BT的3C认证。 好吧。 1、获取调试蓝牙的几个工具 两个方法: 1.1、方法一:自己交叉…

蓝桥杯2024年第十五届省赛真题-爬山

贪心优先队列的题&#xff0c;贪心会漏一个情况&#xff0c;不知道怎么处理&#xff0c;这里直接打表了 2 1 1 48 49 答案是30&#xff0c;贪心是31 专有名词&#xff1a;hack-有新的测试点过不了 #include<bits/stdc.h> using namespace std; #define endl \n #define …

QT C++ sqlite 对多个数据库的操作

//本文描述&#xff0c;QT 对多数据库的操作。 //你可能会想&#xff0c;多数据库的操作时&#xff0c;查询语句怎么知道是哪个数据库。 //QT提供了这样一种构造函数 QSqlQuery(const QSqlDatabase &db) //指定数据库 //在QT6.2.4 MSVC2019调试通过。 //效果见下图&am…

HarmonyOs开发:导航tabs组件封装与使用

前言 主页的底部导航以及页面顶部的切换导航&#xff0c;无论哪个系统&#xff0c;哪个App&#xff0c;都是最常见的功能之一&#xff0c;虽然说在鸿蒙中有现成的组件tabs可以很快速的实现&#xff0c;但是在使用的时候&#xff0c;依然有几个潜在的问题存在&#xff0c;第一&a…

12. MyBatis(二)

源码位置&#xff1a;MyBatis_demo 上篇文章我们学习了MyBatis的定义以及增删查改操作&#xff0c;并且学习了如何在xml文件中编写SQL时使用#{}的方式将参数和对象的属性映射到SQL语句中&#xff0c;上篇的内容已经足以应对大部分场景&#xff0c;本篇文章我们就要学习一下MyBa…

测绘管理与法律法规 | 测绘资质管理办法 | 学习笔记

目录 一、测绘资质概述 二、测绘资质分类与等级 三、审批与管理 四、申请条件 五、审批程序 六、测绘资质证书 七、监督管理 八、违规处理 九、特殊规定 十、审批受理时间要点补充 1. 审批机关决定是否受理的时间 2. 审批机关作出批准与否的决定时间 3. 颁发测绘资…

linux /proc进程文件目录介绍

参考&#xff1a;https://zhuanlan.zhihu.com/p/619966043 有时候想只查出来进程号&#xff0c;可以通过/proc/下查出该进程的运行及执行脚本情况信息 /proc/pid子目录 记录了进程的相关信息cmdline文件&#xff1a;包含了进程启动时使用的完整命令行参数。 cwd符号链接&#x…

29. 【Android教程】折叠列表 ExpandableListView

本节学习一个可折叠的 ListView&#xff0c;可以用在一些需要分类的场景下。通过 ExpandableListView 我们可以首先在 ListView 上展示大的分类&#xff0c;当点击某个类别的时候再将 ListView 做一个展开&#xff0c;展示该类下的所有子类供用户选择。它与 ListView 的不同主要…

考研数学|武忠祥VS张宇,谁讲得更全面❓

张宇和武忠祥都是很好的老师&#xff0c;你肯定也是这么觉得的&#xff0c;你自己也说了&#xff0c;跟着张宇看了几章&#xff0c;感觉不错&#xff0c;那就继续跟着啊&#xff0c;为什么听到同学说武忠祥好&#xff0c;你就动摇了呢。我们对于任何事情都要有自己的思考和规划…

SQL注入简单总结

一、SQL注入是什么 SQL注入即&#xff1a;是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…

prompt问题【中间不好】

问题1:longchain 关键词在中间容易被忽略掉 Found in the Middle: How Language Models Use Long Contexts Better via Plug-and-Play Positional Encoding 论文对大模型在长文本情况下的性能做了一系列实验研究&#xff0c;发现了一个有趣的“Lost in the middle”现象&#x…

我与C++的爱恋:隐式类型转换

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 朋友们大家好&#xff0c;本篇内容我们来介绍初始化列表&#xff0c;隐式类型转换以及explicit的内容 一、初始化列表 1.1 构造函数体赋值 在创建对象时&#xff0c;编译器…

【笔试强训】Day3 --- 简写单词 + dd爱框框 + 除2!

文章目录 1. 简写单词2. dd爱框框3. 除2&#xff01; 1. 简写单词 【链接】&#xff1a;简写单词 解题思路&#xff1a;简单模拟题&#xff0c;主要是处理⼀下输⼊的问题。&#xff08;也可以利用string类中的find函数&#xff0c;但时间复杂度会偏高&#xff09; #include …

一套全院级PACS系统源码,实现影像检查的电子预约申请、电子诊断报告、 临床科室设立影像浏览终端等功能

一套全院级PACS系统源码&#xff0c;实现影像检查的电子预约申请、电子诊断报告、 临床科室设立影像浏览终端等功能 一套全院级PACS系统源码&#xff0c;包括放射、CT、超声、内镜、病理等科室影像及信息管理系统的建设&#xff0c;解决医学影像的采集、诊断、传输、存储&#…

电感与磁珠

电感是什么&#xff1f; 电感会通过产生感应电动势的方式来阻碍电流的变化&#xff0c;电流变化率越大&#xff0c;产生的感应电动势越大阻碍电流效果越明显。 [一]品质因数Q: 电感的品质因数Q值定义&#xff1a;电感的Q值也叫作品质因数&#xff0c;其为无功功率除以有功功率…

永恒之蓝复现

目录 一、原理 二、实验环境 三、实验步骤 \1. 查询ip \2. 测试两台主机的连通性 \3. 查询指kali数据库的状态 \4. 此时就可以进行永恒之蓝漏洞扫描&#xff0c;&#xff08;永恒之蓝利用的是ms17_010漏洞&#xff0c;因此到这一步之后的任务就是在kali 里寻找ms17_010漏…

比特币减半倒计时:NFT 生态将受到怎样的影响?

BTC 减半倒计时仅剩不到 1 天&#xff0c;预计在 4 月 20 日迎来减半。当前区块奖励为 6.25 BTC&#xff0c;减半后区块奖励为 3.125 BTC&#xff0c;剩余区块为 253。比特币减半无疑是比特币发展史上最重要的事件之一&#xff0c;每当这一事件临近&#xff0c;整个加密社区都充…

从零开始搭建网站(第二天)

今天把之前的htmlcssjs项目迁移过来&#xff0c;直接使用tspiniavue3vite组合&#xff0c;搭建过程可以看从零开始搭建性能完备的网站-思路过程&#xff08;1&#xff09;_自己架设一个芯参数网站-CSDN博客。之后安装一下volar扩展。迁移过来使用Vue重构时发现之前使用的左右两…

《深入浅出多模态》: 多模态经典模型:BLIP

🎉AI学习星球推荐: GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料,配有全面而有深度的专栏内容,包括不限于 前沿论文解读、资料共享、行业最新动态以、实践教程、求职…

计算机网络——GBN协议实现

实验目的 编程模拟实现GBN可靠传输软件 实验内容 C 程序模拟实现Go-Back-N可靠数据传输&#xff0c;需要编写一个发送端程序和一个测试端程序来模拟传输过程 具体流程 1. 编写发送端程序&#xff0c;调用库实现socket连接&#xff0c;然后主要实现滑动窗口&#xff0c;接收…
最新文章