C++入门:类和对象(上)

类和对象重点解析

  • 1.类的定义
    • 1.类的访问限定符及封装
      • 1.C++实现封装的方式
      • 2.访问限定符
        • 注意
      • 3.封装
  • 2.类对象模型
    • 2.1类对象存储方式
    • 2.2类对象的大小
      • 2.2.1结构体内存对齐原则
      • 2.2.2为什么要内存对齐
  • 3.this指针
    • 3.1this指针的引出
    • 3.2this指针的特性
    • 3.3this指针的存储
    • 3.4this指针可以为空吗?

1.类的定义

1.类的访问限定符及封装

1.C++实现封装的方式

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

2.访问限定符

public(公有),protect(保护),private(私有)

注意
1.public修饰的成员在类外可以直接被访问
2.protected和private修饰的成员在类外不能直接被访问
3.访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4.如果后面没有访问限定符,作用域就到 } 即类结束。
5.class的默认访问权限为private,struct为public(因为struct要兼容C)

3.封装

面向对象的三大特性:封装,继承,多态

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

封装本质上是一种管理,让用户更方便使用类。
通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。

2.类对象模型

2.1类对象存储方式

我们知道在C++中类的实现只是一个模板,用类创建成员后才会分配空间。如果创建多个对象,而每一个成员的函数都是一样的,那么在创建变量时是每一个成员都会有类函数还是所有的成员共用一个函数呢?那么我们在计算一个类对象的大小时应不应该计算这些函数的大小呢?

存储方式:每个对象中只保存成员变量,成员函数存放在公共的代码段。

a5468091abde0dd8a86df0.png)

2.2类对象的大小

2.2.1结构体内存对齐原则

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

注意:没有成员变量的类默认是1字节,占位标识对象的存在

2.2.2为什么要内存对齐

class A
{
private:char c;int i;
}

假设有一个类,先表示出对齐和不对齐的内存中的存储形式。
在这里插入图片描述
假设有三种读取方式:
方式一(内存对齐时):按照对齐的方式读取:先读取char,然后丢弃三个二进制位,再直接从int的开始位置进行读取。
方式二(不内存对齐时):先读取char,然后从char的下一个位置,也就是和char连续存储的int的位置。
方式三:先读取char,然后将剩余的三个字节存起来,再读取int的剩下的字节,然后将这两部分拼接起来。

首先,计算机根据地址线的大小,来确定能给多少存储器进行编码,是按照整数倍来读取,而不是从任意位置进行读取。而如果选择读取多次再进行数据的拼接的话更加麻烦,相比之下,内存对齐时只需要按顺序读取再丢掉不需要的那部分即可。
即:内存对齐就是计算机在读取数据的时候,尽量可以一次取到完整的数据而不是要分很多次才能拿到完整的数据,而且分多次拿到的话还需要进行数据的拼接组合,这样就会更加麻烦了。

3.this指针

3.1this指针的引出

class Date
{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}
private:int _year;     // 年int _month;    // 月int _day;      // 日
};
int main()
{Date d1, d2;d1.Init(2022,1,11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}

对于上面的Date类当我们在调用类的成员函数中,由于没有对于对象的区分,那么编译器是如何知道是哪个对象调用了它的函数从而执行对应的操作呢?
比如在打印时如何区分打印d1的信息还是打印d2的信息。

解决方案:

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

3.2this指针的特性

1.this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
2.只能在“成员函数”的内部使用
3.this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。
4.this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

3.3this指针的存储

不存储在堆上:堆上内存需要我们自己去申请。
不存储在对象内:我们在计算类对象大小时并没有将其算入在内。
不存储在常量区和静态区:没有static修饰,其也不是常量。

this指针是地址,它的作用为作为形参,其存储在栈空间上,但是有的编译器比如VS可能会存储在寄存器中,这样访问的时候比较快。

3.4this指针可以为空吗?

可以。在我们之前的理解中,认为所有的空指针配合上解引用操作符都会崩毁,但是在一些情况下并非如此。

观察下面两段代码:
代码一:

class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;(*p).PrintA();p->Print();return 0;
}
这段代码可以正确打印出结果,程序不会崩溃。

代码二:

class A
{
public:void PrintA(){cout << _a << endl;}
private:int _a;
};
int main()
{A* p = nullptr;(*p).PrintA();p->PrintA();return 0;
}
这里仅仅和上面有打印函数的差别,但是程序会崩溃。

首先,有*或者->都不一定是解引用,解引用以后要有实际意义编译器才会解引用。
我们上面的(*p)和->本质是给成员函数传递this指针,确定是哪个对象调用的this指针,this指针作为形参传递过去。

代码一:我们只是将空的this指针传递过去,在函数内部并没有解引用,因此程序正常运行。

代码二:我们将空的this指针传递之后,由于需要打印成员变量,因此必须对于this指针解引用从而找到该变量,进而造成空指针的解引用。

汇编观察:
在这里插入图片描述

我们通过反汇编也可以观察到,在底层并没有先对指针解引用,而是通过p去调用对应的Print函数。

以上是本次所有内容,谢谢观看。

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

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

相关文章

如何安全地添加液氮到液氮罐中

液氮是一种极低温的液体&#xff0c;它在许多领域广泛应用&#xff0c;但在处理液氮时需谨慎小心。添加液氮到液氮罐中是一个常见的操作&#xff0c;需要遵循一些安全准则以确保操作人员的安全和设备的完整性。 选择合适的液氮容器 选用专业设计用于存储液氮的容器至关重要。…

UEDITOR WORD图片转存交互

1.下载示例&#xff1a; Word一键粘贴控件-示例-泽优软件 2.复制WordPaster插件目录 3.引入插件文件 注意&#xff1a;不要重复引入jquery&#xff0c;如果您的项目已经引入了jq&#xff0c;则不用再引入jq-1.4 4.在工具栏中增加插件按钮 6.初始化控件 注意&#xff1a; 1.如…

专业文件翻译,笔译翻译公司推荐!

在全球化的大潮中&#xff0c;文件翻译已然成为了商业、法律、科技、文化等诸多领域的核心纽带。特别是在商业交往、合同签订、技术交流等方面&#xff0c;一份高质量的译文往往关乎着合作的成败。而在这其中&#xff0c;专业的文件翻译公司更是扮演着至关重要的角色。它们不仅…

C语言例4-33:求调和级数中第多少项的值大于10

代码如下&#xff1a; //求调和级数中第多少项的值大于10 //调和级数的第n项为11/21/3...1/n #include<stdio.h> #define LIMIT 10 int main(void) {int n1;float sum0.0;for(;;) //死循环&#xff0c;或者while&#xff08;1&#xff09;{sumsum1.0/n;if(sum&g…

软件测试工作规范、流程规范

1. 制定规则 为了规范测试工作、减少开发与测试之前的沟通成本、保证项目进度、提高软件质量&#xff0c;测试组起草了这份软件测试工作规范。 1.1. 编码规范 软件程序开发需要遵守编码规范&#xff0c;一是可以减少代码的维护成本&#xff0c;提高开发工作效率&#xff1b;…

Chrome 插件 storage API 解析

Chrome.storage API 解析 使用 chrome.storage API 存储、检索和跟踪用户数据的更改 一、各模块中的 chrome.storage 内容 1. Service worker 中 runtime 内容 2. Action 中 runtime 内容 3. Content 中 runtime 内容 二、权限&#xff08;Permissions&#xff09; 如果需使…

2024 年学习 AI 路线图

2024 年学习 AI 路线图 一、数学二、工具2.1 Python2.2 PyTorch 三、机器学习3.1 从头开始编写3.2 参加比赛3.3 做副业项目3.4 部署模型3.5 补充材料 四、深度学习4.1 fast.ai4.2 多参加一些比赛4.3 论文实现4.4 计算机视觉4.5 强化学习4.6 自然语言处理 五、大型语言模型5.1 观…

SpringBoot国际化配置流程(超详细)

前言 最新第一次在做SpringBoot的国际化&#xff0c;网上搜了很多相关的资料&#xff0c;都是一些简单的使用例子&#xff0c;达不到在实际项目中使用的要求&#xff0c;因此本次将结合查询的资料以及自己的实践整理出SpringBoot配置国际化的流程。 SpringBoot国际化 "i…

爱思助手验机不靠谱?

1.骗子只能骗的一种人就是有点懂 因为完全不懂的不会感兴趣 骗不到 太懂的人 基本属于猴精的人 你骗不到 2. 3.基本做的是翻新机 维修过的 4。转载 爱思助手验机不靠谱&#xff1f;“报告全绿”已成奸商的阴谋 - 知乎

单片机通俗一点讲究竟是个什么东西?

单片机就是一个微型电脑&#xff0c;它是靠程序工作的&#xff0c;并且可以修改。通过不同的程序实现不同的功能。在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信…

智慧公厕四大核心能力,赋能城市公共厕所智能化升级

公共厕所是城市基础设施中不可或缺的一部分&#xff0c;但由于传统的公共厕所在建设与规划上&#xff0c;存在一定的局限性&#xff0c;导致环境卫生差、管理难度大、使用体验不佳等问题&#xff0c;给市民带来了很多不便。而智慧公厕作为城市智能化建设的重要组成部分&#xf…

2024年阿里云服务器8核16G配置活动价格分享,最低仅需1803.17元1年

阿里云服务器8核16G配置2024年活动价格是多少&#xff1f;具体配置还需要看想要购买的云服务器实例规格和配置及带宽大小&#xff0c;目前在阿里云2024年活动中&#xff0c;8核16G配置价格最低的是通用算力型u1实例&#xff0c;价格只要1803.17元1年&#xff0c;除此之外&#…

JAVA------基础篇

java基础 1.JDK JDK :java development kit JRE&#xff1a;java runtime environment JDK包含JRE java跨平台&#xff1a;因为java程序运行依赖虚拟机&#xff0c;虚拟机需要有对应操作系统的版本&#xff0c;而jre中有虚拟机。 当你想要在Linux系统下运行&#xff0c;则需要…

轻松管理你的热点函数!

之前&#xff0c;我们介绍了卡顿分析下的卡顿帧汇总功能&#xff0c;以便开发者能够更精准地定位和归因项目的卡顿现象。本周&#xff0c;我们将继续介绍本次版本更新的新功能&#xff0c;从函数CPU耗时、资源管理等角度&#xff0c;帮助开发者更细致地洞察项目性能问题&#x…

TCPView下载安装使用教程(图文教程)超详细

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;更多干货&#xff0c;请关注专栏《网络安全自学教程》 TCPView是微软提供的一款「查看网络连接」和进程的工具&#xff0c;常用来查看电脑上的TCP/UDP连接…

明渠流量监测站—实时监测明渠中水流流量和水位

TH-ML2明渠流量监测站是一种专门用于实时监测明渠中水流流量和水位等参数的设施。它通常设置在河流、渠道或其他开放水流明渠中&#xff0c;旨在收集、记录和汇总水流数据&#xff0c;为水利管理部门、研究机构和其他相关方提供决策支持。 明渠流量监测站的工作涉及多个关键步骤…

Go——map操作及原理

一.map介绍和使用 map是一种无序的基于key-value的数据结构&#xff0c;Go语言的map是引用类型&#xff0c;必须初始化才可以使用。 1. 定义 Go语言中&#xff0c;map类型语法如下&#xff1a; map[KeyType]ValueType KeyType表示键类型ValueType表示值类型 map类型的变量默认…

Altair-一个被名字耽误的超强交互式可视化库

今天的推文我们介绍一个功能很强,但知名度不如Matplotlib、pyecharts等静态或者交互式可视化库-Altair。Altair是基于Vega和Vega-Lite的Python数据统计可视化库&#xff0c;其优秀的交互、数据统计功能和清新的配色&#xff0c;很难让人用过就忘记(唯一不好就是名字太难记啦!)。…

2024年的黑马项目,在视频号上开小店,这个机会不容错过!

大家好&#xff0c;我是电商小布。 在互联网的快速发展下&#xff0c;电商这一行可以说是展现出来了前所未有的生机。 也造就了越来越多项目的产生&#xff0c;视频号小店就是其中之一。 有人说&#xff0c;就今年的各大项目情况来看&#xff0c;视频号小店无疑是最大的黑马…

jsp将一个文本输入框改成下拉单选框,选项为字典表配置,通过后端查询

一&#xff0c;业务场景&#xff1a; 一个人员信息管理页面&#xff0c;原来有个最高学历是文本输入框&#xff0c;可以随意填写&#xff0c;现在业务想改成下拉单选框进行规范化&#xff0c;在专科及以下、本科、研究生三个选项中选择&#xff1b; 二&#xff0c;需要解决问…