从CPU的视角看C++的构造函数和this指针

从汇编角度,清晰的去看构造函数和this指针到底是个什么东西呢?也许可以解决你的一点小疑问

首先写一个很简单的代码demo:

class A{
public:
    int a;
    A(){
        ;
    }
    void seta(int _a){
        a=_a;
    }
    A* getA(){
        return this;
    }
};

int fun1(int px){
    return px;
}

int main(){
    A aa;
    aa.seta(8); 
    aa.getA();
}

mov rbp, rsp:设置新的基址指针,指向当前栈帧。

mov QWORD PTR [rbp-8], rdi:将 this 指针(存储在 rdi 中)保存到栈上。

在seta中的部分汇编:

mov rax, QWORD PTR [rbp-8]:将 this 指针的值加载到 rax 中。

mov DWORD PTR [rax], edx:将 edx(即 _a 的值)存储到 this->a 中。

我们从类成员函数和构造函数中都能看到 两句关于参数的汇编,同理普通函数中px参数也有着相同的汇编,那么很显然,对于cpu而言,this指针仅仅是一个参数而已。C++语法糖对于this做了隐藏处理,因此我们在使用的时候才会无感。

而这个有这个this往往可以认为函数的完整使用是这样:

    A aa;
    aa.seta(8); 


====
    A::seta(&aa,8) 当然这么调用是错误的,看着很像类静态函数

this 指针的创建

  • 函数调用前创建:当成员函数被调用时,this 指针在调用成员函数之前被设置为当前对象的地址。也就是说,在成员函数执行之前,this 指针已经被创建并指向调用该函数的对象。

this 指针的销毁

  • 函数调用结束后销毁:在成员函数执行完毕并返回后,this 指针的生命周期就结束了。因为 this 只是一个指向对象的指针,当函数返回时,不再需要这个指针,函数调用上下文会自动清理这个隐式参数。

 

学习C++的友友大概率会知道这么一句话:静态成员函数不属于类的某个具体对象,而是属于整个类。这意味着静态成员函数不能访问非静态成员变量和成员函数,因为它们没有 this 指针。针对这句话我们也可以通过cpu视角进行观察

而this 指针的存在条件

  • 对象实例调用:只有当对象实例调用非静态成员函数时,this 指针才会被传递给该函数。
  • 隐式参数:在非静态成员函数内部,编译器会自动添加一个隐式的 this 指针参数,用于引用调用该函数的对象

观察上图,你就会看到 静态成员函数中没有this指针,即也就没法去调用相关的成员函数和数据,如果我们想要通过静态成员函数去调用对象相关的数据,可以通过黄色框框的这种写法。你会发现这种写法的汇编同成员函数的汇编相同,也就是说this存的就是传递进去的这个对象的地址。

也就有了成员函数的完整版应该是:void setp(A* this,int p);是不是看着参数和示例第二个静态成员函数一样~

cpu眼中构造函数与普通函数没有任何区别:

通过上面的汇编也能看明白,构造含有this指针,且对于cpu来说他与普通函数是相同的

派生类构造函数总会调用基类的构造函数

  • mov QWORD PTR [rbp-8], rdi:将 this 指针(在 rdi 中)保存到局部变量中。
  • mov rax, QWORD PTR [rbp-8]:将 this 指针从局部变量中加载到 rax 中。
  • mov rdi, rax:将 this 指针(现在在 rax 中)移动到 rdi 中,以便调用基类构造函数时使用。
  • call A::A() [base object constructor]:调用基类 A 的构造函数。此时,this 指针指向 B 对象,但调用的是 A 的构造函数,因此它会正确初始化 A 的部分。
  • mov rax, QWORD PTR [rbp-8]:再次将 this 指针从局部变量中加载到 rax 中。
  • mov DWORD PTR [rax+4], 1:将 1 赋值给 this->a。这里的 [rax+4] 指的是b 位于对象内偏移量 4 的位置。 (因为B继承A,B所以内存结构上,前四个字节是A.a ,然后才是B.a ,所以是移动到偏移4位置之后在赋值)

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全新桌面编辑器

目录 前言 一、链接 ONLYOFFICE 8.1版本 官网下载链接: ONLYOFFICE 在线工具: 下载版本推荐: 二、使用体验 1. 界面设计: 2. 文档编辑功能: 3. 电子表格功能: 4. 演示文稿功能: 5.PDF编…

python-开关灯(赛氪OJ)

[题目描述] 假设有 N 盏灯(N 为不大于 5000 的正整数),从 1 到到 N 按顺序依次编号,初始时全部处于开启状态;第一个人( 1 号)将灯全部关闭,第二个人( 2 号)将…

nginx修改网站默认根目录及发布(linux、centos、ubuntu)openEuler软件源repo站点

目录 安装nginx配置nginx其它权限配置 安装nginx dnf install -y nginx配置nginx whereis nginxcd /etc/nginx llcd conf.d touch vhost.conf vim vhost.conf 命令模式下输入:set nu或:set number可以显示行号 复制如下内容: server {listen 80;server_name…

基于java+springboot+vue实现的流浪动物管理系统(文末源码+Lw)277

摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对流浪动物信息管理的提升&…

玩转Easysearch语法

Elasticsearch 是一个基于Apache Lucene的开源分布式搜索和分析引擎,广泛应用于全文搜索、结构化搜索、分析等多种场景。 Easysearch 作为Elasticsearch 的国产化替代方案,不仅保持了与原生Elasticsearch 的高度兼容性,还在功能、性能、稳定性…

Spring框架Mvc(2)

1.传递数组 代码示例 结果 2.集合参数存储并进行存储类似集合类 代码示例 postman进行测试 ,测试结果 3.用Json来对其进行数据的传递 (1)Json是一个经常使用的用来表示对象的字符串 (2)Json字符串在字符串和对象…

Mysql数据库索引、事务相关知识

索引 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引, 并指定索引的类型,各类索引有各自的数据结构实现 查看索引 show index from 表名;创建索引对于非主键、非唯一约束、非外键的字段&#…

JAVA ArrayList应用案例

一案例要求&#xff1a; 二代码&#xff1a; package 重修;import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class first {public static void main(String[] args) {ArrayList<String>arrayListnew ArrayList<>();array…

ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法

目录 方法1&#xff1a;php://filter 流的 base64-decode 方法 方法2&#xff1a;通过 rot13 编码实现绕过 方法3&#xff1a;通过 strip_tags 函数去除 XML 标签 除了替换&#xff0c;新增 file_put_contents 函数&#xff0c;将会往 $file 里写入 <?php die(大佬别秀了…

微软与OpenAI/谷歌与三星的AI交易受欧盟重点关注

近日&#xff0c;欧盟委员会主管竞争事务的副主席玛格丽特维斯塔格(Margrethe Vestager)在一次演讲中透露&#xff0c;欧盟反垄断监管机构将就微软与OpenAI的合作&#xff0c;以及谷歌与三星达成的AI协议寻求更多第三方意见。这意味着微软与 OpenAI、谷歌与三星的 AI 交易及合作…

MySQL中的DDL语句

第一题 输入密码登录mysql&#xff0c;创建数据库zoo&#xff0c;转换到zoo数据库&#xff0c; mysql> create database zoo character set gbk; mysql> use zoo查看创建数据库zoo信息 mysql> show create database zoo;删除数据库zoo mysql> drop database zo…

独立开发者系列(20)——扫码登录

&#xff08;1&#xff09;网页端的安全登录设计 很多大型网站都有登录限制。这里以一个案例作为例子完整解析。理解安全的登录设计方式&#xff0c;无论对于以后做自动化&#xff0c;自动登录网站&#xff0c;获取数据&#xff0c;还是自己开发月租类型的系统非常有用。当前一…

2024菜鸟春招笔试

第一题 解题思路&#xff1a; 签到题&#xff0c;把帖子按好评度降序排列&#xff0c;再将人按升序排列。 第二题 解题思路 从左到右遍历&#xff0c;如果当前元素没有错排&#xff0c;将其与后一个交换&#xff0c;这样两个元素一定都错排。 第三题 、 解题思路 这题当时暴力…

【总线】AXI4第八课时:介绍AXI的 “原子访问“ :独占访问(Exclusive Access)和锁定访问(Locked Access)

大家好,欢迎来到今天的总线学习时间!如果你对电子设计、特别是FPGA和SoC设计感兴趣&#xff0c;那你绝对不能错过我们今天的主角——AXI4总线。作为ARM公司AMBA总线家族中的佼佼者&#xff0c;AXI4以其高性能和高度可扩展性&#xff0c;成为了现代电子系统中不可或缺的通信桥梁…

comsol随机材料参数赋值

comsol随机材料参数赋值 在comsol中定义外部matlab函数 在comsol中定义外部matlab函数 首选项&#xff0c;安全性&#xff0c;允许 材料中&#xff0c;将杨氏模量更改为变量函数 计算 应力有波动&#xff0c;可见赋值成功 也可以看到赋值的材料参数&#xff1a;

matlab 抛物线图像绘制

抛物线图像绘制 x^2y4绘制结果 x^2y4 clc,clear,close all; length10; % 创建一个范围内的 x 和 y 值 x linspace(-length, length, 1000); y linspace(-length, length, 1000);% 创建一个网格来表示 x 和 y 值的组合 [X, Y] meshgrid(x, y);% 计算方程的左边和右边的值 LH…

【启明智显分享】乐鑫HMI方案2.8寸触摸串口屏应用于太阳能控制器

前言 太阳能作为一种无尽的、可再生的能源&#xff0c;在现代社会的能源结构中占据着日益重要的地位。而在太阳能应用系统中&#xff0c;有一种设备是不可或缺的&#xff0c;那就是太阳能控制器。太阳能控制器在太阳能系统中起着至关重要的作用&#xff0c;它保证系统的安全和…

redis学习(005 java客户端 RedisTemplate学习)

黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 总时长 42:48:00 共175P 此文章包含第16p-第p23的内容 文章目录 java客户端jedisSpringDataRedis项目实现hash哈希操作 java客户端 jedis 测试 ps:如果连接不上&…

C-study(五).2

逻辑运算符 连接两个完整的关系表达式。 && 逻辑与&#xff0c;ab都为真时&#xff0c;a&&b的值真&#xff0c;其余时候假。 || 逻辑或&#xff0c;ab都为假时&#xff0c;a||b的值假&#xff0c;其余时候真。 ! 逻辑非、只需要一个运算对象&#xff0c;a真&a…

维护和管理LDAP之OpenDJ

目录 基本介绍 服务专有名词 安装 命令行工具 密码管理 重置管理员密码 管理服务器进程 管理索引 如何搜索 管理索引 管理目录数据 测试数据 导出数据 导入数据 LDIF文件数据查看和比较 数据存储-Backends 配置连接 开启 HTTP/HTTPS连接 使用 REST访问 -open…