c++入门----类与对象(上)

       大家好啊,好久没有更新了。因为本人的愚笨,想与大家分享的话肯定还得自己明白了才能给大家分享吧。所以这几天都在内部消化。好给大家优质的文章。当然我写的肯定还是很有问题的,希望大家可以在评论区里面指出来。好,废话不多说,我们买上来讲今天的主题。

类定义

         当然,如果前期没有预习过的话,看到这个主题可能会思考一下。类是什么东西。有什么用,怎么表示。这是我们没有预习过的疑问。我们来一一解答。

        类:是对某一类具有共同特征的事物的抽象描述。例如电脑类,具有键盘、屏幕、电源键等共同特征。但我感觉这样说也有点模糊。但大家可以向这方面想。并且类是一种用户自定义的引用数据类型,它的本质是数据类型,并不是数据,所以不存在于内存中,不能被直接操作,只有被实例化为对象时,才会变得可操作。但是如何实例化,我们后面是会讲的。

       好了,讲了这一些后。我们还是来讲讲实际的。类如何创建以及类成员是否有要求。对于类的创建的话,与我们以前的结构体是有相似之处的。大家先看一下下面的图片:

        首先我们只看我们看的懂的。我们在c++的第一篇博客中写过,最简答的打印代码吧。所以我们能看懂那个在空中台上打印实验的代码吧。然后就是在private下面的几个定义 。只是我们没有赋值嘛。只是大多数情况也只是定义一下。好了。除了上面这两个就是我们的主函数了。我们可以看到我们的第一个是不是像一个取别名呀。就是我们的上一篇博客中的那个别名。大家可以打个模糊眼觉得这样差不多。也可以想象成boss与下属的关系。毕竟不能每一件事情都要boss亲自出马吧。需要boss出马的时候肯定占少数。然后就是我们像以前c语言中的指针引用了。只是我们c语言还是用->,但是在c++里,只能这样使用。好了这些就是我们用以前的知识就能显而易见得知的知识了。

       接下来就是与我们以前c语言有点不一样的知识点了。我们知道c语言我们用的是struct来创建的。但是我们这里用的是class。但是其实这两个我们在c++里都可以使用,并且都是用来创建类的。那么都是创建类的话,肯定有区别,不然的话,为什么需要两个嘛。对于这两个的区别就是我们图片中的两个单词public和private。这两个单词和protected在c++中被称为访问限定符。这个知识点我们接下来是会讲到的。所以我们这里就不多讲。

        我们看到我们这里用class创建类与我们以前创建结构题的区别其实是不大的。都是关键字与名词然后加{}。并且在结尾的}后加上;。这些都是与我们以前的东西差不多的。然后就是我们类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。并且大家可以在我上面的图片看出,成员函数与成员变量还是很容易分析出来的吧。

        而且我们为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m 开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是struct中可以定义函数,⼀般情况下我们还是推荐⽤class定义类。因为我们刚从c转为c++有可能写着写着就将类转为结构体了。

       注:如果执意使用struct来写类的话。需要记住我们在类内部定义成员变量的时候不需要再使用typedef了。我们可以直接写然后定义了如下面:

       大家看到了吧,这里我们没有写typedef系统也没用爆红线出来。这就表明系统是支持这样的。这里大家需要注意一下,不要再像c语言那样还加一个typedef了。

        好了。在类定义这个小节里面我们讲了,如何创建类,类成员可以是哪些。和如何使用类。以及类与c语言中的结构体的一些差异。

访问限定符

        大家看到这里,就要来学习我们的第二个知识点了。访问限定符了。那么我们在前面稍微提及看一下访问限定符有那三个:public,private和protected。那么这三个词有什么用以及如何使用。是不是必须使用咧。这也是我们接下来要讨论的主题了。

         我们对于这三个单词的作用我们可以先来看着三个单词的意思:public是公开的,private是私有的,protected是保护的。大家先想一下。这些单词的意思加上上面的标题大家思考一下这些的作用是什么。是不是与我们那个全局变量和局部变量很像啊。当用public修饰的类成员的时候这些成员都是可以在外部访问的。那么private和protected就是相反的只能在类里面访问了。但是大家可能会问。protected和private意思不是不一样嘛。确实。这两个单词意思是不一样的。但是要讲具体的区别的话,我们这里才学这么一点,是讲不清楚和不能理解的,所以关于protected和private的具体区别我们在后面对c++的知识有更多的了解后在具体解释。我们现在就需要知道这两个单词的作用差不多就可以了。public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问

         那么访问限定符是不是在类里面必须使用啊。不用不行啊。当然不是啊。大家应该看到我上面的那张图片了吧。我创建的类也并没有写访问限定符啊。这就表明类不是一定需要访问限定符。依据使用情况使用。

         我们还在前面说过struct与class都是创建类的关键词。那么他们的区别是是吧。区别就是class定义成员没有被访问限定符修饰时默认为private,struct默认为public。我们以下面的这个图片为例子,我们在这个类里面使用的struct。并且我们并没有用访问限定符来修饰,所以关于这个类,在外部是可以被访问的。就是我们以前说的是全局变量,是可以随意使用的。但是如果我们使用的是class的话,那么这个就是局部变量,外部是不能使用的。只能在类内部使用才行。

        还有就是访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到 }即类结束。就是没有被修饰的地方就是我们关键词的作用域,如果被修饰了那么作用域至到下一个限定符。如果没有下一个限定符,就直接到末尾了。

        好,本小节我们讲了访问限定符的含义,使用,以及每个限定符的区别和作用域。

类域

       不知道大家在以前的时候是否有过那种。就是不想定义和生命在一起的,就想我们前面声明头文件那样,声明和定义分开。

        在c++中我们可以在类外面定义。什么意思咧。好比一个总部派了一个人在其他地方考察。如果可以直接在那里创建了一个分公司帮助总公司完成业务。但是我们创建子公司肯定要表明自己来自那个公司嘛。所以在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。那么具体如何实施。我们看看下面的图片:

        也就是简单的在主类里面声明。然后在自己想要的地方定义。只是我们需要确定好这个定义来自哪个类域。上⾯程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域Stack,就是知道Init是成员函数,当前域找不到的array等成员,就会到类域中去查找。

        好吧,这一小节就是向为大家展示,类可以将定义与声明分开,不用在类内部全部写完。可以在外部进行定义。

类实例化

        不知道大家对这个标题有没有什么见解。我们看题目大家或许有点了解吧。而且我们前面用过关于这个知识点的基础使用方法的。大家可以到上面看看我们说的那个boss的例子。⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。 类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。

        这个大家应该还是很好理解的如⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。打个⽐⽅:类实例化出对象就像现实中使⽤建筑设计图建造出房⼦,类就像是设计图,设计图规划了有多少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房⼦才能住⼈。同样类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。我们开始的类都是设计图。我们只有在使用的时候才会在编译的时候申请空间。我们简单的看一下下面的图片就能理解很多了:

        是不是与我们上面的例子很像啊。只是我们上面的例子只用实例出了一个。这里我们出了2个并且住了不同的人。 并且传的数据一般都是不一样的。不然的话,你实例出两个干什么啊。是吧。

       好,这个小节就是告诉我们在我们开始写类的时候只是在画图纸,并没有直接申请空间。只有当我们实例化编译的时候去申请空间。然后我们可以多个实例化。并且传入不同的参数。

类大小计算

       大家应该还没有忘记c中的结构体计算大小的规则吧。我们在前面说过c++的类包含了c中的struct,让struct升华成了类。那么结构体可以计算大小。我们类肯定也要有。所以我们现在来看看如何计算类的大小。

        首先分析⼀下类对象中哪些成员呢?类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量_year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。并且其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在运⾏时找,就需要存储函数地址,这个我们以后会讲解。我们现在再讲讲内存对齐的规则:

第⼀个成员在与结构体偏移量为0的地址处。
其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。
VS中默认的对⻬数为8
结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。
如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。
        是不是很熟悉啊。与我们c中的内存对齐很像啊。但是我们还是以实际情况来定。所以我们举个例子来计算一下:

       首先我们看看,第一个例子是我们最常见的有成员变量和函数。但这里我们只看变量。先char后是int那么大小是不是刚好为8啊。这个简单。但是我们看后面这两个例子就有古怪了。b没有成员变量啊。还有c啥都没有啊。这里我们就需要牵扯出外面c++这里计算大小的 专属规则了。

      大家想一想,如果这里我们给0的话。那就代表我们这里没有大小啊。没有大小不就表明啥都没有。没有就是无,调用无。会不会报错啊。所以我们不能给0。所以这⾥给1字节,纯粹是为了占位标识对象存在。

        好吧,这里咧我们计算类大小与计算数据结构大小是差不多的,区别就是当类没有变量的时候也会给个1。表示来过。

this指针

         看到指针大家应该很激动吧。我们以前有过学习,那么我们这里学起来就很简单了。对于这个知识点的引入大家可以思考一下Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?是吧,编译器怎么知道用的是哪个。所以c++中给了⼀个隐含的this指针解决这⾥的问题。那么这个this具体是如何解决问题的咧。

        其实编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。⽐如Date类的Init的真实原型为, void Init(Date* const this, int year, int month, int day)。意思是是说在外面的参数接受的时候其实是有一个隐藏的参数没有写的。这个参数就是来解决应该用哪个函数的。

      并且类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值, this->_year = year;所以大家明白为什么系统不会搞混了吧。就是我们的参数中是有一个隐含的this指针来指定该用那个函数。不用我们特别指定,不然的话,我们又会多很多工作量。但是C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显⽰使⽤this指针。就是说,在传参和接参的时候不能写,因为编译器会给我们写的。但是在内部可以写,毕竟都是公用的所以可以写。但是你不写也是可以的毕竟都在内部了,要是不特别指定的话,都是用内部的数据。

       ok,这个小节就是告诉了我们在外面传参的时候有一个隐含的this指针,这个来表明我们引用的是那个函数。这样我们系统就不会乱调用了。但是我们不能直接写出来只能让系统帮我们写。但是可以在函数体内显⽰使⽤this指针。就像我们上面图片中的那样。

总结

         好了,上面的内容就是我们今天这篇博客的知识了。关于c++的类的话这还只是马前卒。大家可以看到这篇博客有很多字。所以需要大家理解记忆的地方很多。大家多看看。也可以去看一些视频讲解。大家如果想要我博客中的代码的话,大家加油在Gitee中搜索@yang-hong-and-duan。最新的那个里面就有了。

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

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

相关文章

揭秘物联网“心脏“:智能控制器的无限可能

在飞速发展的物联网时代,我们身边的智能设备越来越多,从智能家居到工业自动化,从智能交通到智慧城市,这些设备的背后,都离不开一个至关重要的“心脏”——物联网智能控制器。那么,这个神秘的控制器究竟有何…

django踩坑(四):终端输入脚本可正常执行,而加入crontab中无任何输出

使用crontab执行python脚本时,有时会遇到脚本无法执行的问题。这是因为crontab在执行任务时使用的环境变量与我们在终端中使用的环境变量不同。具体来说,crontab使用的环境变量是非交互式(non-interactive)环境变量,而终端则使用交互式(inter…

Unresolved reference: button2

书籍 《第一行代码 Android》第三版 开发环境 Android Studio Jellyfish | 2023.3.1 问题 在学习《第一行代码 Android》第三版的3.3.5 返回数据给上一个Activity章节时, 在SecondActivity中给按钮注册点击事件时出现问题"Unresolved reference: button2",如下图…

[集成学习]基于python的Stacking分类模型的客户购买意愿分类预测

1 导入必要的库 import pandas as pd import numpy as np import missingno as msno import matplotlib.pyplot as plt from matplotlib import rcParams import seaborn as sns from sklearn.metrics import roc_curve, auc from sklearn.linear_model import LogisticRegres…

【SpringBoot配置文件application.yaml】笔记

详细内容见官方文档Common Application Properties 使用application.yaml进行简单配置 第一步:创建WebDemo第二步:创建application.yaml配置文件注意: 第三步:验证自己创建的yaml文件是否生效测试:思考:如…

【STM32嵌入式系统设计与开发---拓展】——1_9_1上拉输入和下拉输入

在使用GPIO引脚时,上拉输入和下拉输入的选择取决于外部电路的特性和应用需求。以下是它们各自的应用场景: 1、上拉输入(Pull-up Input) 用途: 当默认状态需要为高电平时。 避免引脚悬空(floating)导致的…

逆向学习思路链接分享

学好逆向先学C 然后我们需要学习好 编码问题CTF常见编码及加解密(超全) - ruoli-s - 博客园 (cnblogs.com) 并且规划好学习路线 CTF逆向Reverse入门学习路线(面向小白)_逆向reverse 思路-CSDN博客 并且安好反编译的环境 x64d…

微信保存的图片很模糊,用这个软件,秒变高清图!

我们有时从微信下载下来的图片就是很模糊,重新加载也一样,不知道什么原因。那么有什么好的解决图片模糊的办法吗? 微信保存的图片很模糊,用这个软件,秒变高清图! 或者是写一个东西,需要配图&am…

在项目服务器部署git 并实现自动提交

以下场景适合在服务器当中使用git 方便提交代码,同时不需要外部的git仓库(码云gitee或者github作为管理平台)。依靠服务器本身ssh 连接协议做为git提交的地址,同时利用钩子自动同步项目代码 首先下载git sudo apt update sudo a…

什么是 EDI 电子数据交换? EDI 有哪些优势?EDI 解决方案 以及行业应用

什么是EDI电子数据交换? EDl电子数据交换(Electronic Data |nterchange)是指按照同一规定的一套通用标准格式,将标准的数据信息通过通信网络传输,在贸易伙伴的电子计算机系统之间进行数据交换和自动处理。简单来说,EDI是将贸易、…

2024Datawhale AI夏令营---Inclusion・The Global Multimedia Deepfake Detection--学习笔记

赛题背景: 其实总结起来就是一句话,这个项目是基于目前的深度伪装技术,就是通过大量人脸的原数据集进行模型训练之后,能够生成伪造的人脸视频。这项目就是教我们如何去实现这个DeepFake技术。 Task1:了解Deepfake和跑通baseline …

C语言 | Leetcode C语言题解之第237题删除链表中的节点

题目: 题解: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/void deleteNode(struct ListNode* node) {struct ListNode * p node->next;int temp;temp node->val;node->val…

C++从入门到起飞之——inline/nullptr关键字全方位剖析!

个人主页:秋风起,再归来~ C从入门到起飞 个人格言:悟已往之不谏,知来者犹可追 克心守己,律己则安! 目录 1、inline 2、nullptr 3.完结散花 1、inline • ⽤inline修饰的函数叫…

苹果手机的微信过期文件怎么恢复?3个小窍门,让你快速找回

在微信APP里,发送过的文件只能储存7天,7天之后就会自动清除,导致无法打开。那么,微信过期文件怎么恢复呢?别担心,今天我们就来分享3个实用的小窍门,帮助你轻松恢复苹果手机上过期的微信文件。赶…

React Native 自定义 Hook 获取组件位置和大小

在 React Native 中自定义 Hook useLayout 获取 View、Pressable 等组件的位置和大小的信息 import {useState, useCallback} from react import {LayoutChangeEvent, LayoutRectangle} from react-nativeexport function useLayout() {const [layout, setLayout] useState&l…

springcolud学习03Eureka

Eureka 模块 来实现服务治理 服务治理就是提供了微服务架构中各微服务实例的快速上线或下线且保持各服务能正常通信的能力的方案总称 建立eureka模型 导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XM…

Linux 上 TTY 的起源

注&#xff1a;机翻&#xff0c;未校对。 What is a TTY on Linux? (and How to Use the tty Command) What does the tty command do? It prints the name of the terminal you’re using. TTY stands for “teletypewriter.” What’s the story behind the name of the co…

浅谈Visual Studio 2022

Visual Studio 2022&#xff08;VS2022&#xff09;提供了众多强大的功能和改进&#xff0c;旨在提高开发者的效率和体验。以下是一些关键功能的概述&#xff1a;12 64位支持&#xff1a;VS2022的64位版本不再受内存限制困扰&#xff0c;主devenv.exe进程不再局限于4GB&#xf…

SQL常用数据过滤---IN操作符

在SQL中&#xff0c;IN操作符常用于过滤数据&#xff0c;允许在WHERE子句中指定多个可能的值。如果列中的值匹配IN操作符后面括号中的任何一个值&#xff0c;那么该行就会被选中。 以下是使用IN操作符的基本语法&#xff1a; SELECT column1, column2, ... FROM table_name WH…

用Vue3和WebCola实现3D图的在线展示

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 基于Cola.js的网络图绘制 应用场景 Cola.js是一个JavaScript库&#xff0c;用于绘制交互式网络图。它广泛应用于社交网络、知识图谱、生物网络等领域&#xff0c;帮助用户可视化和探索复杂的数据关系。 基本…