在这大概从三个角度来谈this指针 :
A . this指针的由来 B . this指针的特点 C . this指针与this Call调用方式
有错误的地方,欢迎批评指正
A . this指针的由来
测试代码 1:
#include "stdafx.h" struct MyStruct { int x ; int y ; }; //函数在结构体外部 void Max(MyStruct* str) { if (str->x > str->y) printf("%d",str->x); else printf("%d",str->y); } int _tmain(int argc, _TCHAR* argv[]) { MyStruct haha ; haha.x = 1 ; haha.y = 2 ; Max(&haha); printf("%d\n",sizeof(haha)); return 0; }
执行结果 : 2 8
测试代码 2:
#include "stdafx.h" struct MyStruct { int x ; int y ; //函数在结构体内部 int Max(MyStruct* str) { return str->x > str->y ? str->x :str->y ; } }; int _tmain(int argc, _TCHAR* argv[]) { MyStruct haha ; haha.x = 1 ; haha.y = 2 ; haha.Max(&haha); printf("%d\n",haha.Max(&haha)); printf("%d\n",sizeof(haha)); return 0; }
执行结果 : 2 8
由此可以看出函数在结构体内部与外部并不影响对象(或者结构体变量)的大小 , 那么这就构成了类的原因之一. 然而这并不是关键
测试代码1 的反汇编代码
<pre name="code" class="cpp"> 23: MyStruct haha ; 24: haha.x = 1 ; 011739E8 C7 45 F0 01 00 00 00 mov dword ptr [ebp-10h],1 25: haha.y = 2 ; 011739EF C7 45 F4 02 00 00 00 mov dword ptr [ebp-0Ch],2 26: Max(&haha); 011739F6 8D 45 F0 lea eax,[ebp-10h] 011739F9 50 push eax 011739FA E8 FF D7 FF FF call 011711FE 011739FF 83 C4 04 add esp,4
//进入函数内部(部分): 13: void Max(MyStruct* str) 14: { 011E2A20 55 push ebp 011E2A21 8B EC mov ebp,esp 011E2A23 81 EC C0 00 00 00 sub esp,0C0h 011E2A29 53 push ebx 011E2A2A 56 push esi 011E2A2B 57 push edi 011E2A2C 8D BD 40 FF FF FF lea edi,[ebp+FFFFFF40h] 011E2A32 B9 30 00 00 00 mov ecx,30h 011E2A37 B8 CC CC CC CC mov eax,0CCCCCCCCh 011E2A3C F3 AB rep stos dword ptr es:[edi] 15: if (str->x > str->y) 011E2A3E 8B 45 08 mov eax,dword ptr [ebp+8] 011E2A41 8B 4D 08 mov ecx,dword ptr [ebp+8] 011E2A44 8B 10 mov edx,dword ptr [eax] 011E2A46 3B 51 04 cmp edx,dword ptr [ecx+4] 011E2A49 7E 1F jle 011E2A6A 16: printf("%d\n",str->x);
测试代码2的反汇编代码:
22: MyStruct haha ; 23: haha.x = 1 ; 00F939E8 C7 45 F0 01 00 00 00 mov <span style="background-color: rgb(51, 255, 255);">dword ptr [ebp-10h],1 </span> 24: haha.y = 2 ; 00F939EF C7 45 F4 02 00 00 00 mov dword ptr [ebp-0Ch],2 25: haha.Max(&haha); 00F939F6 8D 45 F0 lea eax,[ebp-10h] 00F939F9 50 push eax 00F939FA 8D 4D F0 <span style="background-color: rgb(255, 255, 51);">lea ecx,[ebp-10h] </span> 00F939FD E8 01 D8 FF FF call 00F91203
10: //函数在结构体内部 11: void Max(MyStruct* str) 12: { 00F93420 55 push ebp 00F93421 8B EC mov ebp,esp 00F93423 81 EC CC 00 00 00 sub esp,0CCh 00F93429 53 push ebx 00F9342A 56 push esi 00F9342B 57 push edi 00F9342C 51 <span style="background-color: rgb(255, 255, 51);">push ecx</span> 00F9342D 8D BD 34 FF FF FF lea edi,[ebp+FFFFFF34h] 00F93433 B9 33 00 00 00 mov ecx,33h 00F93438 B8 CC CC CC CC mov eax,0CCCCCCCCh 00F9343D F3 AB rep stos dword ptr es:[edi] 00F9343F 59 <span style="background-color: rgb(255, 255, 51);">pop ecx</span> 00F93440 89 4D F8 <span style="background-color: rgb(255, 255, 51);"> mov dword ptr [ebp-8],ecx</span> 13: if (str->x > str->y) 00F93443 8B 45 08 mov eax,dword ptr [ebp+8] 00F93446 8B 4D 08 mov ecx,dword ptr [ebp+8] 00F93449 8B 10 mov edx,dword ptr [eax] 00F9344B 3B 51 04 cmp edx,dword ptr [ecx+4] 00F9344E 7E 1F jle 00F9346F 14: printf("%d\n",str->x);
可以注意到 测试代码2的反汇编代码 在call 之前多了一句代码
<pre name="code" class="cpp"><span style="background-color: rgb(255, 255, 0);">lea eax,[ebp-10h]</span>
在函数内部我们可以观察到ecx的值被存放到dword ptr [ebp-8] 的位置 ,即为参数 .
那么[ebp-10h]是什么呢 ,这显然是一个地址 , 是什么地址呢? 在上面代码中可知
[ebp-10h]存放的是 结构体变量(在C++中就称为对象了)的 第一个成员变量的地址 .这就是所谓的this指针了
但是呢,问题来了: 在C语言代码中我们什么都没做,只是将函数放在了结构体内部 . 就莫名其妙的多出了汇编指令
<pre name="code" class="cpp"><pre name="code" class="cpp"><span style="background-color: rgb(255, 255, 0);">lea eax,[ebp-10h]</span>
由此,我们得出结论 : 将全局的函数放进结构体内,便出现了this指针,该this指针是由ecx传递的 . 更重要的是这是编译器替我们加上的.
即是说,由C转化为C++,更多的是编译器做的操作.
可以归纳this指针的本质 :
this是调用结构体(或类)内部成员函数时传递的参数(通常用ecx传递) . 其本质是结构体变量(或者对象)的第一个成员变量的地址.(读者可以试下)
B : this指针的特点
1.this指针不可以++ - -操作 , 即this指针的值不可以被改变 .
2.参数个数确定的函数,this指针是由ecx传递的 , 在变参函数中最后一个传递的参数是this指针
3.this指针不占用结构体变量(类的对象)的大小
C : this指针与this调用方式
见下篇 .
从反汇编看this指针
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
猜你喜欢
转载自blog.csdn.net/jxz_dz/article/details/47808795
今日推荐
周排行