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

C++类和对象(上):一文搞懂基础定义与核心规则

gitee地址:Yu 子淳 (yyyzzzzccc) - Gitee.com

目录

1、类和对象的定义(class)

1.1什么是类?

1.2 类定义格式

1.3代码示例

1.4类的核心组成元素

2、类(class)与结构体(struct)的关系

​编辑3、为啥优先使用class?

4、什么时候反而用 struct?

5、 访问限定符

6、类域作用域与成员访问规则

7、实例化

8、内存对齐原则

9、this指针的讲解


1、类和对象的定义(class)

1.1什么是类?

我们可以把类理解为一张【图纸】,把对象理解为根据图纸造出来的【实物】。

举个生活最直观的例子:

- 汽车图纸:规定了汽车必须有车轮、颜色、品牌(属性),可以行驶、刹车、鸣笛(行为)——这就是类

- 特斯拉、比亚迪、丰田的每一台具体汽车:按照图纸造出来、有具体参数、可以实际使用的实物——这就是对象

简单总结核心关系:类是对象的模板,对象是类的实例。
类只定义「规则和特征」,不占用实际内存;对象是类的具体化,会开辟内存空间,承载真实数据。

1.2 类定义格式

1、class为定义类的关键字,Stack为类的名字,这里的类的名字不是唯一的,可以自定义。{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。

2、 为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m开头,注意C++中这个并不是强制的,只是⼀些惯例,具体看公司的要求。

3、C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,明显的变化是struct中可以定义函数,⼀般情况下我们还是推荐⽤class定义类。

4、 定义在类⾯的成员函数默认为inline。

1.3代码示例

这段代码当中,student就是一个类,它只规定了学生[有什么、能做什么],没有具体的年龄和姓名,也没有执行任何操作,只是一个套用模板。

1.4类的核心组成元素

类由属性(成员变量)和方法(成员函数)组成:

属性(成员变量):代表事物的静态特征、数据信息。比如:人的身高,年龄等,属性是用来存储数据,表述[这个事物是什么样子]。

方法(成员函数):代表事物的动态特征,功能操作。比如:人吃饭睡觉,手机拍照联网。方法用来实现逻辑,表述[这个事物能做什么]。

2、类(class)与结构体(struct)的关系

学完类的概念与作用后,绝大多数 C++ 初学者都会遇到同一个困惑:
结构体 struct 看起来和 class 几乎一模一样,也能存数据、写函数,那它和类到底是什么关系?有什么区别?

本章彻底讲透:struct 和 class 的历史关系、底层联系、语法区别、设计定位,一次性终结混淆。

2.1 二者真实关系:struct 是 class 的「前身」

1)C语言时代的 struct(纯数据容器)

C 语言没有类、没有面向对象。
为了把零散变量打包成一个整体,C 设计了 struct ,只能存变量,不能写函数。

它的唯一作用:聚合一组相关数据。

2)C++ 对 struct 进行全面升级

C++ 为了兼容 C 语言,保留了 struct,并给 struct 新增了全套面向对象能力:

- 可以写成员函数

- 可以有构造、析构函数

- 可以继承

- 可以多态

- 可以封装

所以在 C++ 语法层面:struct 和 class 本质是同一个东西。

3)一句话总结二者关系

struct 是 C++ 中弱化版、兼容版的 class。
class 是 C++ 专门为面向对象设计的、规范化的 struct。

它们同源、同结构、同能力,只是默认规则、设计语义、使用场景不同。

3.2 struct 与 class 的完全相同点(重点!很多人不知道)

在 C++ 中,两者语法能力完全一致:

1. 都可以封装成员变量

2. 都可以定义成员函数

3. 都拥有构造函数、析构函数

4. 都支持继承、派生

5. 都支持多态、虚函数

6. 都可以实例化对象

也就是说:你能用 class 写出来的代码,100% 可以用 struct 替代编译通过。

3.3 struct 与 class 的唯一本质语法区别

1)成员默认访问权限不同(核心差异)

- class 默认 private(私有)

- struct 默认 public(公有)

3、为啥优先使用class?

最核心的区别是:默认权限不同

class的默认成员权限是private(私有)。外部无法直接访问访问成员,数据默认被保护。

struct的默认成员是public(公有),所有成员对外完全暴露,任何人都可以直接读写数据。

4、什么时候反而用 struct?

这里补充边界场景,做到完整认知,避免绝对化:
- 简单数据结构体:坐标、点、颜色、报文协议、传输数据等,只有成员变量,没有业务方法,优先用 struct 。

- 兼容 C 语言代码:老项目、底层驱动、嵌入式代码需要兼容 C 语法时,沿用 struct 。

5、 访问限定符

• C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的⽤⼾使⽤。

• public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的,以后继承章节才能体现出他们的区别。

• 访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到 }即类结束。

• class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

• ⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

6、类域作用域与成员访问规则

在前面的讲解当中,我们知道类是一个封装了数据和函数的独立模块。但是在实际开发当中,我们经常遇到一个问题:不创建对象,能不能直接访问类里面的成员?这里就需要用类域::,并结合成员类型和访问权限来判断。在前面的C++基础当中,我们直到::作用域运算符,语法格式为类名::成员名。

它的作用,就是明确告诉编译器:我要访问它的这个成员,属于那个类的。

为啥要创建对象才能访问成员变量呢?是因为我们在前面的讲解中,我们可以把class student比作【学生档案模板】,这些模板上面只写了姓名,年龄,学号这些字段,并没有具体的值。当你创建student s时,就相当于打印了一份空白档案,为s这个学生分配独立的空间,你才可以往里面填写s.age=18;如果不创建对象,就像手中只有一张模板,你没法在模板上直接写年龄=18---因为模板是通用的,不属于任何一个学生。最简陋的说就是你定义的类只是一个模板,没有创建空间,所以你直接把18这个值赋给age,它是没有办法存放的,所以需要先创建变量,才能存放这个值。

7、实例化

什么是实例化呢?

1、实例化就是用类类型在物理内存中创建对象的过程,称为实例化出的对象。

2、我们在上面说了,类是一个模板,需要创建对象才能进行使用,一个类可以创建出多个对象。

如上面我们在开头也讲了,可以把类看作一个设计图纸,对象就是根据设计图纸创建出来的一个个房子,它们的布局都是一样的。

我们写一个以学生为类的模板,我们实例化两个对象d1和d2,我们想一下,我们假如调用50次成员函数,就重复50次吗?太浪费空间是时间了,我们一般把成员函数放一个公共区域,这样每次调用直接在公共区域里面去找,这样就会很方便,我们在这里先不仔细讲解,以后再讲。

8、内存对齐原则

这个我们在之前的文章当中讲解过,这里就不仔细讲解了,我们再次把定义重复一遍,练几道题就过。

• 第⼀个成员在与结构体偏移量为0的地址处。

• 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

• 注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

• VS中默认的对⻬数为8

• 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

• 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍。

注意:在类当中,我们算内存大小只需要计算成员变量,不用算成员函数。如果类当中只有成员函数,只有成员变量,默认内存大小为1,不能为0,代表这个类存在过,这时C++规定。

内存大小的计算:首先第一个成员放到结构体偏移量为0的地址处,它的字节大小是4,所以依次放4个字节,第二个成员要对齐到对齐数的整数倍的地址处,而对齐数=编译器默认值和该成员大小的较小值,而又因为编译器的默认值是8,而这个成员变量的字节大小是1,所以对齐数综合下来就是1,结构体的总大小:最大对齐数(所有成员变量的最大值与默认值的最小)的整数倍,也就是4的整数倍,而现在是5,所以再填3个字节大小凑到8,成为4的倍数。所以总大小是8.

而对于这种只有成员函数,没有成员变量的类,它的内存大小默认是1;

9、this指针的讲解

• student类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了⼀个隐含的this指针解决这⾥的问题

• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。⽐如student类的Init的真实原型为, void Init(student* const this, int age,int height)

• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_age赋值, this->_age=age;

• C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显⽰使⽤this指针。

我们可以看到把this指针补上去,也可以正常过,但是在实参和形参的位置没有显示this指针,是因为C++规定,会处理掉this指针,所以这两处没有显示this指针,但是在访问成员变量和打印时我们可以把this指针填上去,也是可以的。

http://www.rkmt.cn/news/1445383.html

相关文章:

  • 聚力绿色包装创新,interpack China×WPO 上海盛会 11 月启幕
  • 电网设备拓扑图一键自动排布工具(基于FR力导向算法)
  • 职场人必备!高颜值电脑音乐播放器YesPlayMusicV0.4.10
  • Oura Ring 5 发布:体积缩小40%,新增血压追踪与睡眠呼吸分析
  • 2026年天津建设工程律师避坑指南:5位建工经验丰富靠谱推荐 - 本地品牌推荐
  • 定理证明器在干细胞生物学中的应用:形式化建模与逻辑推理
  • 从零到一:用Python和SQLAlchemy玩转MIMIC-IV数据库(实战数据分析流程)
  • 大模型自动化领域自适应:从通用到专业的低成本迁移方案
  • 500+免费插件:让RPG Maker MV/MZ实现专业级游戏开发的终极指南
  • 体育直播AI化倒计时!Sora 2已通过FIFA技术认证,但92%团队正误用“运动连贯性参数”——即刻修正的4个致命配置
  • 从随机到精确:现代采样方法的核心演进与工程实践
  • FastSpeech:非自回归语音合成的速度、准确性与可控性革命
  • Ubuntu 20.04/22.04下,Isaac Gym的Segmentation fault坑我踩完了,这是最全的避坑指南
  • KMS智能激活实战宝典:从零掌握Windows与Office永久激活秘籍
  • 别再死记硬背了!用Simulink手把手复现双三相电机VSD建模(附模型文件)
  • 告别黑白终端!用Python的termcolor库给你的日志和CLI工具加点‘颜色’
  • AI生成代码的合规、版权与漏洞治理(传统IT转型专项课题)
  • Diablo Edit2完全指南:暗黑破坏神2角色编辑器终极使用教程
  • UE5蓝图实战:用样条线+Spline组件打造可交互的3D测距工具(附完整项目文件)
  • 量身定做网络工程师日常运维的MCP Server企业级工具
  • 后量子密码学FrodoKEM:基于LWE的保守安全方案解析
  • Deepoc VLA开发板:采摘机器人自主决策与柔性协同系统
  • 抖音无水印下载器:3分钟快速上手免费批量下载神器
  • 从手机剪辑到云端处理:FFmpeg批量缩放视频的3种自动化实战方案
  • 告别Clion和GCC:在VS2022上用MSVC编译器搞定你的第一个C语言图像处理项目
  • 云安全新范式:无代理内存快照与自动化威胁检测
  • KeyboardChatterBlocker终极指南:3步解决机械键盘连击问题
  • STM32的ADC采样精度怎么校准?手把手教你提升自制万用表的测量准确度
  • 告别流氓软件!用Sandboxie在Windows 11/10上安全测试未知程序(附EV录屏实测)
  • 企业级网络运维接入LLM大模型(在线)实战