C++的类与对象(二)

news2024/9/24 7:21:32

目录

结构体内存对其规则

相关面试题

this指针

相关面试题


结构体内存对其规则

1、第一个成员在与结构体偏移量为0的地址处

2、其它成员变量要对齐到某个数字(对齐数)的整数倍的地址处

对齐数 = 编译器默认对齐数与该成员大小的较小值(vs中默认为8)

3、结构体总大小为:最大对齐数的整数倍

4、如果是嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有结构体的最大对齐数的整数倍

相关面试题

1、内存对齐会导致空间闲置,那为什么要进行内存对齐?

①提高读取效率

②硬件(地址总线)规定内存一次读取4(32根线)或8(64根线)个字节

③如果不内存对齐可能会对同一块内存需要多次读取

采用内存对齐:一次读取4个字节,先读取一个字节的i后将其它三个没用的字节丢掉,然后继续读取四个字节的a

不采用内存对齐:一次读取4个字节,先读取i的一个字节和a的前三个字节后将a的前三个字节丢掉,然后继续读取a剩余的一个字节,最后将那三个字节和最后一个字节组合才能得到a,麻烦

2、如何让结构体按照指定的对齐参数进行对齐?

答:#pragma pack(指定对齐数) 

this指针

#include <iostream>
using namespace std;

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, 27);
	d2.Init(2022, 2, 28);
	d1.Print();
	d2.Print();
	return 0;
}

        Data类中有Init和Print两个成员函数,不论是d1还是d2它们调用的Init函数和Print函数在实现上是一样的,为什么编译器可以做到d1调用Print函数就会打印d1对象的成员变量组成的日期,d2调用Print函数就会打印d2对象的成员变量组成的日期?

        这是因为每一个成员函数都会多一个叫this的指针,它是成员函数的第一个参数,那么对于Print函数其实我们可以将其理解成:

void Print(Data* this)
{
	cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
}
void Print(Data* this,int year,int month,int day)
{
	_year = year;    //实际上就是this->_year = year;
    _month = month;  //this->_month = month;
    _day = day;      //this->_day = day;
}    

在调用的时候,编译器也会将其处理成这样的形式:

d1.Print(&d1);
d2.Print(&d2);

将调用对象的地址当作实参传递给函数

传入谁的地址就访问谁

注意事项:

1、this指针实际上的格式是:类名* const this,即指向的内容可以更改,但本身不能修改

2、形参和实参位置不能显式的写this指针

3、函数内部可以使用this指针

相关面试题

1、this指针存在哪里?堆?栈?静态区?常量区?对象里面?

对象里面(×):计算类的大小时,有三个整型成员变量的类的大小是12字节,如果this指针存放在对象中类的大小应该是大于12的

常量区×被const修饰的变量不会存放在常量区,const char*p = "xzxxxxxx"中,p作为指针是存放在栈上的,"xzxxxxxx"是被存放在常量区的,这段代码的意思是将字符串存储的地址给了p,打印p显示出来的就是常量区的地址,被const修饰的变量i的地址和变量j的地址相近,由于变量j是存放在栈上的,可以推出被const修饰的变量i也是存放在栈上的

不加void*强转,p打印出来的就是字符串"xzxxxxxx" ,强转后打印的是字符串的地址

静态区(×):被static修饰的变量和全局变量才存放在静态区

堆(×):calloc、malloc、realloc开辟的才在堆上

栈(): this指针是成员函数的形参,而形参跟指针一样是存放在栈上的

有些编译器(比如vs)会将this指针存放在寄存器上,频繁访问this指针时效率更高

~over~

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

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

相关文章

学习记录12-单片机代码几种常见命名规则

良好的编程习惯&#xff0c;决定了今后代码的质量。 有很多人平时不注意自己的代码规范&#xff0c;函数和变量命命随心所欲&#xff0c;造成一个星期就不认识自己的代码&#xff0c;于是今天就来分享一点关于软件代码常见的几种命名规则。 匈牙利命名法 匈牙利命名法广泛应用…

RBAC实战

一、权限控制概述 1.1、访问控制目的 在实际的组织中&#xff0c;为了完成组织的业务工作&#xff0c;需要在组织内部设置不同的职位&#xff0c;职位既表示一种业务分工&#xff0c;又表示一种责任与权利。根据业务分工的需要&#xff0c;职位被划分给不同群体&#xff0c;各…

C++:Vector的模拟实现

创作不易&#xff0c;感谢三连 &#xff01;&#xff01; 一&#xff0c;前言 在学习string类的时候&#xff0c;我们可能会发现遍历的话下标访问特别香&#xff0c;比迭代器用的舒服&#xff0c;但是下标其实只能是支持连续的空间&#xff0c;他的使用是非常具有局限性的&am…

迷不迷糊?前后端、三层架构和MVC傻傻分不清

现在的项目都讲究前后端分离&#xff0c;那到底什么是前后端&#xff0c;前后端和以前的MVC以及三层架构啥关系呢&#xff1f;今天就这个问题展开一下&#xff0c;方面后面的学习&#xff0c;因为前面讲的jsp、servlet和javabean根据实例&#xff0c;基本上有一个框架的理解了&…

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘…

【如何在Docker中,修改已经挂载的卷(Volume)】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 提示&#xff1a;添加投票&#xff01;&#xff01;&#xff01; 目录 简述概要知识图谱 简述概要 如何在Docker中&#xff0c;修改已经挂载的卷&#xff08;Volume&#xff09; 知识图谱 在Docker中&#xff0c;修改已经挂载…

消息队列-kafka-消息发送流程(源码跟踪)

官方网址 源码&#xff1a;https://kafka.apache.org/downloads 快速开始&#xff1a;https://kafka.apache.org/documentation/#gettingStarted springcloud整合 发送消息流程 主线程&#xff1a;主线程只负责组织消息&#xff0c;如果是同步发送会阻塞&#xff0c;如果是异…

安装Proxmox VE虚拟机平台

PVE是专业的虚拟机平台&#xff0c;可以利用它安装操作系统&#xff0c;如&#xff1a;Win、Linux、Mac、群晖等。 1. 下载镜像 访问PVE官网&#xff0c;下载最新的PVE镜像。 https://www.proxmox.com/en/downloads 2. 下载balenaEtcher balenaEtcher用于将镜像文件&#…

【Vue3】3-6 : 仿ElementPlus框架的el-button按钮组件实

文章目录 前言 本节内容实现需求完整代码如下&#xff1a; 前言 上节,我们学习了 slot插槽&#xff0c;组件内容的分发处理 本节内容 本小节利用前面学习的组件通信知识&#xff0c;来完成一个仿Element Plus框架的el-button按钮组件实现。 仿造的地址&#xff1a;uhttps://…

docker pull 拉取失败,设置docker国内镜像

遇到的问题 最近在拉取nginx时&#xff0c;显示如下错误&#xff1a;Error response from daemon: Get “https://registry-1.docker.io/v2/”: net/http: request canceled (Client.Timeout exceeded while awaiting headers)。 这个的问题是拉取镜像超时&#xff0c;通过检索…

基于Golang客户端实现Nacos服务注册发现和配置管理

基于Golang客户端实现Nacos服务注册发现和配置管理 背景 最近需要把Golang实现的一个web项目集成到基于Spring Cloud Alibaba的微服务体系中&#xff0c;走Spring Cloud Gateway网关路由实现统一的鉴权入口。 软件版本 组件名称组件版本Nacos2.2.0Go1.21.0Ginv1.9.1Nacos-s…

项目部署发布

目录 上传数据库 修改代码中的数据源配置 修改配置文件中的日志级别和日志目录 打包程序 ​编辑​编辑 上传程序 查看进程是否在运行 以及端口 云服务器开放端口(项目所需要的端口) 上传数据库 通过xshell控制服务器 创建目录 mkdir bit_forum 然后进入该目录 查看路…

【AI+CAD】(一)ezdxf 解析DXF文件

DXF文件格式理解 DXF文件格式是矢量图形文件格式&#xff0c;其详细说明了如何表示不同的图形元素。 DXF是一个矢量图形文件&#xff0c;它捕获CAD图形的所有元素&#xff0c;例如文本&#xff0c;线条和形状。更重要的是&#xff0c;DXF是用于在CAD应用程序之间传输数据的图形…

Java日志框架的纷争演进与传奇故事

在Java的世界里&#xff0c;日志记录是每一个应用不可或缺的部分。它帮助开发者了解应用的运行状态、调试问题、监控性能等。而在这背后&#xff0c;是一系列日志框架的发展与演进。今天&#xff0c;就让我们一起回顾这些日志框架的历史&#xff0c;探寻它们背后的故事。 1. Lo…

分布式数据库中全局自增序列的实现

自增序列广泛使用于数据库的开发和设计中&#xff0c;用于生产唯一主键、日志流水号等唯一ID的场景。传统数据库中使用Sequence和自增列的方式实现自增序列的功能&#xff0c;在分布式数据库中兼容Oracle和MySQL等传统数据库语法&#xff0c;也是基于Sequence和自增列的方式实现…

使用Visual Studio 2022 创建lib和dll并使用

概述&#xff1a;对于一个经常写javaWeb的人来说,使用Visual Studio似乎没什么必要&#xff0c;但是对于使用ffi的人来说&#xff0c;使用c或c编译器&#xff0c;似乎是必不可少的&#xff0c;下面我将讲述如何用Visual Studio 2022 来创建lib和dll&#xff0c;并使用。 静态库…

UNIapp实现局域网内在线升级

首先是UNIapp 生成apk 用Hbuilder 进行打包 可以从网站https://www.yunedit.com/reg?gotocert 使用自有证书&#xff0c;目测比直接使用云证书要快一些。 发布apk 网站 用IIS发布即可 注意事项中记录如下内容 第一、需要在 iis 的MiMe 中添加apk 的格式&#xff0c;否则无法…

Java架构之路-架构应全面了解的技术栈和工作域

有时候我在想这么简单简单的东西&#xff0c;怎么那么难以贯通。比如作为一个架构师可能涉及的不单单是技术架构&#xff0c;还包含了项目管理&#xff0c;一套完整的技术架构也就那么几个技术栈&#xff0c;只要花点心思&#xff0c;不断的往里面憨实&#xff0c;总会学的会&a…

UE4升级UE5 蓝图节点变更汇总(4.26/27-5.2/5.3)

一、删除部分 Ploygon Editing删除 Polygon Editing这个在4.26、4.27中的插件&#xff0c;在5.1后彻底失效。 相关的蓝图&#xff0c;如编辑器蓝图 Generate mapping UVs等&#xff0c;均失效。 如需相关功能&#xff0c;请改成Dynamic Mesh下的方法。 GetSupportedClass删…

在K8S集群中部署SkyWalking

1. 环境准备 K8S 集群kubectlhelm 2. 为什么要部署SkyWalking&#xff1f; 我也不道啊&#xff0c;老板说要咱就得上啊。咦&#xff0c;好像可以看到服务的各项指标&#xff0c;像SLA&#xff0c;Apdex这些&#xff0c;主要是能够进行请求的链路追踪&#xff0c;bug排查的利…