【C++杂货铺】详解类和对象 [上]

博主:代码菌@-CSDN博客
专栏:C++杂货铺_代码菌@的博客-CSDN博客

目录
🌈前言🌈
📁 面向对象语言的特性
📁 类
📂 概念
📂 定义
📁 访问限定符
📂分类
📂 封装
📁 类的作用域
📁 类的实例化
📁 类的模型
📂 类的存储
📁 面试题
📁this指针(灰常重要)
📂 this指针的引入
📂 this指针的特性
📂面试题
📁 总结
🌈前言🌈
欢迎收看本期【C++杂货铺】,这期内容,我们将围绕C++中类和对象部分内容进行讲解,包括了 封装,类的概念,如何定义类和类的大小等内容,最后我们给出工作面试出的一道题目进行讲解。
如果你想学习C++,或者刚学完C语言衔接C++,那么这篇文章将会非常有效的帮助你理解。
📁 面向对象语言的特性
面向对象语言有三大特性:封装,继承,多态。在类和对象中,我们重点讲解一下,什么是封装。

例如,我们使用电脑,用户只需要知道如何与鼠标,键盘等进行交互,而不需要知道机器内部CPU,内存等是如何工作的,厂商都将其隐藏起来,封装在机箱中,这就是封装的过程。而这个机箱就是 类。
📁 类
📂 概念
不知道你是否学习过C语言中的结构体struct,来存储不同类型的数据。类就是结构体的进阶版,类 中不仅可以定义变量(成员变量),还可以定义 函数(成员函数)。
📂 定义
class className
{// 类体:由成员函数和成员变量组成 ...
};struct Name
{// 类体:由成员函数和成员变量组成...
}
需要注意的是类,不仅可以是class,也可以是struct。class定义时{}后面有 ; ,这点需要注意。
class为定义类的关键字,ClassName为类的名字,{}内为类的主体。
类体中的内容称为类的成员:类中的变量称为类的属性或者成员变量;类中的函数称为类的方法或成员函数。
类的两种定义方式:
1. 声明和定义都在类体中,需要注意的是:成员函数如果在类中定义,编译器可能会将其当做是内联函数处理。(如果不懂内联函数,可以参考下面这篇文章)
【C++杂货铺】三分钟彻底搞懂函数重载-CSDN博客
下图中,public 和 private是限定操作符。

2. 类的声明放在 .h 文件中, 成员函数定义在 .cpp文件中。

一般情况是,在学习竞赛中使用第一种情况;工作过程,采用第二种。
此外,还有一个约定俗成,就是成员变量一般以 _开头,也是为了方便区分。
📁 访问限定符
什么是访问限定符呢,就是一种限制。例如,我们的电脑,对于一个小白,那就限制他只能使用鼠标键盘等操作,不允许触碰机器内部的元器件。鼠标键盘就是共有的,机器元器件就是私有的。
📂分类

【 访问限定符说明 】:
1. public 修饰的成员在类外可以直接被访问。2. protected 和 private 修饰的成员在类外不能直接被访问 ( 此处 protected 和 private 是类似的 )。3. 访问权限 作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。4. 如果后面没有访问限定符,作用域就到 } 即类结束。5. class 的默认访问权限为 private , struct 为 public( 因为 struct 要兼容 C)。注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

C++需要兼容C语言,所以C语言中的struct可以当成结构体来使用。另外C++中struct还可以用来定义类。和class一样,区别是struct定义的类默认访问权限是public,class定义的类默认访问权限是private。
(注意:在继承和模板参数列表位置也有区别,后续给大家介绍)
📂 封装
C++中实现封装的方式: 用类将对象的属性与方法结合在一起,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
封装具有一下特性:
1. C++中数据和方法都在类中
2. 通过C++访问限定符对成员进行限制,可以访问在公有作用域下,不可以访问在私有作用域下。
封装的本质是一种管理,让用户更加方便的使用类。
📁 类的作用域
类定义了一个新的作用域,类的所有成员都在这个类中。在类体外定义成员时,需要使用 :: 来标明作用域操作符指明成员属于哪个类域。
class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " "<< _gender << " " << _age << endl;
}
📁 类的实例化
用类 来创建对象的过程,叫做类的实例化。
1. 类是对对象进行描述的,是一个模型,限定了类有哪些成员,定义一个类并没有分配具体实际的内存空间来存储。
2. 类 可以实例化出多个对象,实例化的对象 占用实际的物理空间,存储成员变量。

📁 类的模型
类中既有成员变量,又有成员函数,那么如何计算类的大小呢?
📂 类的存储
● 对象中包含类的各个成员

● 代码只保存一份,在对象中保存存放代码的地址

● 只保存成员变量,成员函数存放在公共的代码段

目前,是采用第三种方法。也就是说,成员变量存在对象中,而成员函数存在代码区。因为大家想想,如果每个成员函数都存储一份相同的成员函数,会造成很大的空间浪费。
求类的对象大小,就是看里面的成员变量。
// 类中既有成员变量,又有成员函数
class A1 {
public:void f1(){}
private:int _a;
};
// 类中仅有成员函数
class A2 {
public:void f2() {}
};
// 类中什么都没有---空类
class A3
{}; 结论:一个类的大小,实际就是该类中 ” 成员变量 ” 之和,当然要注意内存对齐注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。
📁 面试题
1. 结构体怎么对齐? 为什么要进行内存对齐?(1). 第一个成员在与结构体偏移量为 0 的地址处。(2). 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8(3). 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数 倍。(4). 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。![]()
2. 如何让结构体按照指定的对齐参数进行对齐?能否按照3、4、5即任意字节对齐?#pragma pack( ~ ) 这个预处理指令,可以改变编译器的默认对齐数。
📁this指针(灰常重要)
📂 this指针的引入
如果我们实例化两个相同类的对象A,B。同时调用成员函数初始化和打印这两个对象,如下。
class Date
{
private:int _year;int _month;int _day
public:void Init(int year,int month,int day){_yeaar = year;_month = month;_day = day;}void Print(){cout<<_year<<'/'<<_month<<'/'<<_day<<endl;}
}int main()
{Date A;A.Init(1,1,1);A.Print();Date B;B.Init(2,2,2);B.Print();
}
编译器如何识别A和B呢?通过类的模型,我们知道,A和B的所调用的函数都是同一个,都是执行相同的指令,那编译器怎么识别year,month,day是A还是B的成员变量了。
你会发现,谁调用了,就打印,赋值给谁的成员变量。
这就引入了this指针的概念,隐含的this指针。所有的成员函数都隐藏一个形参,调用的地方,编译器也会处理。
void Print(Date* const this)
{cout<<_year<<'/'<<_month<<'/'<<_day<<endl;
}A.Print(&A);
C++编译器会给每个“非静态的成员函数”增加1个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有操作对用户是透明的,即不用不需要传递,编译器自动处理。
📂 this指针的特性
1. this指针的类型:类 类型 * const 。即在成员函数中,this1指针不能被修改指向。
2. 在形参和实参的位置不能显示写。即你不能写this,这是编译器做的事,你做了,编译器会报错。
3. this指针只能在成员函数中内部使用。
4. this指针的本质是 成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this这个形参,所以对象不存储this指针。
5. this指针是成员函数第一个隐含的指针形参,一般情况下由编译器通过ecx寄存器自动传递,不需要用户传递。
📂面试题
this指针存在在哪里?(B)
A. 堆 B. 栈 C. 静态区 D. 常量区 E. 对象里面
解析:
首先排除E,因为对象实例化后,只存储成员变量,这是在类的模型中讲解的。
其次,排除常量区,cosnt修饰的常变量本质上还是变量。
然后,排除静态区,静态区只存储 static静态变量和全局变量。
最后,排除堆,堆是程序员自己开辟管理的空间。
this指针可以为空吗:可以,只要不在成员函数中解引用。
我么创建一个类的空指针,空指针作为实参传递给形参。
( mov的意思就是数据赋值,lea的意思就是取地址。)
下面为案例,成员函数不存储在对象中,所以A->Print不是解引用,编译器会识别成Date::Print,即通过A的类找到Print这个成员函数。其他成员函数也是同理。
① 在成员函数不解引用this指针。
class Date { private:int _year;int _month;int _day public:void Init(int year,int month,int day){_yeaar = year;_month = month;_day = day;}void Print(){cout<<_year<<'/'<<_month<<'/'<<_day<<endl;} } int main() {Date* A = nullptr; A->Print(); }上面代码,会将A的值传递给this指针,但在Print中并没有解引用空指针,所以程序正常运行。
② 如果this指针为空,在成员函数解引用this指针。会发生运行错误。
class Date { private:int _year;int _month;int _day public:void Init(int year,int month,int day){_yeaar = year;_month = month;_day = day;}void Print(){cout<<_year<<'/'<<_month<<'/'<<_day<<endl;} }int main() {Date* A = nullptr; A->Init(); }上面代码,会将A的值传递给this指针,但在Init中解引用空指针,所以程序运行错误。
总结一下,可以定义了一个类的指针为空指针,通过空指针,可以找到类的成员函数,此时,并不是空指针的解引用,此外,空指针将赋值给this指针。
this指针可以为空,但在成员函数中解引用this指针会运行错误。
📁 总结
总结,类就类似于struct结构体,不过可以再内部定义成员函数。
通过学习类,了解什么是封装,即通过类将对象的属性和方法结合在一起,通过访问限定符有选择的接口提供给外部用户使用。封装的本质就是一种管控。
当然这只是类的初窥门槛,之后的文章将逐渐揭开类的神秘面纱。
如果这篇文章对你有所收获,欢迎点赞,评论,收藏。Thanks♪(・ω・)ノ

相关文章:
【C++杂货铺】详解类和对象 [上]
博主:代码菌-CSDN博客 专栏:C杂货铺_代码菌的博客-CSDN博客 目录 🌈前言🌈 📁 面向对象语言的特性 📁 类 📂 概念 📂 定义 📁 访问限定符 📂分类 &#x…...
Linux 驱动开发基础知识—— 驱动设计的思想(六)
个人名片: 🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:V…...
Mybatis-Plus入门
Mybatis-Plus入门 MyBatis-Plus 官网:https://mp.baomidou.com/ 1、简介 MyBatis-Plus (简称 MP) 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、 提高效率而生。 https://github.com/baomidou/mybatis-p…...
MODNet 剪枝再思考: 优化计算量的实验历程分享
目录 1 写在前面 2 模型分析 3 遇到问题 4 探索实验一 4.1 第一部分 4.2 第二部分 Error 1 Error 2 4.3 实验结果 ①参数量与计算量 ②模型大小 ③推理时延 5 探索实验二 5.1 LR Branch 5.2 HR Branch 5.2.1 初步分析 5.2.2 第一部分 enc2x 5.2.3 第二部分 en…...
Flink多流转换(1)—— 分流合流
目录 分流 代码示例 使用侧输出流 合流 联合(Union) 连接(Connect) 简单划分的话,多流转换可以分为“分流”和“合流”两大类 目前分流的操作一般是通过侧输出流(side output)来实现&…...
CSS高级技巧导读
1,精灵图 1.1 为什么需要精灵图? 目的:为了有效地减少服务器接收和发送请求的次数,提高页面的加载速度 核心原理:将网页中的一些小背景图像整合到一张大图中,这样服务器只需要一次请求就可以了 1.2 精灵…...
Redis数据类型-string
Redis-string类型 Redis中的数据类型全局命令get&setredis中变量设置的过期时间是如何检测的 keysexistsdelexpirettlpexpirepttltype string数据类型的底层的数据结构操作string类型的常用命令get&setmset&mgetsetnxsetexpsetexincr&decrincrby&decrbyinc…...
【HDFS】一天一个RPC系列--updatePipeline
updatePipeline这个RPC一般都会配合updateBlockForPipeline RPC一起使用。 先updateBlockForPipeline、然后再updatePipeline。 建议先阅读【HDFS】一天一个RPC系列–updateBlockForPipeline 本文目标是弄清楚以下问题: 弄清updatePipeline这个RPC的作用。弄清updatePipeli…...
CentOS 7 上使用 wget 安装 Nginx 并设置开机自启
在 CentOS 7 上使用 wget 安装 Nginx 并设置开机自启,你可以按照以下步骤进行操作: 首先,确保你已经以 root 用户或者具有 sudo 权限的用户身份登录到 CentOS 7。 安装 Nginx 所需的依赖包。在终端中运行以下命令: sudo yum inst…...
Android源码设计模式解析与实战第2版笔记(一)
第一章 走向灵活软件之路 — 面向对象的六大原则 优化代码的第一步 — 单一职责原则 单一职责原则的英文名称是Single Responsibility Principle,缩写是SRP。 SRP:就一个类而言,应该仅有一个引起它变化的原因。 一个类中应该是一组相关性很…...
HTML+JavaScript-06
节点操作 目前对于节点操作还是有些困惑,只是了解简单的案例 具体操作可以看菜鸟教程:https://www.runoob.com/js/js-htmldom-elements.html 案例-1 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8…...
单元测试——题目十二
目录 题目要求: 定义类 测试类 题目要求: 根据下列流程图编写程序实现相应处理,执行j=10*x-y返回文字“j1=:”和计算值,执行j=(x-y)*(10⁵%7)返回文字“j2=:”和计算值,执行j=y*log(x+10)返回文字“j3=:”和计算值。 编写程序代码,使用JUnit框架编写测试类对编写的…...
详解:大数据信用报告信用等级怎么看?
在大数据技术的加持之下,金融风控也逐渐运用大数据技术了,也就是我们说的大数据或者大数据信用,在大数据信用报告中对个人的综合信用风险有着等级划分,那大数据信用报告信用等级怎么看呢?本文为你详细介绍一下,感兴趣…...
rsync命令常用参数详解
1、语法 Usage: rsync [OPTION]… SRC [SRC]… DEST or rsync [OPTION]… SRC [SRC]… [USER]HOST:DEST or rsync [OPTION]… SRC [SRC]… [USER]HOST::DEST or rsync [OPTION]… SRC [SRC]… rsync://[USER]HOST[:PORT]/DEST or rsync [OPTION]… [USER]HOST:SRC [DEST] or r…...
基于SpringBoot实现策略模式提供系统接口扩展能力
相信我们对策略模式都有耳闻,但是可能不知道它在项目中具体能有什么作用,我们需要在什么场景下才能去尽可能得去使用策略模式。 这里我简单的列出一个我之前在公司做的一个需求:跟第三方oa系统对接接口,对方需要回调我们当前系统…...
v43-47.problems
1.for循环 一般地,三步走: for(初始化;表达式判断;递增/递减) { ....... } 但是,如果说声明了全局变量,那么第一步初始化阶段可以省略但是要写分号‘ ; ’…...
华为HCIP Datacom H12-831 卷14
多选题 1、以下哪些Community属性可以保证BGP路由条目的传播范围只在AS内? A No_Export B No_Export_Subconfed C Interne D No_Advertise 正确答案 A,B 解析:Internet:缺省情况下,所有的路由都属于internet团体。具有此属性的路由可以被通告给所有的BGP对等体。n…...
《vtk9 book》 官方web版 第3章 - 计算机图形基础 (1 / 6)
计算机图形是数据可视化的基础。从实际角度来看,可视化是将数据转换为一组图形基元的过程。然后使用计算机图形的方法将这些基元转换为图片或动画。本章讨论了基本的计算机图形原理。我们首先描述了光线和物体如何相互作用形成我们所看到的景象。接下来,…...
负载均衡是什么,负载均衡有什么作用
一、什么是负载均衡 负载均衡是一种在计算机网络和系统架构中使用的技术,用于均衡分发工作负载到多个资源,比如:服务器、计算节点或存储设备上,以提高系统的性能、可伸缩性。 在传统的单个服务器架构中,当请求量增加…...
Leetcode 3020. Find the Maximum Number of Elements in Subset
Leetcode 3020. Find the Maximum Number of Elements in Subset 1. 解题思路2. 代码实现 题目链接:3020. Find the Maximum Number of Elements in Subset 1. 解题思路 这一题我做的是比较水的,首先就是统计下array当中各个元素出现的频次࿰…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

