C++基础之类二(类的实例化,This指针)

目录

类的实例化

概念

类和对象的区别

计算一个类

不同的类的大小

类的存储模型

内存对齐

让结构体按照指定的默认对齐数进行对齐

确定偏移量

大小端字节序

This指针

概念

this指针四大特性

一些关于this指针的问题

总结


之前学过了类,但在编程中类无法直接使用,需要将类进行实例化后才能使用,现在就来看看类的实例化是什么?

类的实例化

概念

用类创建对象的过程叫做类的实例化,类可以抽象为虚拟的图纸,对象是按照图纸创建好的类,创建的过程就是类的实例化。

类和对象的区别

对象是按照类创建的实体,所以对象的功能是按照类的设计,但两者之间还有很多不同点

对象
虚拟实体
不占用内存空间占用内存空间
不参与程序运行参与程序运行
不存在生命周期生命周期具体看所在是全局域还是局部域

计算一个类

不同的类的大小

有内容的类:

看一下下面的代码,它的大小应该是多少?

class Bit
{
public:int A(char x, int y){return (a + x) - (b + y);}
private:char a;int b;
};

看一下其中的元素,一个成员函数,两个成员变量,32位系统的情况下,成员函数的地址是4个字节,char类型是1字节,int类型是4字节,按照内存对齐的规则,这个类应该是12字节的大小,但实际的运算结果是8字节。

无内容的类:

再看一下下面的代码,它的大小又是多少?

class Bit
{};

什么都没有,那它的字节应该是0,但实际上它的字节数是1。

类的计算结果这么奇怪,中间起决定性因素的是类的存储模型 

类的存储模型

C++之父在创建类的模型是充分考虑了类被实例化的情况,所以设计了一个极为简单的存储模型,那就是将类中的成员函数放到常量区,而类中只保留成员变量。

下面的图表是一个类,在实例化后,对象中的成员函数被放到一个公共区域中,对象中只存放成员变量,所以计算对象的结果为8个字节,同时这个特性也被保留在了类中,所以sizeof(Bit)(注意这里计算的只是类,不是对象)得到的结果也是8个字节。

对于空类,空类没有内容,但考虑到类会实例化为多个对象,所以会分配给类1个字节作为占位符,占位符中部存储有效内容,仅仅表示类的存在。

类中的成员函数保存到常量区,不用担心找不到,是因为整个过程由编译器完成。

内存对齐

内存对齐的概念

现代计算机都是按照Byte作为划分单位的,从理论上讲,访问任何类型的变量都可以从任意的位置开始,但在实际操作的过程中,特殊类型的变量需要放在特殊的位置,这句需要特殊类型的变量按照一定的规则存放在内存中,而不是一个接一个的放在一起,这就是内存对齐。

为什么需要内存对齐

内存对齐主要有两个原因:

一是不同架构的cpu对数据存储及读取的方式不同,在某些CPU上任意位置读取可能会发生错误。

二是为了提升效率,假设一个32位系统下的int变量,它占据4个字节,一些平台读取是从偶地址开始读取,int变量放在偶地址开始时,只要一个读周期就能完成数据读取,但放在奇地址需要两个读周期,才能将数据读完,之后还要将数据高低字节拼凑才能得到完整的数据。

内存对齐的规则

内存对齐一共四点规则

一、特殊变量(这里指结构体,类,联合体等自定义变量)放入内存时,第一个数据存放在标记为offset为0的地址,之后的数据按照数据的大小或者数据的子数据(结构体中嵌套结构)的大小的整数倍。

以该类为例class  BIT
{char a;int b;}

 

在32位系统下,char类型变量a占据1个字节,a放在偏移量为0的位置,int类型变量b占据4个字节,按照规则将放在数据的整数倍的位置,所以放在偏移量为4的位置。

二、自定义类型变量,按照其最大子类型的成员作为标准,从最大成员的整数倍开始储存。

看一下这个类,类Y中嵌套了类Xclass X
{int a;char b;double c;
};class Y
{char i;int j;short d;X k;
};

 在偏移量为0的位置放入i,在偏移量为4的位置放入4,偏移量为8的位置放入d,此时的偏移量为10变量K中最大的类型是double占据8个字节,10不能整除8,偏移量后移,直到偏移量为16时,放入a,之后放入b,在偏移量为24的位置放入c,最终大小为32个字节。

三、类的总大小是最大成员类型的整数倍,如果不是,需要在成员后继续填补,直到达到最大成员类型的整数倍。

看一下下面的代码class BIT
{int a;char b;
}

 这个类中数据占据5个字节,数据之间没有填补,但类的总大小是8个字节,按照规则三,类的大小是最大元素的整数倍,最大类型是4个字节,不能被5整除,所以在变量b之后还要继续填补三个字节。

四、如果程序中有#pragma pack(n)定义了字节,那么编译器会用n与数据大小做比较,两者中选择小的为偏移量。

类的大小的影响因素

一,系统是32位还是64位

数据类型32位64位
char11
char*48
short int22
int44
unsigned int44
float44
double88
long48
long long88
unsigned long48

二、成员变量的排列顺序 

class  A
{char a;char b;int  c;
}class  B
{char a;int  c;char b;
}

 同样的数据,顺序不同A的大小为8字节,B的大小为12字节。

让结构体按照指定的默认对齐数进行对齐

VS中,可以通过#pragma pack(n)预处理指令定义字节。

确定偏移量
大小端字节序

内存中每个字节作为一个存储单元对应一个唯一的编号,这个编号就是地址也就是指针,地址分为低地址与高地址,编号小的为低地址,大的为高地址。

数据的值分为高位和低位

大端存储模式:高位值放入低地址位

小端存储模式:低位值放入低地址位

当然需要注意的是,如果多个数据  0X12345678 0X11223344,不同的数据存储与大小端没有关系。

不同的处理器,大小端字节序不同,判断如何判断采用的是大端还是小端?

看一下下面的图不难发现,将int类型的1放入内存,只需要提取内存中0X00000000的数据,就可以判断是大端还是小端。

This指针

概念

先看一下下面代码:

class Date
{
public:void Init(int year, int month, int day);
private:int _year;int _month;int _day;
};
void Date::Init(int year, int month, int day)
{_year = year;_month = month;_day = day;printf("%d-%d-%d\n", _year, _month, _day);
}
int main()
{Date A;Date B;A.Init(2023, 10, 12);B.Init(2022, 10, 9);system("pause");return 0;
}

类中的函数存在于(常量区)只有一份,上面的代码中对象A和B分别调用了Init函数,输出的结果不同,这是因为在类中存在一个隐形的指针,this指针。

为了让成员函数知道操作哪一个对象的成员变量,C++增加了一个隐藏的指针this指针,当该指针指向了某个对象时,通过成员函数操作的内容就是该类的成员变量。 

this指针四大特性

一、成员函数内部使用

this指针只能在成员函数内部使用,C++定义时将this指针默认定义成了成员函数的第一个形参。

void Date::Init(Date* this,int year, int month, int day)
{this->_year = year;this->_month = month;this->_day = day;printf("%d-%d-%d\n", _year, _month, _day);
}

 本质上this指针只是个形参,接收实参(类的地址),完成相应的操作。

二、隐式指针

this指针作为形参不能显式(手动)写,C++自动完成的,一般通过ecx寄存器自动完成,实际在成员函数中可以在成员变量前填写this指针,不过没有必要。

三、类型

为了保护this指针的内容,C++定义它的类型为  类类型*const this,const修饰this指针,this指针的值不可被修改。

const int *pa = &a;
int const *pb = &a;
int *const pc = &a;*pa = 20; (不可修改指针指向的变量的值)
*pb = 30; (不可修改指针指向的变量的值)
*pc = 40; (可修改指针指向的变量的值)pa = &b; (可修改指针的值)
pb = &b; (可修改指针的值)
pc = &b; (不可修改指针的值)

四、存储位置

每一个对象,都有this指针,实际上就是它的地址,一般情况下this指针存储的在栈区中,VS编译器this指针存在ecx寄存器中。

一些关于this指针的问题

1、this指针的问题,下面两个题分别选择什么

题目一的选项是C、正常运行,p的指针是nullptr,print(p)调用后不发生解引用,直接打印print(),不发生解引用编译运行时不会崩溃。

题目二的选项时B、运行崩溃,P的指针是在传递后在cout<<this->_a<<endl处,发生了解引用,所以程序运行崩溃。

二、this指针放在哪里

this指针放在栈区中,VS编译器下this指针存放在ecx编译器中。

三、this指针可以为空吗

this指针可以为空,在不解引用时能正常使用,解引用时程序会崩溃。

总结

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

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

相关文章

鼎鑫鸿鄴利用国家的策略优势和满足全球需求并驾齐驱

随着全球对可再生能源的需求不断增长&#xff0c;鼎鑫鸿鄴新能源科技有限公司正充分利用中国政府的策略优势&#xff0c;积极满足全球能源使用需求&#xff0c;并在可再生能源领域崭露头角。中国属于全球最大的太阳能市场&#xff0c;在技术研发、产能建设和市场规模等方面拥有…

[Spring] SpringMVC 简介(一)

目录 一、SpringMVC 简介 1、什么是 MVC 2、什么是 SpringMVC 3、SpringMVC 实现原理 4、SpringMVC 的特点 二、简单案例 1、引入依赖 2、在 web.xml 中配置前端控制器 DispatcherServlet 3、创建 SpringMVC 的配置文件 4、创建请求控制器 5、测试页面 6、访问不到 …

数学建模——人工神经网络模型

一、人工神经网络简介 1、神经网络起源与应用 1943年心理学家McCulloch和数学家Pitts提出神经元生物数学模型&#xff08;M-P模型&#xff09;&#xff0c;后来人工神经网络(Artifical Neural Network,ANN)是在生物神经网络(Biological Neural Network,BNN)基础上发展起来的&a…

MobaXterm使sftp目录与cmd目录同步

MobaXterm使sftp目录与cmd目录同步 创建session时在ssh菜单栏中选择Advanced SSH settings其中SSH-browser type 选择SCP&#xff08;enhanced speed&#xff09; 勾选Follow SSH path

TS(五):装饰器

装饰器 启用装饰器支持类装饰器定义并使用装饰器对比不使用装饰器装饰器叠加实现消息提示统一响应装饰器工厂 方法装饰器登录状态验证数据请求 属性装饰器大小写转换 元数据安装依赖基础用法 参数装饰器验证参数是否为必填项 启用装饰器支持 修改 tsconfig.json {"exper…

和鲸 ModelWhale 与华为 OceanStor 2910 计算型存储完成兼容性测试

数智化时代&#xff0c;数据总量的爆炸性增长伴随着人工智能、云计算等技术的发展&#xff0c;加速催化了公众对于数据存储与应用的多元化需求。同时&#xff0c;数据也是重要的基础资源和战略资源&#xff0c;需要严格保障其安全性、完整性。搭建国产数据基础设施底座&#xf…

信息系统项目管理师第四版学习笔记——高级项目管理

项目集管理 项目集管理角色和职责 在项目集管理中涉及的相关角色主要包括&#xff1a;项目集发起人、项目集指导委员会、项目集经理、其他影响项目集的干系人。 项目集发起人和收益人是负责承诺将组织的资源应用于项目集&#xff0c;并致力于使项目集取得成功的人。 项目集…

实验2.1.2 交换机的常用配置

项目2 交换技术的位置 活动2 交换机的常用配置 一、具体要求&#xff1a; &#xff08;1&#xff09;添加1台计算机&#xff0c;将标签名更改为PC1。 &#xff08;2&#xff09;添加1台S3700-26C-HI交换机&#xff0c;标签名为SWA&#xff0c;将交换机的名称设置为SWA。 &am…

华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的 Linux 磁盘目录分析神器 ncdu

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之硬件参数评测&#xff1a;华为云云耀云服务器下的 Linux 磁盘目录分析神器 ncdu 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器…

关键词搜索快手商品列表数据,快手商品列表数据接口,快手API接口

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取快手网站上的商品页面。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#xff0c;快手网站…

Android Studio: unrecognized Attribute name MODULE

错误完整代码&#xff1a; &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd; (1.8.0_291) &#xfffd;г&#xfffd;&#xfffd;&#xfffd;&#xfffd;쳣&#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xff…

17个开源的Go语言博客和CMS解决方案

Go语言&#xff0c;也称为Golang&#xff0c;是一种为构建高效、可靠和可扩展软件而设计的开源编程语言。它于2007年在Google开发&#xff0c;现在广泛用于开发Web应用程序、网络工具和系统软件。 为什么使用基于Go的CMS解决方案&#xff1f; 这些优势使Go成为开发可扩展、高…

ansible的介绍安装与模块

目录 一、ansible简介 二、ansible特点 三、Ansible核心组件与工作原理 1、核心组件 2、工作原理 四、ansible的安装 五、ansible 命令行模块 1&#xff0e;command 模块 2&#xff0e;shell 模块 3&#xff0e;cron 模块 4&#xff0e;user 模块 5&#xff0e;group 模…

如何在Synology群晖DSM中为不同用户设置权限

在使用Synology 群晖NAS时往往需要为不同的用户添加各自的账户权限&#xff0c;我们希望他们可以自由使用自己的主文件夹&#xff0c;但不要互相看到别人的主文件夹&#xff0c;更不要互相浏览别人主文件夹下的内容&#xff0c;应该怎么设置呢&#xff1f;DSM系统中有完善的文件…

阿里云10M公网收费价格表(一年和1个月报价)

阿里云服务器10M带宽收费价格表&#xff0c;阿里云服务器上海地域10M带宽一年优惠价格5355元&#xff0c;10M带宽一个月525元&#xff0c;地域不同带宽价格不同&#xff0c;阿里云服务器网以华东1&#xff08;上海&#xff09;地域为例&#xff0c;5M及5M以下带宽按照23元一个月…

UI设计师岗位的基本职责八篇

UI设计师岗位的基本职责1 职责&#xff1a; 1. 负责公司互联网产品app、web、h5等的用户界面设计工作; 2. 负责运营活动相关的平面及视频设计支持; 3. 负责完成产品相关的界面、图标、动画等的图形界面设计&#xff0c;并参与制定、编写产品视觉设计规范文档; 4. 整理和分…

多服务器云探针源码(服务器云监控)/多服务器多节点_云监控程序python源码

源码简介&#xff1a; 多服务器云探针源码(服务器云监控),支持python多服务器多节点&#xff0c;云监控程序源码。它是一款很实用的云探针和服务器云监控程序源码。使用它可以帮助管理员能够快速监控和管理各种服务器和节点&#xff0c;实用性强。 源码链接&#xff1a; 网盘…

XXE漏洞复现实操

文章目录 一、漏洞原理二、验证payload三、没有回显时的验证四、漏洞特征五、读取文件六、Base64加密读取七、端口检测八、使用php检测端口九、dtd外部实体读取文件十、Xxe漏洞防御 一、漏洞原理 (1)XXE漏洞全称XML External Entity Injection&#xff0c;即xmI外部实体注入漏…

CTF/AWD竞赛标准参考书+实战指南:《AWD特训营》

文章目录 前言内容简介读者对象目录介绍 前言 随着网络安全问题日益凸显&#xff0c;国家对网络安全人才的需求持续增长&#xff0c;其中&#xff0c;网络安全竞赛在国家以及企业的人才培养和选拔中扮演着至关重要的角色。 在数字化时代&#xff0c;企业为了应对日益增长的攻…

【智能家居项目】裸机版本——网卡设备接入输入子系统 | 业务子系统 | 整体效果展示

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f95e;网卡设备接入输入子系统&#x1f354;测试 &#x1f95e;业务子系统&#…