欢迎来到天天文库
浏览记录
ID:18893016
大小:104.50 KB
页数:13页
时间:2018-09-26
《反汇编角度分析vc++面向对象机制.doc》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、//target:从内存角度熟悉VC++面向对象机制作为MFC编程的基础//author:byReduta//descritption:IA32+winsp3+vc6.0/OD1.10一:构造函数的之争1.1:构造函数是有返回值的——返回当前对象的this指针基本打开每一本C++的教程,都会对构造函数有如此类似的描述“构造函数无返回值,可进行函数重载”,但是事实上又如何呢?答案是构造函数具备返回值,返回值为当前对象的this指针。编写如下代码://示例#includeusingnamespacestd;classtest{inta;public:test();v
2、oidshow();};test::test(){a=1;}voidtest::show(){cout<3、llapi.0040123F;构造函数0040159036:C70002000000movdwordptrss:[eax],2;修改对象的数据成员004015978D4DFCleaecx,dwordptrss:[ebp-4];hacker的this指针0040159AE80FFCFFFFcallapi.004011AE;hacker的show函数执行到401590时,注意观察eax与ecx的值,如图1所示,eax和ecx的值是一样的,说明构造函数的确是有返回值,且返回值为当前对象的this指针,重新载入OD,在构造函数处,F7跟进,如图2所示,用红框标识的为关键代码,即构造函数,最4、后都会执行一句指令,将当前对象的this指针保存到eax中,而eax是函数的返回值。不管是debug版的程序还是release版程序都会执行类似的指令,即无论何时,构造函数将返回当前对象的this指针。1.2:构造函数并不一定是函数——inline内联的影响看到构造函数并不一定是函数,你可能觉得可笑,这主要受inline内联的影响。如果将上面的构造函数定义在类作用域内即如下代码,此时测试release版本程序会发现,执行结果依然为1,如图3所示,即修改未遂,release版与debug版程序的最大区别在于代码优化,使用release版,基本所有的inline函数都能得到扩展,即此时5、构造函数并不是一个函数,而只是指令扩展。将release版程序载入OD,跟进主函数,发现如下代码:0040102055pushebp004010218BECmovebp,esp0040102351pushecx00401024C745FC01000000movdwordptrss:[ebp-4],1;构造函数代码处0040102B36:C70002000000movdwordptrss:[eax],2004010328D4DFCleaecx,dwordptrss:[ebp-4]00401035E8C6FFFFFFcallapi.004010000040103A33C0xoreax,6、eax0040103C8BE5movesp,ebp0040103E5Dpopebp0040103FC3retn并没有将test()构造函数进行显示调用,此时的test()构造函数只有一句代码即movdwordptrss:[ebp-4],1。1.3:C++初始化的过程几乎每本C++的教程都会告诉我们对象是有构造函数初始化数据成员,但是并不能系统的告诉我们初始化的具体过程,本部分着重分析C++面向对象数据成员初始化的一般过程及各种初始化方式的特点。首先来讨论一下C++初始化的一般方法——全局对象初始化、初始化列表、构造函数、static成员的初始化。static数据成员是在类内声明,类7、外定义的,在定义的时候并不遵守访问限定符的限定,一旦定义,static数据成员即遵守访问限定的限制,这里不过分讨论static成员,我们来看一下剩余的几种初始化方式,它们实际上组成了如图4的初始化层次结构。//全局初始化过程......................classtest{inta;public:test(){a=1;cout<<"constructor!"<
3、llapi.0040123F;构造函数0040159036:C70002000000movdwordptrss:[eax],2;修改对象的数据成员004015978D4DFCleaecx,dwordptrss:[ebp-4];hacker的this指针0040159AE80FFCFFFFcallapi.004011AE;hacker的show函数执行到401590时,注意观察eax与ecx的值,如图1所示,eax和ecx的值是一样的,说明构造函数的确是有返回值,且返回值为当前对象的this指针,重新载入OD,在构造函数处,F7跟进,如图2所示,用红框标识的为关键代码,即构造函数,最
4、后都会执行一句指令,将当前对象的this指针保存到eax中,而eax是函数的返回值。不管是debug版的程序还是release版程序都会执行类似的指令,即无论何时,构造函数将返回当前对象的this指针。1.2:构造函数并不一定是函数——inline内联的影响看到构造函数并不一定是函数,你可能觉得可笑,这主要受inline内联的影响。如果将上面的构造函数定义在类作用域内即如下代码,此时测试release版本程序会发现,执行结果依然为1,如图3所示,即修改未遂,release版与debug版程序的最大区别在于代码优化,使用release版,基本所有的inline函数都能得到扩展,即此时
5、构造函数并不是一个函数,而只是指令扩展。将release版程序载入OD,跟进主函数,发现如下代码:0040102055pushebp004010218BECmovebp,esp0040102351pushecx00401024C745FC01000000movdwordptrss:[ebp-4],1;构造函数代码处0040102B36:C70002000000movdwordptrss:[eax],2004010328D4DFCleaecx,dwordptrss:[ebp-4]00401035E8C6FFFFFFcallapi.004010000040103A33C0xoreax,
6、eax0040103C8BE5movesp,ebp0040103E5Dpopebp0040103FC3retn并没有将test()构造函数进行显示调用,此时的test()构造函数只有一句代码即movdwordptrss:[ebp-4],1。1.3:C++初始化的过程几乎每本C++的教程都会告诉我们对象是有构造函数初始化数据成员,但是并不能系统的告诉我们初始化的具体过程,本部分着重分析C++面向对象数据成员初始化的一般过程及各种初始化方式的特点。首先来讨论一下C++初始化的一般方法——全局对象初始化、初始化列表、构造函数、static成员的初始化。static数据成员是在类内声明,类
7、外定义的,在定义的时候并不遵守访问限定符的限定,一旦定义,static数据成员即遵守访问限定的限制,这里不过分讨论static成员,我们来看一下剩余的几种初始化方式,它们实际上组成了如图4的初始化层次结构。//全局初始化过程......................classtest{inta;public:test(){a=1;cout<<"constructor!"<
此文档下载收益归作者所有