当前位置: 首页 > news >正文

《类和对象(上)》

引言:

上次我们学习了C++的一些入门基础,但其实还没有入门C++,想要入门C++,肯定是要把类和对象这部分学透彻,这次先来学习类和对象(上)

一:类的定义

1. 类定义格式:

  1. class为定义关键字Stack为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量,类中的函数称为类的方法或者成员函数。
  2. 为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面加_或者m开头,注意C++中这个并不是强制的,只是一些惯例,具体看公司的要求。
  3. C++中struct也可以定义,C++兼容C中struct的用法,同时struct升级成了类,明显的变化是struct中可以定义函数,一般情况下我们还是推荐用class定义
  4. 定义在里面的成员函数默认为inline
场景一 :类和结构体的对比

这个是我们用类来实现的栈(功能并不完善,重在对比)
在这里插入图片描述
在这里插入图片描述

这是我们之前用结构体实现的:
在这里插入图片描述
在这里插入图片描述
通过对比可以发现几点区别:

  1. 结构体来实现时,数据方法是分开的;用来实现的话,数据方法是放在一块的。
  2. 结构体来实现时,为了避免函数名冲突,还需要有一些前缀来进行区分,比如SKPush,但是如果用来实现的话,就不用再顾虑这个点,因为不同的类域里面允许存在相同的函数名。
场景二:特殊标识来区分成员变量

在这里插入图片描述来看上面这个场景,初始化时传入的形参成员变量的名字相同,这时候就很难去区分了,为此,按照惯例的话会将成员变量加上一些特殊标识,如下面这种情形:

在这里插入图片描述
成员变量中加上了一个前缀_来进行区分,这个按照个人习惯即可,并没有什么硬性要求。

场景三:C++中的结构体

尽管在C++中引入了,C++中也是可以兼容struct的用法的,并且struct在C++中也升级为了,比较明显的就是在struct中也可以定义函数了,尽管如此,我们还是建议使用class来定义
在这里插入图片描述
由于struct升级为了,因此无需再typedefstruct的名字就可以用来表示类型。
在这里插入图片描述

2. 访问限定符:

访问限定符分类

在这里插入图片描述

  1. C++用一种实现封装的方式,将类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
  2. public修饰的成员在类外可以直接被访问;protectedprivate修饰的成员在类外不能直接被访问,protectedprivate是一样的,以后继承章节才能体现出他们的区别。
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到}即类结束。
  4. class定义成员没有被访问限定符修饰时默认为privatestruct默认为public
  5. 一般成员变量都会被限制为private/protected,需要给别人使用的成员函数会放为public
场景一:public的成员和private的成员对比

在这里插入图片描述
由于Init函数是在public里面,可以访问,但是top是在private里面,不能访问,所以编译器在这里会报错。

场景二:class和struct定义类-默认限定符对比

在这里插入图片描述

解读:

由于class定义时,默认访问限定符private,因此这里都不能访问了。

在这里插入图片描述

解读:

由于struct定义时,默认访问限定符public,所以这里都可以访问。

3. 类域:

  1. 定义了一个新的作用域的所有成员都在作用域中,在类体外定义成员时,需要用::作用域操作符指明成员属于哪个类域
  2. 类域影响的是编译的查找规则,下面程序中Init如果不指定类域Stack,那么编译器就把Init当成全局函数,那么编译时,找不到arr等成员的声明/定义在哪里,就会报错。指定类域Stack,就是知道Init成员函数,当前域找不到的arr等成员,就会到类域中去查找。
在类中函数定义和声明分离时的注意事项

在这里插入图片描述
解决方法-指定类域
在这里插入图片描述

引申思考:

既然声明定义分离容易出错,那么我们为什么还要这么做呢?其实这样做还是有好处的:

  1. 避免链接时的冲突
  2. 将一些复杂函数进行声明定义的分离,增加代码的可读性。

二:实例化

1.实例化概念:

  1. 用类类型在物理内存中创建对象的过程,称为类实例化出对象。
  2. 类是对象进行一种抽象描述,是一个像模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。
  3. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。比如:建造房屋时,首先有一个设计图纸来规定这个房屋的大小、风格、构造等,并没有真的建造出一个实体。类就像这个房屋图纸一样,只是规定了类中都有哪些成员,并没有为其分配空间。

在这里插入图片描述

实例化举例

在这里插入图片描述

在这里插入图片描述

2. 对象大小

分析一下类对象中都有哪些成员呢?类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?首先函数被编译后是一段指令,对象中没办法存储,这些指令存储在一个单独的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针。再分析一下,对象中是否有存储指针的必要呢,Date实例化d1d2两个对象,d1d2都有各自独立的成员_year_month_day存储各自的数据,但是d1d2的成员函数Init/Print指针却是一样的,存储在对象中就浪费了。如果用Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。其实函数指针是不会存储的,但是现在还没学,解释不了这个问题。

因此得出结论:
对象中只会存储成员变量,还需要注意这里也要遵守内存对齐原则

旧知复习:

内存对齐规则:

  1. 第⼀个成员在与结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
  3. 注意:对齐数 = 编译器默认的一个对齐数与该成员大小的较小值
  4. VS中默认的对齐数为8
  5. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  6. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小。
练习:

计算A B C 在内存中的空间大小
在这里插入图片描述

分析:

在这里插入图片描述
但是BC里面都没有成员变量,难道BC0吗?
我们来打印看一下

在这里插入图片描述

解读:

这里可以看到a占用的空间大小和我们分析的一样,但是bc都是1,并不是0,这是为什么呢?

因为如果一个字节都不给,怎么表示对象存在过呢!所以这里给1字节,纯粹是为了占位标识对象存在。

三:this 指针

Date类中有InitPrint两个成员函数,函数体中没有关于不同对象的区分,那当d1调用InitPrint函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这里就要看到C++给了一个隐含的this指针解决这里的问题。

其实编译器在编译后,类的成员函数默认都会在形参第一个位置,增加一个当前类类型的指针,叫做this指针。比如Date类的Init的真实原型为,void Init(Date* const this, int year, int month, int day)

类的成员函数中访问成员变量,本质都是通过this指针访问的,比如这里在进行初始化时:this-> _year = year
注意:C++规定不能在实参形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。
在这里插入图片描述
这里在调用函数的时候其实自动将d1d2的地址传了过去this指针接收了,因此函数才能区分d1d2
在类里面是可以将this指针写出来的,但不能在参数中写。
在这里插入图片描述
在参数里面写是会出错的,因为这是编译器的活儿,咱们不用多管闲事。
在这里插入图片描述

完结

撒花!!!

相关文章:

  • Python 整理3种查看神经网络结构的方法
  • 虚幻引擎作者采访
  • 什么是原码、反码与补码?
  • 2025流感疫苗指南+卫健委诊疗方案|高危人群防护+并发症处理 慢性肾脏病饮食指南2025卫健委版|低盐低磷食谱+中医调理+PDF 网盘下载 pdf下载
  • 牛客1018逆序数-归并排序
  • 金融的本质是智融、融资的实质是融智、投资的关键是投智,颠覆传统金融学的物质资本中心论,构建了以智力资本为核心的新范式
  • PyTorch 张量与自动微分操作
  • 全球化电商平台Azure云架构设计
  • 期末代码Python
  • iptables的基本选项及概念
  • 串 Part 1
  • 数据链路层(MAC 地址)
  • Gemini 解释蓝图节点的提示词
  • STC单片机与淘晶驰串口屏通讯例程之04【密码登录与修改】
  • 有哪些场景不适合使用Java反射机制
  • 基于C++实现的深度学习(cnn/svm)分类器Demo
  • H3C无线控制器自动信道功率调整典型配置实验
  • 数据结构小扫尾——栈
  • JAVA:使用 Maven Assembly 创建自定义打包的技术指南
  • Kubernetes(k8s)学习笔记(七)--KubeSphere 最小化安装
  • 新剧|《执法者们》《亲爱的仇敌》5月7日开播
  • 多地政府机关食堂迎来大客流,重庆荣昌区委书记给厨师们鼓劲
  • 建邦高科赴港上市,大股东陈子淳系山东建邦集团董事长陈箭之子
  • 牧草之王苜蓿的江南驯化史
  • 一周观展|上海浦东美术馆透纳展还剩最后5天
  • 巴菲特股东大会4.5万字问答实录:股神60年穿越牛熊的最新心得和人生思考