理解 C++ 的 this 指针

1. 什么是 this 指针

**C++**中的 this 指针是一个由系统维护的指针,其指针本身的地址存储在某个内存位置,对程序员不可见(程序员不能取得其地址),其仅在当前定义的实体的函数体内可见。

当任何外部函数调用实体的函数时,系统会将该实体的地址存入 this 指针,进入函数后就可以通过该 this 指针访问实体的成员(数据和函数)。

2. 例释 this 指针(以windows 64位平台为例)

为了简单起见,我们定义一个结构体并定义一个函数,使用默认构造函数:

struct DataEntity

{

__int64 m = 10;

__int64 n = 20;

__int64 Add()

{

return m + n;

}

};

调用代码:

DataEntity data;

__int64 total = data.Add();

实现分析(汇编代码): 下面通过其生成的汇编代码来分析其实现过程。

(1) 调用构造函数

DataEntity data;

00007FF689FF5073 lea rcx,data ;将实体的地址存入寄存器 rcx (调用构造函数传参用)

00007FF689FF5078 call DataEntity::DataEntity (07FF689E76F55h) ;调用构造函数

下面进入构造函数:

DataEntity::DataEntity(void):

00007FF7946A13F0 mov qword ptr this,rcx ;将实体地址存入this指针

;在每一个生成函数中,都会在进行正式操作前插入这样一段代码,先将实体地址存入this指针,

;以便程序员后续利用 this指针操作该对象的成员。

00007FF7946A13F5 mov rax,qword ptr this ;取得this存储的对象地址

00007FF7946A13FA mov qword ptr rax,0Ah ; 将 10 送入 m ,因为此时寄存器 rax

;存放的是实体的首地址,其首地址就是 m 的地址。

00007FF7946A1401 mov rax,qword ptr this ;再取this存储的对象地址存入寄存器 rax

00007FF7946A1406 mov qword ptr rax+8,14h ;地址+8正好是n的内存位置,将20送入

;n 的地址指向的内存

00007FF7946A140E mov rax,qword ptr this ; 将 this 指针送入寄存器 rax 以备使用

00007FF7946A1413 ret ; 操作完成,函数返回

注意:该 this 指针在函数调用期间保持不变。

(2) 调用自定义函数

__int64 total = data.Add();

00007FF79481507D lea rcx,data ;将实体的地址存入寄存器 rcx (调用构造函数传参用)

00007FF794815082 call DataEntity::Add (07FF794696F64h) ;调用函数

00007FF794815087 mov qword ptr total,rax ;从rax取出计算结果送入total 内存。

进行被调函数内部流程:

__int64 Add()

{

00007FF7946A12F0 mov qword ptr this,rcx ; 取出实体地址存入 this

return m + n;

00007FF7946A12F5 mov rax,qword ptr this ;得取this

00007FF7946A12FA mov rax,qword ptr rax ; m 值送入寄存器 rax

00007FF7946A12FD mov rcx,qword ptr this ;得取this

00007FF7946A1302 add rax,qword ptr rcx+8 ;rcx+8=n的地址,将n加到rax(m)

}

00007FF7946A1306 ret ;函数返回,寄存器rax的值即为计算结果,上述标红的部分即从rax取

;出结果,在 Windows X64 加构下,约定使用 rax 传递返回值。

相关推荐
半杯咖啡半行码10 分钟前
C++ 编程与 STL 模板:从泛型编程到内存安全详解
开发语言·c++
caoerzhong23 分钟前
JeeWMS 开源 WMS 部署避坑指南:Java 仓库管理系统的环境基线、四类根因与可复现交付
java·开发语言·开源
时间的拾荒人25 分钟前
Qt 界面优化:绘图详解 —— 从基础图形到图片处理
开发语言·qt·面试
MayZork43 分钟前
Qt 文件操作:QSaveFile 与 QTemporaryFile(含 QTemporaryDir)实战
开发语言·qt
北冥you鱼1 小时前
Go 语言空接口(interface{})使用场景与最佳实践
开发语言·windows·golang
xh didida1 小时前
Linux -- 基础IO
linux·服务器·开发语言·c++
垆边人似月.1 小时前
华为机试题 :两数之和
c++·算法·华为
个 人 练 习 生1 小时前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
垆边人似月.2 小时前
华为机试题 :有效的括号
c++·算法·华为
2601_966949652 小时前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash