c++初阶——类和对象(下)

大家好,我是小锋,今天我们来学习我们类和对象的最后一个章节,我们本期的内容主要是类和对象的一些细节进行讲解

再谈构造函数

我们在初始化时有两种方式一种是函数体内初始化,一种是初始化列表

我们先来看看日期类的初始化

构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

简单来说初始化列表是每个成员定义的地方,这个时候大家要问了,这个初始化列表有什么用?

那让我们来看看

1,const 成员变量

我们正常写在函数体中是不是就行不通过了,这是因为const 成员变量在定义时就必须初始化

我们用初始化列表就可以了

2,引用的成员变量

还是使用初始化列表就可解决

3,自定义类型成员初始化 (该类没有默认构造函数)

注意: 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

接下来我们来看看初始化列表的一些细节

我们来从代码中来分析

我们对上面的代码进行调试我们可以发现在初始化列表,我们并没有写_day的定义,编译器会自动定义并且赋随机值,

其实,初始化列表是成员变量定义的地方,而我们在类中写的成员变量是在声明,不管我们写不写初始化列表,成员变量都会先在初始化列表先定义,内置类型就赋随机值,自定义类型就调用默认的构造函数,进行赋值。

当我们给了显示值,在初始化是就用显示值初始化,没有就用缺省值初始化。

初始化列表初始化的顺序是,变量声明的顺序。

总结

1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2. 类中包含以下成员,必须放在初始化列表位置进行初始化:

引用成员变量

const成员变量

自定义类型成员(该类没有默认构造函数)

3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。

4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

explicit关键字

我们先来看下面的一段代码

可能有些同学会不信我们可以来验证一下(因为编译器优化,所以要想看见过程可以使用比较老的编译器),我们这里从另一个角度去分析

如果我们不想发生隐式类型转换,可以用explicit关键字去修饰构造函数

像这样

这样就禁用了隐式类型转换

在c++11中加入了多参数的隐式类型转换

static成员

引出

问大家一个问题,我们怎么知道我们构造了多少个对象,又怎么知道有多少个对象正在被使用

对于这个问题我们很自然的想到一个解决方法,定义两个全局变量来记录构造和销毁的对象

如下,

思路就是这样的,但是我们知道c++对比c语言的地方是c++面向对象所以的功能都封装起来,这样用全局变量,有问题,每个人都可以更改。那我们怎么解决这个问题呢?

这里就要用到我们的static成员了

概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态的成员变量一定要在类外进行初始化

我们来看看怎么使用

这里为什么会报错啊?这里其实跟命名空间域类似,静态成员变量属于类域编译器是不会直接访问域中的数据,但是我们可以用一些突破类域的方法去访问

大家看这样是不是就可以访问到域中的数据了?

当然这里我们是令它为公有的才可以访问,

我们注意到为什么我们这里用空指针也可以访问到m和n,这么说m和n并没有存储在类中?

我们验证一下

这么看是不是说明m和n并没有存储在类中,其实m和n是属于静态变量存储在静态区中

那如果我们不是公有的,而是私有应该这么访问m和n,

这里我们可以创建函数来访问,或者通过函数来获取m和n的值。

我们还可以用静态成员函数来访问

它的特点是没有this指针,所以无法访问对象的成员变量,我们来验证一下

大家看是不是无法访问??

我们接下来看看静态成员变量的特性

特性

1. 静态成员为所有类对象所共享,不属于某个具体的实例

2. 静态成员变量必须在类外定义,定义时不添加static关键字

3. 类静态成员即可用类名::静态成员或者对象.静态成员来访问

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

5. 静态成员和类的普通成员一样,也有public、protected、private3种访问级别,也可以具有返回值

6,静态成员函数不可以调用非静态成员函数,非静态成员函数可以调用类的静态成员函数

友元

友元分为:友元函数和友元类

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

友元函数

我们来看下面这段代码

这里<<和>>为什么支持内置类型不支持自定义类型?

我们大家来看

这里支持内置类型不是直接支持而是对每个内置类型都进行了函数重载,以及运算符重载

大家看所以的内置类型都可以通过<<输出并且自动识别类型,本质是函数重载

那我们是不是也可以写一个函数来实现输出自定义类型的流插入

大家看为什么还是不行?

首先我们来分析<<这个是应该有两操作数并且位置应该对应,我们知道成员变量在调用成员函数是会隐藏地传一个this指针过去,这是this指针在右out在左是不是顺序不对啊,我们调换过来就行了

虽然可行但是,这样使用与我们平常的使用习惯不符,所以我们一个把他的位置调换,但是在类中this指针默认是在第一个,所以我们一个把函数定义在全局中。

这里我们又会遇到一个新的问题,我们定义在全局,无法访问到类的成员变量了。

这个时候我们友元函数就派上用场了。(不是只能用友元,只是一个例子)

这里的frend是一种声明,说明该函数可以访问类中的成员变量。

那接下来我们把>>也一起实现

说明:

友元函数可访问类的私有和保护成员,但不是类的成员函数

友元函数不能用const修饰

友元函数可以在类定义的任何地方声明,不受类访问限定符限制

一个函数可以是多个类的友元函数

友元函数的调用与普通函数的调用和原理相同

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

友元关系是单向的,不具有交换性。

比如Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

友元关系不能传递

如果B是A的友元,C是B的友元,则不能说明C时A的友元。

注意,友元尽量不用

内部类

概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。

注意:此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

特性:

1. 内部类可以定义在外部类的public、protected、private都是可以的。

2. 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。

3. sizeof(外部类)=外部类,和内部类没有任何关系。

我们来一步一步验证

大家看B是A的内部类,只受A域,以及访问限定符的限制,A,B是两个独立的类

大家看在定义时受到了A域的限制

大家看这里我们可以看出B类默认时A类的友元类。

匿名对象

就是没有名字的对象,我们来看一下它的定义

从上面的代码中我们可以看到匿名对象与有名对象定义的不同

并且匿名对象的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数

那又同学可能要问了,匿名对象有什么用呢?

我们来想一个场景当我们只简单的需要调用类的一个成员函数时,我们就可以直接定义匿名对象直接调用。

我们只是简单调用,不需要定义一个有名对象。

注意:匿名对象,临时对象具有常性。

const可以延长匿名对象的声明周期

当A类型的引用出了作用域后A的匿名对象才调用析构函数。

   以上就是全部内容了,如果有错误或者不足的地方欢迎大家给予建议。 

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

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

相关文章

[机缘参悟-166] :周期论:万物的周期现象是这个世界有序性和稳定性保障;超越周期:在轮回中,把握周期节奏。

目录 前言&#xff1a;超越周期 一、周期是大自然和宇宙的规律&#xff0c;是天道 1.1 概述 1.2 万物的周期规律的现象 1.3 电磁波的周期 二、计算机世界中的周期性 三、佛家的生命轮回规律 四、人类社会发展的周期规律 五、经济活动的周期规律 5.1 概述 5.2 股市的…

Ieetcode——21.合并两个有序链表

21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 合并两个有序链表我们的思路是创建一个新链表&#xff0c;然后遍历已知的两个有序链表&#xff0c;并比较其节点的val值&#xff0c;将小的尾插到新链表中&#xff0c;然后继续遍历&#xff0c;直到将该两个链表…

C语言实验-函数与模块化程序设计

一&#xff1a; 编写函数fun&#xff0c;其功能是&#xff1a;输入一个正整数&#xff0c;将其每一位上为偶数的数取出重新构成一个新数并输出。主函数负责输入输出&#xff0c;如输入87653142&#xff0c;则输出8642。&#xff08;main函数->fun函数&#xff09; #define _…

【代码问题】【Pytorch】训练模型时Loss为NaN或INF

解决方法或者问题排查&#xff1a; 加归一化层&#xff1a; 我的问题是我新增的一个模块与原来的模块得到的张量相加&#xff0c;原张量是归一化后的&#xff0c;我的没有&#xff1a; class Module(nn.Module):def __init__(self,dim,):super().__init__()# 新增一个LayerNo…

节假日如何快速回应客户消息?

在宝贵的休闲时光或者特殊的节日期间&#xff0c;有时候由于工作、家庭等原因&#xff0c;我们很难及时回应客户的消息。那么如何在忙碌之时&#xff0c;如何确保与他人的交流畅通无阻呢&#xff1f;答案就是使用微信私域流量管理系统。 01 机器人自动回复设置 机器人自动回…

酷我音乐车机版+v6.0.1.0车机共存会员版【附带安装包下载地址】

简介 很多车机的酷我音乐app有限制&#xff0c;不能完全使用酷我音乐的所有功能。我这里分享一个可以使用全部功能的酷我音乐app&#xff0c;大家可以自行下载。 界面预览 软件下载地址【转存到自己的网盘后即可下载】 网盘地址&#xff1a;https://pan.xunlei.com/s/VNwgzNV…

Redis的事务机制能保证ACID属性吗?

目录 事务 ACID 属性 用户如何开启Redis的事务&#xff1f; 使用redis-cli客户端来展示 ​Go语言编码使用事务 Redis 的事务机制能保证哪些属性&#xff1f; 1. 原子性 语法错误 运行错误 执行EXEC时&#xff0c;Redis发生故障 Redis对事务原子性属性的保证情况 2. 一…

idm下载速度慢解决办法 idm批量下载怎么用 idm优化下载速度 Internet Download Manager解决下载速度慢的方法教程

IDM (Internet Download Manager)是一款兼容性大&#xff0c;支持多种语言的下载管理软件&#xff0c;它可以自动检测并下载网页上的内容&#xff0c;这正是这一优点&#xff0c;使得它受到了广大用户的喜爱。但是在下载的过程中&#xff0c;我们会遇到idm下载速度慢怎么回事&a…

深度学习系列66:试穿模型IDM-VTON上手

1. 模型概述 如图&#xff0c;总体流程为&#xff1a; 输入为&#xff1a;衣服的编码xg&#xff1b;人物noise的编码xt&#xff1b;人物身上衣物的mask和人体pose分割(densepose)&#xff1b;衣服部分经过两部分网络&#xff1a;1&#xff09;高级语义网络IP-Adapter&#xff…

假设检验随想

⭐️ 前言 你会吵架吗&#xff1f;你会用数学吵架吗&#xff0c;不会的话就过来看看吧&#xff0c;哈哈 西方人发明了现代意义上的概率论&#xff0c;于是就想把它推广到生产和生活中。借助一大堆的概率论中的概念&#xff0c;他们发明了假设检验&#xff0c;想利用有限的数据…

Cloudflare高级防御规则 看看我的网站如何用防御的

网站已趋于稳定&#xff0c;并且经过nginx调优。我想先分享一下Cloudflare的WAF规则&#xff0c;因为这是最有效的防御之一&#xff0c;可以抵御大量恶意攻击流量&#xff0c;我已经验证了数月。 对于海外独立站电商网站&#xff0c;Cloudflare的CDN服务是首选&#xff0c;它强…

基于SpringBoot的“在线BLOG网”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“在线BLOG网”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 在线BLOG网结构功能图 管理员登录功能界面 用户信息…

自动驾驶 | 仿真测试-HiL测试全解析

1.HiL 的定义 HiL&#xff08;Hardware-in-the-Loop&#xff09;硬件在环是计算机专业术语&#xff0c;也即是硬件在回路。通过使用 “硬件在环”(HiL) &#xff0c;可以显著降低开发时间和成本。在过去&#xff0c;开发电气机械元件或系统时,使用计算机仿真和实际的实验就已经…

大长案例 - 通用的三方接口调用方案设计

文章目录 引言身份验证防止重复提交数据完整性和加密回调地址安全事件响应可用性 设计方案概述1. API密钥生成2. 接口鉴权3. 回调地址设置4. 接口API设计 权限划分权限划分概述1. 应用ID&#xff08;AppID&#xff09;2. 应用公钥&#xff08;AppKey&#xff09;【&#xff08;…

蒸发式工业冷风机

工业冷风机是一种专为工业环境设计的降温设备&#xff0c;它通过水蒸发吸热的原理来降低环境温度。以下是关于工业冷风机降温的一些详细信息&#xff1a; 降温原理&#xff1a; 工业冷风机&#xff08;也称为蒸发式冷风机或蒸发式冷却机&#xff09;利用“水蒸发吸收热量”的物…

Linux基础——Linux开发工具(上)vim

前言&#xff1a;在了解完Linux基本指令和Linux权限后&#xff0c;我们有了足够了能力来学习后面的内容&#xff0c;但是在真正进入Linux之前&#xff0c;我们还得要学会使用Linux中的几个开发工具。而我们主要介绍的是以下几个&#xff1a; yum, vim, gcc / g, gdb, make / ma…

pyqt拖入图片并显示

pyqt拖入图片并显示 介绍效果代码 介绍 像拖入文本一样&#xff0c;把图片拖入到窗体中显示。 效果 代码 import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout from PyQt5.QtGui import QPixmap, QDragEnterEvent, QDropEvent from PyQt5.Q…

嵌入式C语言教程:使用DMA控制的UART通信

在许多嵌入式系统中&#xff0c;UART&#xff08;通用异步接收/发送&#xff09;是一种常见的通信协议&#xff0c;用于低速串行数据传输。 通过DMA&#xff08;直接内存访问&#xff09;控制UART通信&#xff0c;可以有效地释放CPU资源&#xff0c;使其能够处理其他计算任务。…

一种基于YOLOv8改进的高精度红外小目标检测算法 (原创自研)

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;一种基于YOLOv8改进的高精度小目标检测算法&#xff0c; 在红外小目标检测任务中实现暴力涨点&#xff1b; &#x1f4a1;&#x1f4a1;&#x1f4a1;创新点&#xff1a; 1&#xff09;SPD-Conv特别是在处理低分…

安防监控/智能分析EasyCVR视频汇聚平台海康/大华/宇视摄像头国标语音GB28181语音对讲配置流程

一、背景分析 近年来&#xff0c;国内视频监控应用发展迅猛&#xff0c;系统接入规模不断扩大&#xff0c;涌现了大量平台提供商&#xff0c;平台提供商的接入协议各不相同&#xff0c;终端制造商需要给每款终端维护提供各种不同平台的软件版本&#xff0c;造成了极大的资源浪…