【C++笔记】C++之类与对象(上)

news2025/1/23 3:24:36

【C++笔记】C++之类与对象(上)

  • 1、类是结构体的升级
  • 2、类中可以定义的东西
  • 3、类访问限定符
  • 4、类的声明
  • 5、类的实例化(定义)
  • 6、类的大小的计算
  • 7、this指针

1、类是结构体的升级

C++的一个显著特征就是兼容C语言,所以C++把结构体“升级”成了“类”,之所以是“升级”是因为,在C++中的结构体及支持以前C语言的结构体的玩法,也可以支持C++中类的玩法。
例如单链表节点这个类,我们既可以写成纯C版本:
在这里插入图片描述
用纯C的写法,我们每次要定义一个节点变量的时候,都必须要加上一个前缀struct,非常的麻烦。
而且就算是我们用了typedef,在结构体内部也还是不能直接用typedef后的符号,因为在结构体内部typedef还没有起作用:
在这里插入图片描述

非常麻烦!
但在C++中,我们就不必要担心这些情况,因为在C++中,结构体也被当成了类,而类是直接可以类名来定义变量的:
在这里插入图片描述
不管类内部还是外部,我们都可以直接使用类名来定义变量。

2、类中可以定义的东西

既然类是结构体的“升级”,那么内在结构体中定义的东西也一定能在类中定义,所以类中能定义的包括:
各种变量:
在这里插入图片描述
数组:
在这里插入图片描述
还有枚举和结构体等等:
在这里插入图片描述
几乎可以定义所有的东西:

但C++的类除了可以定义以上这些东西之外,还一个定义一个类独有的东西:“成员函数”,
有了成员函数,我们在管理结构体中的各个成员的时候就可以更方便,而不需要每写一个函数就需要传参。
例如栈这个类的初始化:
在这里插入图片描述
这是因为类划分了一个“类域”,在成员函数被调用的时候,就回到类中去寻找各个变量,这就不需要我们老是传递参数了。
而且使用起来也很简单,就像以前结构体访问成员变量一样:
在这里插入图片描述
而这个“public”是一个类访问限定符。

3、类访问限定符

在一个类中,我们总有些东西是不想被外面访问到的,也总有一些东西是想要对外开放的,这时候就需要访问限定符来管理了。
访问限定符一共有三个:

public(公有)
protected(保护)
private(私有)

第一个public表示公开,由这个访问限定符修饰的成员不管是在类内部还是外部,都可以自由访问:
在这里插入图片描述
而第二个protected,我们现在暂且认为它和public是一样的,因为这个访问限定符实在以后的类的继承中才能显现出区别的。
第三个private表示私有,被这个访问限定符所修饰的成员就只能在类里边访问,而在类外边是访问不到的:
在这里插入图片描述

而要是我们不显示的添加访问限定符,在类和结构体中也是有默认的访问限定符的。
其中,类的默认访问限定符是private:
在这里插入图片描述
而结构体的默认访问限定符是public:
在这里插入图片描述

4、类的声明

大家是否有过一个疑问?就是我们平时写的这样一个类:
在这里插入图片描述
它到底是声明还是定义呢?
首先我们要明确声明和定义的区别,声明只是告诉编译器,有这么一个函数或变量存在,而定义则是为这个函数或变量开辟空间。
所以我们就可以想接下来这样来验证上面所写的到底是声明还是定义:
在这里插入图片描述
我们发现用域作用限定符是访问不到成员的,这就说明编译器并没有为这个类开辟空间。所以编译器找不到这个成员的地址。

5、类的实例化(定义)

有声明就得有定义,其实我们平时创建的一个类对象就是一个类的定义,也称为类的实例化:
在这里插入图片描述

这样,编译器才会真正开辟空间。

6、类的大小的计算

其实类的大小计算遵循着结构体内存对齐的规则,例如下面这两个类和结构体:
在这里插入图片描述
从结果就可以看出类大小的计算也是遵循着结构体内存对齐的那套规则的。
同时不管我们是使用类名来计算的小还是使用类对象来计算大小,都是可以准确算出一个类的大小的:
在这里插入图片描述

这是因为就算我们没有实例化类对象,但通过类名我们还是可以找到类的声明,类的生命虽然没有开辟空间,但也相当有了一张“图纸”,我们可以通过这张“图纸”来计算出类的大小。

但是有一点是不一样的,就是当类中存在成员函数的时候:
在这里插入图片描述

我们发现,就算类中添加了成员函数,类的大小还是没有发生改变,这是为什么呢?
其实这是一种节约资源的做法,我们不妨先想一想,我们平时定义的各个类对象,他们的成员变量是否是相同的变量?
在这里插入图片描述
答案显然不是的。
但它们所调用的函数是不是同一个呢?
答案是是的,因为函数的逻辑都是一样的,而各个对象的成员变量的值是可能各不相同的,不相同的只当然不能共用同一个变量了,但是相同的逻辑就只需要一段相同的指令就行了。
所以,类中就没有必要存储成员函数了。类中的成员函数其实是放在代码段中的。

但要是,我有一个“空类”,也就是类中没有成员变量也没有成员函数,那这个类的大小又该是多少呢?
我们可以来验证一下:
在这里插入图片描述
我们可以看到,空类的大小是1字节。
其实这一字节的作用只是用来占位而已,只是表示这个类存在过。

7、this指针

经过前面的叙述,我们已经知道成员函数并不存储在类中。那么问题来了,既然不存储在类中,那么在调用的时候就必定需要传参啊,那为什么在写成员函数的时候不需要传递成员变量呢?

其实,所谓的“不用传参”只是表面现象而已,其实只是把传递对象的工作交给了编译器来做而已。
事实上,我们平时写的成员函数还有一个隐藏的参数:“this”指针,这个指针是一个类对象的指针,也就是调用函数的对象的指针:
例如下面这个函数,编译器会在底层将它处理成这样的一个函数:
在这里插入图片描述
但这是规定给编译器做的工作,也就是说我们不能和编译器“抢工作”,不能显示的将this指针,写在参数列表中。

但我们却可以在类当中使用它,例如上面的这个函数也可以这样写:
在这里插入图片描述
但是像这种单纯访问成员变量的情况,我们一般都不会显示的将this写出来,因为编译器自己会自动补上,何必自己给自己找麻烦呢?

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

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

相关文章

高等数学 | 微分方程解决单中值问题、高阶导数的莱布尼兹公式

单中值问题都可以用通过求解微分方程的特解构造辅助函数,再用罗尔定理即可。 高阶导数的莱布尼兹公式推导以及应用,先求导至能够发现某次求导开始为0的时候,对其使用莱布尼兹公式。

Photoshop制作漂亮光泽感3D按钮

原文链接(https://img-blog.csdnimg.cn/45472c07f29944458570b59fe1f9a0e0.png)

简单记录牛客top101算法题(初级题C语言实现)BM24 二叉树的中序遍历 BM28 二叉树的最大深度 BM29 二叉树中和为某一值的路径

1. BM24 二叉树的中序/后续遍历 要求:给定一个二叉树的根节点root,返回它的中序遍历结果。                          输入:{1,2,#,#,3} 返回值:[2,3,1]1.1 自己的整体思路(与二叉树的前序遍…

HCIP——BGP协议

目录 一.什么是BGP? 二.IGP和EGP 三.BGP的特点 四.BGP的数据包 五.BGP的工作过程 BGP的六种状态机 六.BGP的路由黑洞问题 七.BGP的防环机制——水平分割 八.BGP的宣告问题 九.BGP的自动汇总 十.BGP的安全特性 十一.BGP的选路规则 一.什么是BGP? 1.…

ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) 二、CVE-2018-19440 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) Title 不保存x0~x3寄存器可能会将信息从一个非安全世界的SMC client泄漏到另一个 CVE ID …

学习ts(二)数据类型(接口和对象类型、数组类型)

interface 重名会重合到一起 如果两个interface名称相同,会把两个合到一起 重复定义同一个需要类型相同 不能多或者减少属性 设置任意key 当定义接口返回数据时,我们不确定接口会返回多少,知道所需要的固定属性,其余属性可以…

第九章 动态规划part08(代码随想录)

139.单词拆分 1. 确定dp[i][j] dp数组以及下标的含义一维dp数组的递推公式 dp[i] : 字符串长度为i的话,dp[i]为true,表示可以单词能被在字典中出现的单词组成。 dp[s.size()] true; 说明可以利用字典中出现的单词拼接出 s 。 2. 一维dp数组的递推公式…

【STM32 学习】电源解析(VCC、VDD、VREF+、VBAT)

VCC电源电压GND电源供电负电压(通常接地)VDD模块工作正电压VSS模块工作负电压VREFADC参考正电压VREF-ADC参考负电压VBAT电池或其他电源供电VDDA模拟供电正电压VSSA模拟供电负电压 一、VCC(供电电压) VCC是指芯片的电源电压&#…

linux安装mysql-8.0.33正确方式及常见问题

目录 获取mysql下载地址链接 解压安装包 复制文件到安装目录 添加用户和用户属组修改权限 创建存储数据的文件夹/usr/local/mysql 初始化安装 修改配置文件 创建日志文件并赋予对应权限 启动成功​编辑 创建软链接 之前安装过mysql,时间比较长忘记安装步骤了今天…

【C语言】memset()函数

一.memset()函数简介 我们先来看一下cplusplus.com - The C Resources Network网站上memset()函数的基本信息: 1.函数功能 memset()函数的功能是:将一块内存空间的每个字节都设置为指定的值。 这个函数通常用于初始化一个内存空间,或者清空一个内存空间…

HCIP第五节------------------------------------------ospf

一、OSPF基础 1、动态路由分类 2、距离矢量协议 运行距离矢量路由协议的路由器周期性地泛洪自己的路由表。通过路由的交互,每台路由器都从相邻的路由器学习到路由,并且加载进自己的路由表中,然后再通告给其他相邻路由器。 对于网络中的所有…

服务器数据恢复-EqualLogic存储RAID5数据恢复案例

服务器数据恢复环境: 一台DELL EqualLogic存储中有一组由16块SAS硬盘组建的RAID5阵列。存储存放虚拟机文件,采用VMFS文件系统,划分了4个lun。 服务器故障&检测&分析: 存储设备上有两个硬盘指示灯显示黄色,存储…

使用python读Excel文件并写入另一个xls模版

效果如下: 原文件内容 转化后的内容 大致代码如下: 1. load_it.py #!/usr/bin/env python import re from datetime import datetime from io import BytesIO from pathlib import Path from typing import List, Unionfrom fastapi import HTTPExcep…

炬芯科技发布全新第二代智能手表芯片,引领腕上新趋势!

2023年7月,炬芯科技宣布全新第二代智能手表芯片正式发布。自2021年底炬芯科技推出第一代的智能手表芯片开始便快速获得了市场广泛认可和品牌客户的普遍好评。随着技术的不断创新和突破,为了更加精准地满足市场多元化的变幻和用户日益增长的体验需求&…

二.net core 自动化发布到docker (Jenkins安装之后向导)

目录 ​​​​​​​​​​​​​​ 参考资料:https://www.jenkins.io/doc/book/installing/docker/#setup-wizard Post-installation setup wizard.(安装后安装向导) 基于上一篇文章安装,在安装并运行Jenkins(不包括使用Jenkins Opera…

数据结构-单链表(C语言简单实现)

简介 以顺序结构进行数据存储时,它的特点就是可以用一组任意的存储单元存储数据元素,这组存储单元可以是连续的,也可以是不连续的,这些数据可以存在内存未被占用的任意位置。它也是有缺点的,就是在插入和删除时需要移…

SpringBoot、Java 使用 Jsoup 解析 HTML 页面

使用 Jsoup 解析 HTML 页面 什么是 Jsoup? Jsoup 是一个用于处理 HTML 页面的 Java 库,它提供了简单的 API,使得从 HTML 中提取数据变得非常容易。无论是获取特定标签的内容还是遍历整个页面的元素,Jsoup 都能轻松胜任。 如何使…

CI/CD流水线实战

不知道为什么,现在什么技术都想学,因为我觉得我遇到了技术的壁垒,大的项目接触不到,做的项目一个字辣*。所以,整个人心浮气躁,我已经得通过每天的骑行和长跑缓解这种浮躁了。一个周末,我再次宅在…

echarts图表的应用

1、echarts的简介 echarts 是国内的一个图表应用插件,只需要下载echarts的js 在js中引入。 echarts 的官网:https://echarts.apache.org/zh/index.html 进去之后点击这里, 点击下载按钮,下载文件,下载后解压&#xf…

如何卖 Click to WhatsApp 广告最有效

2022年,大多数直接面向消费者的品牌都面临相同挑战—— Facebook 和 Instagram 的广告成本大幅增加。Business Insider 报导指出,2021年 Facebook 广告每次点击的平均成本(average cost per click)达到0.974美元,按年升…