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

news2024/10/7 13:17:09

本篇主要介绍了类的引入及其定义、类的访问限定符及封装、类的作用域和实例化、类的对象大小计算等内容。初心是为了让读者能够理解并熟悉类与对象的相关内容。

一、类的引入

类,就是类型。它是c++中的一个概念,是把c中的结构体进行了升级同时有兼容c中结构体的用法,一个类进行实例化会有n个对象,很像c中的结构体里面包含的各种类型的变量(对象)。具体怎么升级呢?以前的结构体是里面可以存放数据,升级后不仅可以存放数据,也可以存放函数,不需要传参。比如我们之前所了解的栈或队列,它们的初始化函数都是先创立一个结构体,然后在其外面创立一个初始化函数然后把结构体指针作为参数传进函数实现初始化。而升级了以后,初始化函数就可以直接卸载里面,且不需要传参(这时候就可以考虑缺省参数的应用了,用于更合适的开辟空间大小)。

此外,升级后,结构体的名称就可以代表该类型(省去了typedef,且结构体内的也可以做这种省略操作)。

但我们实际发现,c++更多的用class定义类。怎么用呢?只要把struct换成class即可。4

二、访问限定符

我们假设创建一个类stack并创建一个初始化函数,并去创建一个变量并把它初始化

结果运行时报出不可访问的错误,为什么不可访问呢? 

c++在进行类的封装时,用类将对象的属性与方法结合一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

访问限定符分三种:public(公有)、protected(保护)、private(私有)。

公有修饰的成员在类外面可以直接被访问,在上图中显然不可直接访问,因此不是public,保护和私有只能在类里面访问。class默认是私有,struct默认是公有,因此才会报错。想让其公有,只需在前面加public修饰即可。

这个public的范围是从他开始到下一个访问限定符,如果没有遇到访问限定符就一直管到结束。通常情况下,成员变量设为私有,函数设为公有。

三、类中成员函数的声明和定义分离

我们还是以创建一个栈为例:

这是之前我们所创建的一个类以及它的初始化函数,但是在实际中,我们往往会将声明和定义放在不同位置(.h放分离.cpp放定义),这就需要一些要求,因为一旦声明和定义分离,定义就在类的外,就无法直接访问这个成员函数(class默认的类都是private)所以我们按之前的套路来定义函数是行不通的,需要加一些改进。(此时有人会说,把那些函数设置为public类型的,但是,如果我在这个程序中再创建一个队列,也创建一个同名的初始化函数,那么就会出现重名的问题,但并不冲突)

方法,在函数的定义处指定我的类域(有点像前面的域作用操作符)

四、封装

面向对象的三大特性:封装、继承、多态(不止三个特性)

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来 和对象进行交互。

封装本质上是一种管理,让用户更方便使用类。比如:对于电脑这样一个复杂的设备,提供给用 户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日 常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

五、类的实例化

概念:用类类型创建对象的过程

我们在创建栈的时候

定义了三个变量,而这三个变量此时并没有创建空间去存储,只有具体创建出类的变量才会创建空间

这便是类的实例化,类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象 才能实际存储数据,占用物理空间。

六、类的大小的计算

一个类中,有成员变量,也有成员函数,本质上这个类与c中的结构体对接,计算类的大小其实是运动到结构体内存对齐原理。直接上结论:一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐,成员函数不计入类的大小,而是单独拿出一块空间去存放,需要用的时候再调出来避免浪费空间。

如果一个类是空类呢?其大小又是多少呢?

运行结果我们发现a3的大小是1而不是0,这1个字节不存储有效数据,而是表明了标识对象被定义出来。因为成员函数不计入类的大小因此a2的大小也是1。

在这里补充一下结构体内存对齐规则:

1. 第一个成员在与结构体偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8

3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

七、this指针

我们先来看看他的实际场景,现在我们创建一个有关日期的类

前面我们提到,类中的函数并不算入类的大小,而是放在一个共同的空间,所以d1和d2的init函数是相同的,但运行的结果如下

按道理说,相同的函数相同的结果啊,怎么会这样,我们看main函数中的内容,或许会对init函数的传参产生怀疑,但其原理并不在这里,而是this指针的作用

在我们运行的过程中,编译器会把对象(d1d2)的地址传过去并用指针变量去接受,这个指针就是this指针(注释部分就是解释其原理)

这样我们就能理解为什么结果不同了(d1打印时候走的是d1的this,d2打印走的是d2的this)

this指针其实是隐含的this指针,我们的实参和形参的位置不能显示着写,编译器自己会加(如果运行注释版本会报错)但是可以在类里面用。this的指针是*const类型(无法修改this但可修改this的指向)

到目前为止我们发现,C++中通过类可以将数据以及操作数据的方法进行完美结合,通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。 而且每个方法不需要传递参数了,编译器编译之后该参数会自动还原,即C++中参数是编译器维护的,C语言中需用用户自己维护。

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

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

相关文章

基于springboot的社区医疗服务系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

Web题记

反序列化补充知识: private变量会被序列化为:\x00类名\x00变量名 protected变量会被序列化为: \x00\*\x00变量名 public变量会被序列化为:变量名web254 这个逻辑不难,自己刚看的时候还奇怪是不是自己哪里想错了,因为…

【STM32】ST-LINK 下载时遇到的问题

如果出现“ST-Link USB communication error”ST-Link USB通信错误,则需要启动STM32 ST-LINK Utility,点击【ST-LINK】->【Firmaware】更新固件,然后打开Kei,点击魔术棒->->Debug->Settings,开到出现类似“…

正确使用@Autowired

目录 一、前言二、跟着官方文档,学习正确使用Autowired0、实验环境1、通过构造方法进行注入1.1 问题1:那万一没有这个CustomerPreferenceDao对象,会报错吗? 2、通过setter方法注入3、通过方法注入(这个方法可以是任意名…

蓝桥杯每日一题:斐波那契(矩阵乘法)

在斐波那契数列中,Fib00,Fib11,FibnFibn−1Fibn−2(n>1) 给定整数 n,求 Fibnmod10000。 输入格式 输入包含不超过 100100 组测试用例。 每个测试用例占一行,包含一个整数 当输入用例 n−1时,表示输入终止,且该…

实现Hello Qt 程序

🐌博主主页:🐌​倔强的大蜗牛🐌​ 📚专栏分类:QT❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、使用 "按钮" 实现 1、纯代码方式实现 2、可视化操作实现 (1&#xff09…

【Easy云盘 | 第三篇】登录注册模块上篇(获取验证码、发送邮箱验证码、登录、注册、重置密码)基于AOP实现参数校验

文章目录 4.2登录注册模块设计4.2.1获取验证码(1)思路(2)接口(3)controller层(4)CreateImageCodeUtils工具类(5)测试结果 4.2.2发送邮箱验证码(1&…

C++初阶---vector(STL)

1、vector的介绍和使用 1.1、vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是…

Pagerank学习笔记

前言 通过b站视频学习以及网上资料整理后进行学习笔记的撰写,只包含pr的一些简单原理及其应用。不包括pr的自定义实现。 一、pagerank简介 背景简介 PageRank算法 由Google创始人Larry Page 在斯坦福读大学时提出,又称PR,佩奇排名。主要针对网页进行…

Docker容器(五)Docker Compose

一、概述 1.1介绍 Docker Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,…

bootstrap+thymeleaf 页面多选回显时莫名其妙多了

bootstrapthymeleaf 页面多选回显时莫名其妙多了 问题现象问题分析问题处理总结 问题现象 今天遇到的问题的描述正如标题中的一样,就是后台管理系统在配置完内容后点击保存,回显时发现页面竟然莫名其妙多了一些数据。项目整体后台管理系统采用的是boots…

分类预测 | Matlab实现DRN深度残差网络数据分类预测

分类预测 | Matlab实现DRN深度残差网络数据分类预测 目录 分类预测 | Matlab实现DRN深度残差网络数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现DRN深度残差网络数据分类预测(完整源码和数据),运行环境为Matl…

usb_camera传输视频流编码的问题记录!

前言: 大家好,今天给大家分享的内容是,一个vip课程付费的朋友,在学习过程中遇到了一个usb采集的视频数据流,经过ffmpeg编码,出现了问题: 问题分析: 其实这个问题不难,关键…

wordpress子比主题打开文章详情页一直出现在首页的问题

遇到过几次这种情况了,不知是不是中了木马,无从下手,试了很多方法都不行快要疯了,之前试过解决不了只能重新安装,现在又出现了,第二次了,太麻烦了,突然无意中打开index.php文件发现被…

Android与RN远程过程调用的原理

Android与RN远程过程调用的原理是通过通信协议进行远程过程调用。RPC(Remote Procedure Call)是分布式系统常见的一种通信方式,从跨进程到跨物理机已经有几十年历史。 在React Native中,通信机制是一个C实现的桥,打通了Java和JS,实现了两者的…

数据被halo勒索病毒锁定?这里有恢复秘笈!

在当今数字化的社会,数据的重要性不言而喻。然而,随着网络技术的发展,数据安全问题也日益凸显。近年来,勒索病毒成为网络安全的一大威胁,其中halo勒索病毒更是让人闻风丧胆。一旦数据被这种病毒锁定,用户将…

42. 接雨水(Java)

目录 题目描述:输入:输出:代码实现: 题目描述: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 输入: height [0,1,0,2,1,0,1,3,2,1,2,1]输出&#xff1…

SpringCloud学习(11)-SpringCloudAlibaba-Nacos数据模型

一、Nacos数据模型 1.1、数据模型 对于Nacos配置管理,通过Namespace、Group、Date ID能够定位到一个配置集。Nacos数据模型如下所示: 1.2、命名空间(Namespace) 可用于进行不同环境的配置隔离。例如: 1)、可以隔离开发环境——测试环境和…

数据可视化高级技术Echarts(快速上手柱状图进阶操作)

目录 1.Echarts的配置 2.程序的编码 3.柱状图的实现(入门实现) 相关属性介绍(进阶): 1.标记最大值/最小值 2.标记平均值 3.柱的宽度 4. 横向柱状图 5.colorBy series系列(需要构造多组数据才能实现…

基于java实现的二手车交易网站

开发语言:Java 框架:ssm 技术:JSP JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea…