在这一章节,我们会学习到的概念:类,封装,对象,this类指针,并且从汇编角度贴近计算机底层来深刻讲解this指针。
1.this指针引入
我们先来写一个这样的简单程序:
#include <stdio.h> struct Base{ int a; int b; }; int Max(Base in){ if(in.a>in.b){ return in.a; } else{ return in.b; } } int main(){ Base one; one.a=1; one.b=2; int c=Max(one); printf("%d",c); return 0; }
程序定义了一个Base结构体,结构体中有两个成员,都为int类型
程序定义了一个函数,需要一个Base类型的参数,函数功能为比较Base结构中的两个成员,并返回其中较大的一个。
我们来到反汇编看一看:
mov eax,dword ptr [ebp-4] push eax mov ecx,dword ptr [ebp-8] push ecx call @ILT+0(Max) (00401005) add esp,8 mov dword ptr [ebp-0Ch],eax
我们来看看程序调用Max函数的过程:
先将参数one中的成员(a,b)压入栈中,然后调用Max函数,在函数完成后,我们发现这是一个外平栈。
然后我们将Max函数(封装的定义我们在后面会讲到)封装到结构体中:
#include <stdio.h> struct Base{ int a; int b; int Max(Base in){ if(in.a>in.b){ return in.a; } else{ return in.b; } } }; int main(){ Base one; one.a=1; one.b=2; int c=Max(one); printf("%d",c); return 0; }
这时候我们编译程序的时候发现出错了,错误提示为:error C2065: 'Max' : undeclared identifier
由于我们是将Max函数封装到了Base结构体中,所以我们在调用函数时,应该这样调用:int c= Base.Max(one);
所以我们的程序应该写为:
#include <stdio.h> struct Base{ int a; int b; int Max(Base in){ if(in.a>in.b){ return in.a; } else{ return in.b; } } }; int main(){ Base one; one.a=1; one.b=2; int c=one.Max(one); printf("%d",c); return 0; }
我们发现程序能够正常运行,那么我们来思考一个问题:
将函数封装在结构体中后,他会不会占用结构体空间?
我们在源代码后加入这样一串代码来观察封装的函数到底有没有占用结构体空间:
printf( "%d " , sizeof(one) );
在程序运行之后,我们发现 sizeof(one)
的值为8,那么就说明封装在结构体中的函数没有占用结构体空间。
我们继续来到反汇编,观察调用函数的过程:
mov eax,dword ptr [ebp-4] push eax mov ecx,dword ptr [ebp-8] push ecx lea ecx,[ebp-8] call @ILT+10(Base::Max) (0040100f) mov dword ptr [ebp-0Ch],eax
我们发现程序能够正常运行,那么我们来思考一个问题:
将函数封装在结构体中后,他会不会占用结构体空间?
我们在源代码后加入这样一串代码来观察封装的函数到底有没有占用结构体空间:
printf( "%d " , sizeof(one) );
在程序运行之后,我们发现 sizeof(one)
的值为8,那么就说明封装在结构体中的函数没有占用结构体空间。
我们继续来到反汇编,观察调用函数的过程:
mov eax,dword ptr [ebp-4] push eax mov ecx,dword ptr [ebp-8] push ecx lea ecx,[ebp-8] call @ILT+10(Base::Max) (0040100f) mov dword ptr [ebp-0Ch],eax